chore: Make field declarations explicit
This used to be valid code: ``` class Foo { constructor() { this.bar = ‘string’; } } ``` This will now fail since ‘bar’ is not explicitly defined as a field. We now have to write: ``` class Foo { bar:string; // << REQUIRED constructor() { this.bar = ‘string’; } } ```
This commit is contained in:
parent
ab961b327e
commit
044625a098
|
@ -12,8 +12,8 @@ import {Lexer} from 'change_detection/parser/lexer';
|
|||
import {Compiler} from 'core/compiler/compiler';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
|
||||
var COUNT = 30;
|
||||
|
@ -64,6 +64,7 @@ function loadTemplate(templateId, repeatCount) {
|
|||
|
||||
// Caching reflector as reflection in Dart using Mirrors
|
||||
class CachingReflector extends Reflector {
|
||||
_cache: Map;
|
||||
constructor() {
|
||||
this._cache = MapWrapper.create();
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@ export * from './record';
|
|||
export * from './record_range'
|
||||
|
||||
export class ChangeDetector {
|
||||
|
||||
@FIELD('final _rootRecordRange:RecordRange')
|
||||
_rootRecordRange:RecordRange;
|
||||
constructor(recordRange:RecordRange) {
|
||||
this._rootRecordRange = recordRange;
|
||||
}
|
||||
|
|
|
@ -13,18 +13,19 @@ import {
|
|||
} from 'facade/lang';
|
||||
|
||||
export class CollectionChanges {
|
||||
// todo(vicb) Add fields when supported
|
||||
/*
|
||||
_collection;
|
||||
int _length;
|
||||
DuplicateMap _linkedRecords;
|
||||
DuplicateMap _unlinkedRecords;
|
||||
CollectionChangeItem<V> _previousItHead;
|
||||
CollectionChangeItem<V> _itHead, _itTail;
|
||||
CollectionChangeItem<V> _additionsHead, _additionsTail;
|
||||
CollectionChangeItem<V> _movesHead, _movesTail;
|
||||
CollectionChangeItem<V> _removalsHead, _removalsTail;
|
||||
*/
|
||||
_length:int;
|
||||
_linkedRecords:_DuplicateMap;
|
||||
_unlinkedRecords:_DuplicateMap;
|
||||
_previousItHead:CollectionChangeRecord<V> ;
|
||||
_itHead:CollectionChangeRecord<V>;
|
||||
_itTail:CollectionChangeRecord<V> ;
|
||||
_additionsHead:CollectionChangeRecord<V>;
|
||||
_additionsTail:CollectionChangeRecord<V> ;
|
||||
_movesHead:CollectionChangeRecord<V>;
|
||||
_movesTail:CollectionChangeRecord<V> ;
|
||||
_removalsHead:CollectionChangeRecord<V>;
|
||||
_removalsTail:CollectionChangeRecord<V> ;
|
||||
constructor() {
|
||||
this._collection = null;
|
||||
this._length = null;
|
||||
|
@ -236,9 +237,9 @@ export class CollectionChanges {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get rid of any excess [CollectionChangeItem]s from the previous collection
|
||||
* Get rid of any excess [CollectionChangeRecord]s from the previous collection
|
||||
*
|
||||
* - [record] The first excess [CollectionChangeItem].
|
||||
* - [record] The first excess [CollectionChangeRecord].
|
||||
*/
|
||||
_truncate(record:CollectionChangeRecord) {
|
||||
// Anything after that needs to be removed;
|
||||
|
@ -457,19 +458,16 @@ export class CollectionChanges {
|
|||
}
|
||||
|
||||
export class CollectionChangeRecord {
|
||||
// todo(vicb) add fields when supported
|
||||
/*
|
||||
int currentIndex;
|
||||
int previousIndex;
|
||||
V item;
|
||||
currentIndex:int;
|
||||
previousIndex:int;
|
||||
item;
|
||||
|
||||
CollectionChangeItem<V> _nextPrevious;
|
||||
CollectionChangeItem<V> _prev, _next;
|
||||
CollectionChangeItem<V> _prevDup, _nextDup;
|
||||
CollectionChangeItem<V> _prevRemoved, _nextRemoved;
|
||||
CollectionChangeItem<V> _nextAdded;
|
||||
CollectionChangeItem<V> _nextMoved;
|
||||
*/
|
||||
_nextPrevious:CollectionChangeRecord;
|
||||
_prev:CollectionChangeRecord; _next:CollectionChangeRecord;
|
||||
_prevDup:CollectionChangeRecord; _nextDup:CollectionChangeRecord;
|
||||
_prevRemoved:CollectionChangeRecord; _nextRemoved:CollectionChangeRecord;
|
||||
_nextAdded:CollectionChangeRecord;
|
||||
_nextMoved:CollectionChangeRecord;
|
||||
|
||||
constructor(item) {
|
||||
this.currentIndex = null;
|
||||
|
@ -497,10 +495,8 @@ export class CollectionChangeRecord {
|
|||
|
||||
// A linked list of CollectionChangeRecords with the same CollectionChangeRecord.item
|
||||
class _DuplicateItemRecordList {
|
||||
/*
|
||||
todo(vicb): add fields when supported
|
||||
CollectionChangeRecord _head, _tail;
|
||||
*/
|
||||
_head:CollectionChangeRecord;
|
||||
_tail:CollectionChangeRecord;
|
||||
|
||||
constructor() {
|
||||
this._head = null;
|
||||
|
@ -542,7 +538,7 @@ class _DuplicateItemRecordList {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove one [CollectionChangeItem] from the list of duplicates.
|
||||
* Remove one [CollectionChangeRecord] from the list of duplicates.
|
||||
*
|
||||
* Returns whether the list of duplicates is empty.
|
||||
*/
|
||||
|
@ -550,7 +546,7 @@ class _DuplicateItemRecordList {
|
|||
// todo(vicb)
|
||||
//assert(() {
|
||||
// // verify that the record being removed is in the list.
|
||||
// for (CollectionChangeItem cursor = _head; cursor != null; cursor = cursor._nextDup) {
|
||||
// for (CollectionChangeRecord cursor = _head; cursor != null; cursor = cursor._nextDup) {
|
||||
// if (identical(cursor, record)) return true;
|
||||
// }
|
||||
// return false;
|
||||
|
@ -573,7 +569,7 @@ class _DuplicateItemRecordList {
|
|||
}
|
||||
|
||||
class _DuplicateMap {
|
||||
// todo(vicb): add fields when supported
|
||||
map:Map;
|
||||
constructor() {
|
||||
this.map = MapWrapper.create();
|
||||
}
|
||||
|
@ -605,7 +601,7 @@ class _DuplicateMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes an [CollectionChangeItem] from the list of duplicates.
|
||||
* Removes an [CollectionChangeRecord] from the list of duplicates.
|
||||
*
|
||||
* The list of duplicates also is removed from the map if it gets empty.
|
||||
*/
|
||||
|
|
|
@ -3,19 +3,17 @@ import {ListWrapper, MapWrapper} from 'facade/collection';
|
|||
import {stringify, looseIdentical} from 'facade/lang';
|
||||
|
||||
export class MapChanges {
|
||||
// todo(vicb) add as fields when supported
|
||||
/*
|
||||
final _records = new HashMap<dynamic, MapKeyValue>();
|
||||
Map _map;
|
||||
_records:Map;
|
||||
_map:Map;
|
||||
|
||||
Map get map => _map;
|
||||
|
||||
MapKeyValue<K, V> _mapHead;
|
||||
MapKeyValue<K, V> _previousMapHead;
|
||||
MapKeyValue<K, V> _changesHead, _changesTail;
|
||||
MapKeyValue<K, V> _additionsHead, _additionsTail;
|
||||
MapKeyValue<K, V> _removalsHead, _removalsTail;
|
||||
*/
|
||||
_mapHead:MapChangeRecord;
|
||||
_previousMapHead:MapChangeRecord;
|
||||
_changesHead:MapChangeRecord;
|
||||
_changesTail:MapChangeRecord;
|
||||
_additionsHead:MapChangeRecord;
|
||||
_additionsTail:MapChangeRecord;
|
||||
_removalsHead:MapChangeRecord;
|
||||
_removalsTail:MapChangeRecord;
|
||||
|
||||
constructor() {
|
||||
this._records = MapWrapper.create();
|
||||
|
@ -317,18 +315,16 @@ export class MapChanges {
|
|||
}
|
||||
|
||||
export class MapChangeRecord {
|
||||
// todo(vicb) add as fields
|
||||
//final K key;
|
||||
//V _previousValue, _currentValue;
|
||||
//
|
||||
//V get previousValue => _previousValue;
|
||||
//V get currentValue => _currentValue;
|
||||
//
|
||||
//MapKeyValue<K, V> _nextPrevious;
|
||||
//MapKeyValue<K, V> _next;
|
||||
//MapKeyValue<K, V> _nextAdded;
|
||||
//MapKeyValue<K, V> _nextRemoved, _prevRemoved;
|
||||
//MapKeyValue<K, V> _nextChanged;
|
||||
key;
|
||||
_previousValue;
|
||||
_currentValue;
|
||||
|
||||
_nextPrevious:MapChangeRecord;
|
||||
_next:MapChangeRecord;
|
||||
_nextAdded:MapChangeRecord;
|
||||
_nextRemoved:MapChangeRecord;
|
||||
_prevRemoved:MapChangeRecord;
|
||||
_nextChanged:MapChangeRecord;
|
||||
|
||||
constructor(key) {
|
||||
this.key = key;
|
||||
|
|
|
@ -33,7 +33,7 @@ export class ImplicitReceiver extends AST {
|
|||
* Multiple expressions separated by a semicolon.
|
||||
*/
|
||||
export class Chain extends AST {
|
||||
@FIELD('final expressions:List')
|
||||
expressions:List;
|
||||
constructor(expressions:List) {
|
||||
this.expressions = expressions;
|
||||
}
|
||||
|
@ -53,9 +53,9 @@ export class Chain extends AST {
|
|||
}
|
||||
|
||||
export class Conditional extends AST {
|
||||
@FIELD('final condition:AST')
|
||||
@FIELD('final trueExp:AST')
|
||||
@FIELD('final falseExp:AST')
|
||||
condition:AST;
|
||||
trueExp:AST;
|
||||
falseExp:AST;
|
||||
constructor(condition:AST, trueExp:AST, falseExp:AST){
|
||||
this.condition = condition;
|
||||
this.trueExp = trueExp;
|
||||
|
@ -76,10 +76,10 @@ export class Conditional extends AST {
|
|||
}
|
||||
|
||||
export class AccessMember extends AST {
|
||||
@FIELD('final receiver:AST')
|
||||
@FIELD('final name:string')
|
||||
@FIELD('final getter:Function')
|
||||
@FIELD('final setter:Function')
|
||||
receiver:AST;
|
||||
name:string;
|
||||
getter:Function;
|
||||
setter:Function;
|
||||
constructor(receiver:AST, name:string, getter:Function, setter:Function) {
|
||||
this.receiver = receiver;
|
||||
this.name = name;
|
||||
|
@ -105,8 +105,8 @@ export class AccessMember extends AST {
|
|||
}
|
||||
|
||||
export class KeyedAccess extends AST {
|
||||
@FIELD('final obj:AST')
|
||||
@FIELD('final key:AST')
|
||||
obj:AST;
|
||||
key:AST;
|
||||
constructor(obj:AST, key:AST) {
|
||||
this.obj = obj;
|
||||
this.key = key;
|
||||
|
@ -149,9 +149,10 @@ export class KeyedAccess extends AST {
|
|||
}
|
||||
|
||||
export class Formatter extends AST {
|
||||
@FIELD('final exp:AST')
|
||||
@FIELD('final name:string')
|
||||
@FIELD('final args:List<AST>')
|
||||
exp:AST;
|
||||
name:string;
|
||||
args:List<AST>;
|
||||
allArgs:List<AST>;
|
||||
constructor(exp:AST, name:string, args:List) {
|
||||
this.exp = exp;
|
||||
this.name = name;
|
||||
|
@ -165,7 +166,7 @@ export class Formatter extends AST {
|
|||
}
|
||||
|
||||
export class LiteralPrimitive extends AST {
|
||||
@FIELD('final value')
|
||||
value;
|
||||
constructor(value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
@ -180,7 +181,7 @@ export class LiteralPrimitive extends AST {
|
|||
}
|
||||
|
||||
export class LiteralArray extends AST {
|
||||
@FIELD('final expressions:List')
|
||||
expressions:List;
|
||||
constructor(expressions:List) {
|
||||
this.expressions = expressions;
|
||||
}
|
||||
|
@ -195,8 +196,8 @@ export class LiteralArray extends AST {
|
|||
}
|
||||
|
||||
export class LiteralMap extends AST {
|
||||
@FIELD('final keys:List')
|
||||
@FIELD('final values:List')
|
||||
keys:List;
|
||||
values:List;
|
||||
constructor(keys:List, values:List) {
|
||||
this.keys = keys;
|
||||
this.values = values;
|
||||
|
@ -216,9 +217,9 @@ export class LiteralMap extends AST {
|
|||
}
|
||||
|
||||
export class Binary extends AST {
|
||||
@FIELD('final operation:string')
|
||||
@FIELD('final left:AST')
|
||||
@FIELD('final right:AST')
|
||||
operation:string;
|
||||
left:AST;
|
||||
right:AST;
|
||||
constructor(operation:string, left:AST, right:AST) {
|
||||
this.operation = operation;
|
||||
this.left = left;
|
||||
|
@ -262,7 +263,7 @@ export class Binary extends AST {
|
|||
}
|
||||
|
||||
export class PrefixNot extends AST {
|
||||
@FIELD('final expression:AST')
|
||||
expression:AST;
|
||||
constructor(expression:AST) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
@ -277,8 +278,8 @@ export class PrefixNot extends AST {
|
|||
}
|
||||
|
||||
export class Assignment extends AST {
|
||||
@FIELD('final target:AST')
|
||||
@FIELD('final value:AST')
|
||||
target:AST;
|
||||
value:AST;
|
||||
constructor(target:AST, value:AST) {
|
||||
this.target = target;
|
||||
this.value = value;
|
||||
|
@ -294,9 +295,9 @@ export class Assignment extends AST {
|
|||
}
|
||||
|
||||
export class MethodCall extends AST {
|
||||
@FIELD('final receiver:AST')
|
||||
@FIELD('final fn:Function')
|
||||
@FIELD('final args:List')
|
||||
receiver:AST;
|
||||
fn:Function;
|
||||
args:List;
|
||||
constructor(receiver:AST, fn:Function, args:List) {
|
||||
this.receiver = receiver;
|
||||
this.fn = fn;
|
||||
|
@ -314,9 +315,9 @@ export class MethodCall extends AST {
|
|||
}
|
||||
|
||||
export class FunctionCall extends AST {
|
||||
@FIELD('final target:AST')
|
||||
@FIELD('final closureMap:ClosureMap')
|
||||
@FIELD('final args:List')
|
||||
target:AST;
|
||||
closureMap:ClosureMap;
|
||||
args:List;
|
||||
constructor(target:AST, closureMap:ClosureMap, args:List) {
|
||||
this.target = target;
|
||||
this.closureMap = closureMap;
|
||||
|
@ -337,6 +338,8 @@ export class FunctionCall extends AST {
|
|||
}
|
||||
|
||||
export class ASTWithSource {
|
||||
ast:AST;
|
||||
source:string;
|
||||
constructor(ast:AST, source:string) {
|
||||
this.source = source;
|
||||
this.ast = ast;
|
||||
|
@ -344,6 +347,9 @@ export class ASTWithSource {
|
|||
}
|
||||
|
||||
export class TemplateBinding {
|
||||
key:string;
|
||||
name:string;
|
||||
expression:ASTWithSource;
|
||||
constructor(key:string, name:string, expression:ASTWithSource) {
|
||||
this.key = key;
|
||||
// only either name or expression will be filled.
|
||||
|
|
|
@ -9,6 +9,7 @@ export const TOKEN_TYPE_OPERATOR = 5;
|
|||
export const TOKEN_TYPE_NUMBER = 6;
|
||||
|
||||
export class Lexer {
|
||||
text:string;
|
||||
tokenize(text:string):List {
|
||||
var scanner = new _Scanner(text);
|
||||
var tokens = [];
|
||||
|
@ -22,10 +23,10 @@ export class Lexer {
|
|||
}
|
||||
|
||||
export class Token {
|
||||
@FIELD('final index:int')
|
||||
@FIELD('final type:int')
|
||||
@FIELD('final _numValue:int')
|
||||
@FIELD('final _strValue:int')
|
||||
index:int;
|
||||
type:int;
|
||||
_numValue:number;
|
||||
_strValue:string;
|
||||
constructor(index:int, type:int, numValue:number, strValue:string) {
|
||||
/**
|
||||
* NOTE: To ensure that this constructor creates the same hidden class each time, ensure that
|
||||
|
@ -177,6 +178,7 @@ const $NBSP = 160;
|
|||
|
||||
|
||||
export class ScannerError extends Error {
|
||||
message:string;
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
@ -187,10 +189,10 @@ export class ScannerError extends Error {
|
|||
}
|
||||
|
||||
class _Scanner {
|
||||
@FIELD('final input:String')
|
||||
@FIELD('final length:int')
|
||||
@FIELD('peek:int')
|
||||
@FIELD('index:int')
|
||||
input:string;
|
||||
length:int;
|
||||
peek:int;
|
||||
index:int;
|
||||
|
||||
constructor(input:string) {
|
||||
this.input = input;
|
||||
|
|
|
@ -28,8 +28,8 @@ import {
|
|||
var _implicitReceiver = new ImplicitReceiver();
|
||||
|
||||
export class Parser {
|
||||
@FIELD('final _lexer:Lexer')
|
||||
@FIELD('final _closureMap:ClosureMap')
|
||||
_lexer:Lexer;
|
||||
_closureMap:ClosureMap;
|
||||
constructor(lexer:Lexer, closureMap:ClosureMap){
|
||||
this._lexer = lexer;
|
||||
this._closureMap = closureMap;
|
||||
|
@ -54,11 +54,11 @@ export class Parser {
|
|||
}
|
||||
|
||||
class _ParseAST {
|
||||
@FIELD('final input:string')
|
||||
@FIELD('final tokens:List<Token>')
|
||||
@FIELD('final closureMap:ClosureMap')
|
||||
@FIELD('final parseAction:boolean')
|
||||
@FIELD('index:int')
|
||||
input:string;
|
||||
tokens:List<Token>;
|
||||
closureMap:ClosureMap;
|
||||
parseAction:boolean;
|
||||
index:int;
|
||||
constructor(input:string, tokens:List, closureMap:ClosureMap, parseAction:boolean) {
|
||||
this.input = input;
|
||||
this.tokens = tokens;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {ProtoRecordRange, RecordRange} from './record_range';
|
||||
import {FIELD, isPresent, isBlank, int, StringWrapper, FunctionWrapper, BaseException} from 'facade/lang';
|
||||
import {ListWrapper, MapWrapper} from 'facade/collection';
|
||||
import {List, Map, ListWrapper, MapWrapper} from 'facade/collection';
|
||||
import {ClosureMap} from 'change_detection/parser/closure_map';
|
||||
|
||||
var _fresh = new Object();
|
||||
|
@ -26,15 +26,16 @@ export const RECORD_FLAG_IMPLICIT_RECEIVER = 0x0200;
|
|||
* real world numbers show that it does not provide significant benefits.
|
||||
*/
|
||||
export class ProtoRecord {
|
||||
@FIELD('final recordRange:ProtoRecordRange')
|
||||
@FIELD('final context:Object')
|
||||
@FIELD('final funcOrValue:Object')
|
||||
@FIELD('final arity:int')
|
||||
@FIELD('final dest')
|
||||
recordRange:ProtoRecordRange;
|
||||
_mode:int;
|
||||
context:any;
|
||||
funcOrValue:any;
|
||||
arity:int;
|
||||
dest;
|
||||
|
||||
@FIELD('next:ProtoRecord')
|
||||
@FIELD('prev:ProtoRecord')
|
||||
@FIELD('recordInConstruction:Record')
|
||||
next:ProtoRecord;
|
||||
prev:ProtoRecord;
|
||||
recordInConstruction:Record;
|
||||
constructor(recordRange:ProtoRecordRange,
|
||||
mode:int,
|
||||
funcOrValue,
|
||||
|
@ -74,30 +75,29 @@ export class ProtoRecord {
|
|||
* - Keep this object as lean as possible. (Lean in number of fields)
|
||||
*/
|
||||
export class Record {
|
||||
@FIELD('final recordRange:RecordRange')
|
||||
@FIELD('final protoRecord:ProtoRecord')
|
||||
@FIELD('next:Record')
|
||||
@FIELD('prev:Record')
|
||||
recordRange:RecordRange;
|
||||
protoRecord:ProtoRecord;
|
||||
next:Record;
|
||||
prev:Record;
|
||||
|
||||
/// This reference can change.
|
||||
@FIELD('nextEnabled:Record')
|
||||
nextEnabled:Record;
|
||||
|
||||
/// This reference can change.
|
||||
@FIELD('prevEnabled:Record')
|
||||
@FIELD('dest:Record')
|
||||
prevEnabled:Record;
|
||||
|
||||
@FIELD('previousValue')
|
||||
@FIELD('currentValue')
|
||||
previousValue;
|
||||
currentValue;
|
||||
|
||||
@FIELD('mode:int')
|
||||
@FIELD('context')
|
||||
@FIELD('funcOrValue')
|
||||
@FIELD('args:List')
|
||||
_mode:int;
|
||||
context;
|
||||
funcOrValue;
|
||||
args:List;
|
||||
|
||||
// Opaque data which will be the target of notification.
|
||||
// If the object is instance of Record, then it it is directly processed
|
||||
// Otherwise it is the context used by WatchGroupDispatcher.
|
||||
@FIELD('dest')
|
||||
dest;
|
||||
|
||||
constructor(recordRange:RecordRange, protoRecord:ProtoRecord, formatters:Map) {
|
||||
this.recordRange = recordRange;
|
||||
|
|
|
@ -11,15 +11,15 @@ import {
|
|||
} from './record';
|
||||
|
||||
import {FIELD, IMPLEMENTS, isBlank, isPresent, int, toBool, autoConvertAdd, BaseException} from 'facade/lang';
|
||||
import {ListWrapper, MapWrapper} from 'facade/collection';
|
||||
import {List, Map, ListWrapper, MapWrapper} from 'facade/collection';
|
||||
import {AST, AccessMember, ImplicitReceiver, AstVisitor, LiteralPrimitive,
|
||||
Binary, Formatter, MethodCall, FunctionCall, PrefixNot, Conditional,
|
||||
LiteralArray, LiteralMap, KeyedAccess, Chain, Assignment} from './parser/ast';
|
||||
|
||||
|
||||
export class ProtoRecordRange {
|
||||
@FIELD('headRecord:ProtoRecord')
|
||||
@FIELD('tailRecord:ProtoRecord')
|
||||
headRecord:ProtoRecord;
|
||||
tailRecord:ProtoRecord;
|
||||
constructor() {
|
||||
this.headRecord = null;
|
||||
this.tailRecord = null;
|
||||
|
@ -84,11 +84,11 @@ export class ProtoRecordRange {
|
|||
}
|
||||
|
||||
export class RecordRange {
|
||||
@FIELD('final protoRecordRange:ProtoRecordRange')
|
||||
@FIELD('final dispatcher:WatchGroupDispatcher')
|
||||
@FIELD('final headRecord:Record')
|
||||
@FIELD('final tailRecord:Record')
|
||||
@FIELD('final disabled:boolean')
|
||||
protoRecordRange:ProtoRecordRange;
|
||||
dispatcher:any; //WatchGroupDispatcher
|
||||
headRecord:Record;
|
||||
tailRecord:Record;
|
||||
disabled:boolean;
|
||||
// TODO(rado): the type annotation should be dispatcher:WatchGroupDispatcher.
|
||||
// but @Implements is not ready yet.
|
||||
constructor(protoRecordRange:ProtoRecordRange, dispatcher) {
|
||||
|
@ -270,6 +270,8 @@ export class WatchGroupDispatcher {
|
|||
|
||||
//todo: vsavkin: Create Array and Context destinations?
|
||||
class Destination {
|
||||
record:ProtoRecord;
|
||||
position:int;
|
||||
constructor(record:ProtoRecord, position:int) {
|
||||
this.record = record;
|
||||
this.position = position;
|
||||
|
@ -279,9 +281,9 @@ class Destination {
|
|||
|
||||
@IMPLEMENTS(AstVisitor)
|
||||
class ProtoRecordCreator {
|
||||
@FIELD('final protoRecordRange:ProtoRecordRange')
|
||||
@FIELD('headRecord:ProtoRecord')
|
||||
@FIELD('tailRecord:ProtoRecord')
|
||||
protoRecordRange:ProtoRecordRange;
|
||||
headRecord:ProtoRecord;
|
||||
tailRecord:ProtoRecord;
|
||||
constructor(protoRecordRange) {
|
||||
this.protoRecordRange = protoRecordRange;
|
||||
this.headRecord = null;
|
||||
|
|
|
@ -189,6 +189,8 @@ export function main() {
|
|||
}
|
||||
|
||||
class Person {
|
||||
name:string;
|
||||
address:Address;
|
||||
constructor(name:string, address:Address = null) {
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
|
@ -206,6 +208,7 @@ class Person {
|
|||
}
|
||||
|
||||
class Address {
|
||||
city:string;
|
||||
constructor(city:string) {
|
||||
this.city = city;
|
||||
}
|
||||
|
@ -216,12 +219,15 @@ class Address {
|
|||
}
|
||||
|
||||
class TestData {
|
||||
a;
|
||||
constructor(a) {
|
||||
this.a = a;
|
||||
}
|
||||
}
|
||||
|
||||
class LoggingDispatcher extends WatchGroupDispatcher {
|
||||
log:List;
|
||||
loggedValues:List;
|
||||
constructor() {
|
||||
this.log = null;
|
||||
this.loggedValues = null;
|
||||
|
|
|
@ -7,6 +7,9 @@ import {Formatter, LiteralPrimitive} from 'change_detection/parser/ast';
|
|||
import {ClosureMap} from 'change_detection/parser/closure_map';
|
||||
|
||||
class TestData {
|
||||
a;
|
||||
b;
|
||||
fnReturnValue;
|
||||
constructor(a, b, fnReturnValue) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
import {ABSTRACT, CONST, normalizeBlank} from 'facade/lang';
|
||||
import {List} from 'facade/collection';
|
||||
import {TemplateConfig} from './template_config';
|
||||
|
||||
|
||||
@ABSTRACT()
|
||||
export class Directive {
|
||||
selector:any; //string;
|
||||
bind:any;
|
||||
lightDomServices:any; //List;
|
||||
implementsTypes:any; //List;
|
||||
@CONST()
|
||||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
lightDomServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:string,
|
||||
bind:any,
|
||||
lightDomServices:List,
|
||||
implementsTypes:List
|
||||
}={})
|
||||
{
|
||||
this.selector = selector;
|
||||
this.lightDomServices = lightDomServices;
|
||||
this.implementsTypes = implementsTypes;
|
||||
this.bind = bind;
|
||||
}
|
||||
}
|
||||
|
||||
export class Component extends Directive {
|
||||
//TODO: vsavkin: uncomment it once the issue with defining fields in a sublass works
|
||||
template:any; //TemplateConfig;
|
||||
lightDomServices:any; //List;
|
||||
shadowDomServices:any; //List;
|
||||
componentServices:any; //List;
|
||||
|
||||
@CONST()
|
||||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
template,
|
||||
lightDomServices,
|
||||
shadowDomServices,
|
||||
componentServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:String,
|
||||
bind:Object,
|
||||
template:TemplateConfig,
|
||||
lightDomServices:List,
|
||||
shadowDomServices:List,
|
||||
componentServices:List,
|
||||
implementsTypes:List
|
||||
}={})
|
||||
{
|
||||
super({
|
||||
selector: selector,
|
||||
bind: bind,
|
||||
lightDomServices: lightDomServices,
|
||||
implementsTypes: implementsTypes});
|
||||
|
||||
this.template = template;
|
||||
this.lightDomServices = lightDomServices;
|
||||
this.shadowDomServices = shadowDomServices;
|
||||
this.componentServices = componentServices;
|
||||
}
|
||||
}
|
||||
|
||||
export class Decorator extends Directive {
|
||||
@CONST()
|
||||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
lightDomServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:string,
|
||||
bind:any,
|
||||
lightDomServices:List,
|
||||
implementsTypes:List
|
||||
}={})
|
||||
{
|
||||
super({
|
||||
selector: selector,
|
||||
bind: bind,
|
||||
lightDomServices: lightDomServices,
|
||||
implementsTypes: implementsTypes
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Template extends Directive {
|
||||
@CONST()
|
||||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
lightDomServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:string,
|
||||
bind:any,
|
||||
lightDomServices:List,
|
||||
implementsTypes:List
|
||||
}={})
|
||||
{
|
||||
super({
|
||||
selector: selector,
|
||||
bind: bind,
|
||||
lightDomServices: lightDomServices,
|
||||
implementsTypes: implementsTypes
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
import {Directive} from './directive';
|
||||
import {CONST} from 'facade/lang';
|
||||
|
||||
export class Component extends Directive {
|
||||
@CONST()
|
||||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
template,
|
||||
lightDomServices,
|
||||
shadowDomServices,
|
||||
componentServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:String,
|
||||
bind:Object,
|
||||
template:TemplateConfig,
|
||||
lightDomServices:List,
|
||||
shadowDomServices:List,
|
||||
componentServices:List,
|
||||
implementsTypes:List
|
||||
}={})
|
||||
{
|
||||
super({
|
||||
selector: selector,
|
||||
bind: bind,
|
||||
lightDomServices: lightDomServices,
|
||||
implementsTypes: implementsTypes});
|
||||
this.template = template;
|
||||
this.lightDomServices = lightDomServices;
|
||||
this.shadowDomServices = shadowDomServices;
|
||||
this.componentServices = componentServices;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
/*
|
||||
import 'package:angular/core.dart' as core;
|
||||
|
||||
|
||||
@Component(
|
||||
selector: 'example',
|
||||
template: const TemplateConfig(
|
||||
url: 'example.dart',
|
||||
uses: const [core.CONFIG],
|
||||
directives: const [CompA],
|
||||
formatters: const [Stringify]
|
||||
),
|
||||
componentServices: [...],
|
||||
shadowDomServices: [...]
|
||||
implementsTypes: const [App]
|
||||
)
|
||||
class Example implements App {}
|
||||
|
||||
class CompA {}
|
||||
|
||||
@Formatter()
|
||||
class Stringify {}
|
||||
|
||||
<CompA>
|
||||
LightDOM:
|
||||
</CompA>
|
||||
|
||||
CompA ShadowDOM:
|
||||
<div>
|
||||
<CompB></CompB>
|
||||
</div>
|
||||
|
||||
CompB SHadowDOM:
|
||||
<div></div>
|
||||
*/
|
|
@ -1,25 +0,0 @@
|
|||
import {Directive} from './directive';
|
||||
import {CONST} from 'facade/lang';
|
||||
|
||||
export class Decorator extends Directive {
|
||||
@CONST()
|
||||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
lightDomServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:String,
|
||||
bind:Object,
|
||||
lightDomServices:List,
|
||||
implementsTypes:List
|
||||
}={})
|
||||
{
|
||||
super({
|
||||
selector: selector,
|
||||
bind: bind,
|
||||
lightDomServices: lightDomServices,
|
||||
implementsTypes: implementsTypes
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
import {ABSTRACT, CONST} from 'facade/lang';
|
||||
import {List} from 'facade/collection';
|
||||
|
||||
|
||||
@ABSTRACT()
|
||||
export class Directive {
|
||||
@CONST()
|
||||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
lightDomServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:String,
|
||||
bind:Object,
|
||||
lightDomServices:List,
|
||||
implementsTypes:List
|
||||
}={})
|
||||
{
|
||||
this.selector = selector;
|
||||
this.lightDomServices = lightDomServices;
|
||||
this.implementsTypes = implementsTypes;
|
||||
this.bind = bind;
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
import {Directive} from './directive';
|
||||
import {CONST} from 'facade/lang';
|
||||
|
||||
export class Template extends Directive {
|
||||
@CONST()
|
||||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
lightDomServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:String,
|
||||
bind:Object,
|
||||
lightDomServices:List,
|
||||
implementsTypes:List
|
||||
}={})
|
||||
{
|
||||
super({
|
||||
selector: selector,
|
||||
bind: bind,
|
||||
lightDomServices: lightDomServices,
|
||||
implementsTypes: implementsTypes
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,7 +1,12 @@
|
|||
import {ABSTRACT, CONST} from 'facade/lang';
|
||||
// import {Type, List} from 'facade/lang';
|
||||
import {ABSTRACT, CONST, Type} from 'facade/lang';
|
||||
import {List} from 'facade/collection';
|
||||
|
||||
export class TemplateConfig {
|
||||
url:any; //string;
|
||||
inline:any; //string;
|
||||
directives:any; //List<Type>;
|
||||
formatters:any; //List<Type>;
|
||||
source:any;//List<TemplateConfig>;
|
||||
@CONST()
|
||||
constructor({
|
||||
url,
|
||||
|
@ -10,8 +15,8 @@ export class TemplateConfig {
|
|||
formatters,
|
||||
source
|
||||
}: {
|
||||
url: String,
|
||||
inline: String,
|
||||
url: string,
|
||||
inline: string,
|
||||
directives: List<Type>,
|
||||
formatters: List<Type>,
|
||||
source: List<TemplateConfig>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import {Type, FIELD} from 'facade/lang';
|
||||
import {Directive} from '../annotations/directive'
|
||||
import {Directive} from '../annotations/annotations'
|
||||
|
||||
/**
|
||||
* Combination of a type with the Directive annotation
|
||||
*/
|
||||
export class AnnotatedType {
|
||||
type:Type;
|
||||
annotation:Directive;
|
||||
constructor(type:Type, annotation:Directive) {
|
||||
this.annotation = annotation;
|
||||
this.type = type;
|
||||
|
|
|
@ -13,7 +13,7 @@ import {CompileElement} from './pipeline/compile_element';
|
|||
import {createDefaultSteps} from './pipeline/default_steps';
|
||||
import {TemplateLoader} from './template_loader';
|
||||
import {AnnotatedType} from './annotated_type';
|
||||
import {Component} from '../annotations/component';
|
||||
import {Component} from '../annotations/annotations';
|
||||
|
||||
/**
|
||||
* The compiler loads and translates the html templates of components into
|
||||
|
@ -21,6 +21,10 @@ import {Component} from '../annotations/component';
|
|||
* the CompilePipeline and the CompileSteps.
|
||||
*/
|
||||
export class Compiler {
|
||||
_templateLoader:TemplateLoader;
|
||||
_reflector: Reflector;
|
||||
_parser:Parser;
|
||||
_closureMap:ClosureMap;
|
||||
constructor(templateLoader:TemplateLoader, reflector: Reflector, parser:Parser, closureMap:ClosureMap) {
|
||||
this._templateLoader = templateLoader;
|
||||
this._reflector = reflector;
|
||||
|
@ -53,7 +57,7 @@ export class Compiler {
|
|||
// - templateRoot string
|
||||
// - precompiled template
|
||||
// - ProtoView
|
||||
var annotation: Component = component.annotation;
|
||||
var annotation:any = component.annotation;
|
||||
templateRoot = DOM.createTemplate(annotation.template.inline);
|
||||
}
|
||||
var pipeline = new CompilePipeline(this.createSteps(component));
|
||||
|
|
|
@ -2,16 +2,17 @@ import {ProtoElementInjector} from './element_injector';
|
|||
import {FIELD} from 'facade/lang';
|
||||
import {MapWrapper} from 'facade/collection';
|
||||
import {AnnotatedType} from './annotated_type';
|
||||
// Comment out as dartanalyzer does not look into @FIELD
|
||||
// import {List} from 'facade/collection';
|
||||
// import {ProtoView} from './view';
|
||||
import {List, Map} from 'facade/collection';
|
||||
import {ProtoView} from './view';
|
||||
|
||||
export class ElementBinder {
|
||||
@FIELD('final protoElementInjector:ProtoElementInjector')
|
||||
@FIELD('final componentDirective:AnnotatedType')
|
||||
@FIELD('final templateDirective:AnnotatedType')
|
||||
@FIELD('final textNodeIndices:List<int>')
|
||||
@FIELD('hasElementPropertyBindings:bool')
|
||||
protoElementInjector:ProtoElementInjector;
|
||||
componentDirective:AnnotatedType;
|
||||
templateDirective:AnnotatedType;
|
||||
textNodeIndices:List<int>;
|
||||
hasElementPropertyBindings:boolean;
|
||||
nestedProtoView: ProtoView;
|
||||
events:Map;
|
||||
constructor(
|
||||
protoElementInjector: ProtoElementInjector, componentDirective:AnnotatedType, templateDirective:AnnotatedType) {
|
||||
this.protoElementInjector = protoElementInjector;
|
||||
|
|
|
@ -15,6 +15,8 @@ var _undefined = new Object();
|
|||
var _staticKeys;
|
||||
|
||||
class StaticKeys {
|
||||
viewId:int;
|
||||
ngElementId:int;
|
||||
constructor() {
|
||||
//TODO: vsavkin Key.annotate(Key.get(View), 'static')
|
||||
this.viewId = Key.get(View).id;
|
||||
|
@ -28,11 +30,11 @@ class StaticKeys {
|
|||
}
|
||||
|
||||
class TreeNode {
|
||||
@FIELD('_parent:TreeNode')
|
||||
@FIELD('_head:TreeNode')
|
||||
@FIELD('_tail:TreeNode')
|
||||
@FIELD('_next:TreeNode')
|
||||
@FIELD('_prev:TreeNode')
|
||||
_parent:TreeNode;
|
||||
_head:TreeNode;
|
||||
_tail:TreeNode;
|
||||
_next:TreeNode;
|
||||
_prev:TreeNode;
|
||||
constructor(parent:TreeNode) {
|
||||
this._parent = parent;
|
||||
this._head = null;
|
||||
|
@ -71,6 +73,7 @@ class TreeNode {
|
|||
}
|
||||
|
||||
class DirectiveDependency extends Dependency {
|
||||
depth:int;
|
||||
constructor(key:Key, asPromise:boolean, lazy:boolean, properties:List, depth:int) {
|
||||
super(key, asPromise, lazy, properties);
|
||||
this.depth = depth;
|
||||
|
@ -90,9 +93,9 @@ class DirectiveDependency extends Dependency {
|
|||
}
|
||||
|
||||
export class PreBuiltObjects {
|
||||
@FIELD('final view:View')
|
||||
@FIELD('final element:NgElement')
|
||||
constructor(view, element:NgElement) {
|
||||
view:View;
|
||||
element:NgElement;
|
||||
constructor(view:View, element:NgElement) {
|
||||
this.view = view;
|
||||
this.element = element;
|
||||
}
|
||||
|
@ -119,30 +122,30 @@ ElementInjector:
|
|||
*/
|
||||
|
||||
export class ProtoElementInjector {
|
||||
@FIELD('_binding0:Binding')
|
||||
@FIELD('_binding1:Binding')
|
||||
@FIELD('_binding2:Binding')
|
||||
@FIELD('_binding3:Binding')
|
||||
@FIELD('_binding4:Binding')
|
||||
@FIELD('_binding5:Binding')
|
||||
@FIELD('_binding6:Binding')
|
||||
@FIELD('_binding7:Binding')
|
||||
@FIELD('_binding8:Binding')
|
||||
@FIELD('_binding9:Binding')
|
||||
@FIELD('_binding0IsComponent:int')
|
||||
@FIELD('_key0:int')
|
||||
@FIELD('_key1:int')
|
||||
@FIELD('_key2:int')
|
||||
@FIELD('_key3:int')
|
||||
@FIELD('_key4:int')
|
||||
@FIELD('_key5:int')
|
||||
@FIELD('_key6:int')
|
||||
@FIELD('_key7:int')
|
||||
@FIELD('_key8:int')
|
||||
@FIELD('_key9:int')
|
||||
@FIELD('final parent:ProtoElementInjector')
|
||||
@FIELD('final index:int')
|
||||
@FIELD('view:View')
|
||||
_binding0:Binding;
|
||||
_binding1:Binding;
|
||||
_binding2:Binding;
|
||||
_binding3:Binding;
|
||||
_binding4:Binding;
|
||||
_binding5:Binding;
|
||||
_binding6:Binding;
|
||||
_binding7:Binding;
|
||||
_binding8:Binding;
|
||||
_binding9:Binding;
|
||||
_binding0IsComponent:boolean;
|
||||
_keyId0:int;
|
||||
_keyId1:int;
|
||||
_keyId2:int;
|
||||
_keyId3:int;
|
||||
_keyId4:int;
|
||||
_keyId5:int;
|
||||
_keyId6:int;
|
||||
_keyId7:int;
|
||||
_keyId8:int;
|
||||
_keyId9:int;
|
||||
parent:ProtoElementInjector;
|
||||
index:int;
|
||||
view:View;
|
||||
constructor(parent:ProtoElementInjector, index:int, bindings:List, firstBindingIsComponent:boolean = false) {
|
||||
this.parent = parent;
|
||||
this.index = index;
|
||||
|
@ -194,21 +197,23 @@ export class ProtoElementInjector {
|
|||
}
|
||||
|
||||
export class ElementInjector extends TreeNode {
|
||||
@FIELD('_proto:ProtoElementInjector')
|
||||
@FIELD('_lightDomAppInjector:Injector')
|
||||
@FIELD('_shadowDomAppInjector:Injector')
|
||||
@FIELD('_host:ElementInjector')
|
||||
@FIELD('_obj0:Object')
|
||||
@FIELD('_obj1:Object')
|
||||
@FIELD('_obj2:Object')
|
||||
@FIELD('_obj3:Object')
|
||||
@FIELD('_obj4:Object')
|
||||
@FIELD('_obj5:Object')
|
||||
@FIELD('_obj6:Object')
|
||||
@FIELD('_obj7:Object')
|
||||
@FIELD('_obj8:Object')
|
||||
@FIELD('_obj9:Object')
|
||||
@FIELD('_view:View')
|
||||
_proto:ProtoElementInjector;
|
||||
_lightDomAppInjector:Injector;
|
||||
_shadowDomAppInjector:Injector;
|
||||
_host:ElementInjector;
|
||||
_obj0:any;
|
||||
_obj1:any;
|
||||
_obj2:any;
|
||||
_obj3:any;
|
||||
_obj4:any;
|
||||
_obj5:any;
|
||||
_obj6:any;
|
||||
_obj7:any;
|
||||
_obj8:any;
|
||||
_obj9:any;
|
||||
_view:View;
|
||||
_preBuiltObjects;
|
||||
_constructionCounter;
|
||||
constructor(proto:ProtoElementInjector, parent:ElementInjector, host:ElementInjector) {
|
||||
super(parent);
|
||||
if (isPresent(parent) && isPresent(host)) {
|
||||
|
@ -441,6 +446,7 @@ export class ElementInjector extends TreeNode {
|
|||
}
|
||||
|
||||
class OutOfBoundsAccess extends Error {
|
||||
message:string;
|
||||
constructor(index) {
|
||||
this.message = `Index ${index} is out-of-bounds.`;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
import {ListWrapper} from 'facade/collection';
|
||||
import {List, ListWrapper} from 'facade/collection';
|
||||
import {DOM} from 'facade/dom';
|
||||
import {CompileElement} from './compile_element';
|
||||
import {CompileStep} from './compile_step';
|
||||
|
||||
/**
|
||||
* Controls the processing order of elements.
|
||||
* Right now it only allows to add a parent element.
|
||||
*/
|
||||
export class CompileControl {
|
||||
_steps:List<CompileStep>;
|
||||
_currentStepIndex:number;
|
||||
_parent:CompileElement;
|
||||
_current:CompileElement;
|
||||
_results;
|
||||
constructor(steps) {
|
||||
this._steps = steps;
|
||||
this._currentStepIndex = 0;
|
||||
|
|
|
@ -2,9 +2,12 @@ import {List, Map, ListWrapper, MapWrapper} from 'facade/collection';
|
|||
import {Element, DOM} from 'facade/dom';
|
||||
import {int, isBlank, isPresent} from 'facade/lang';
|
||||
import {AnnotatedType} from '../annotated_type';
|
||||
import {Decorator} from '../../annotations/decorator';
|
||||
import {Component} from '../../annotations/component';
|
||||
import {Template} from '../../annotations/template';
|
||||
import {Decorator} from '../../annotations/annotations';
|
||||
import {Component} from '../../annotations/annotations';
|
||||
import {Template} from '../../annotations/annotations';
|
||||
import {ElementBinder} from '../element_binder';
|
||||
import {ProtoElementInjector} from '../element_injector';
|
||||
import {ProtoView} from '../view';
|
||||
|
||||
import {ASTWithSource} from 'change_detection/parser/ast';
|
||||
|
||||
|
@ -14,6 +17,21 @@ import {ASTWithSource} from 'change_detection/parser/ast';
|
|||
* by the CompileSteps starting out with the pure HTMLElement.
|
||||
*/
|
||||
export class CompileElement {
|
||||
element:Element;
|
||||
_attrs:Map;
|
||||
_classList:List;
|
||||
textNodeBindings:Map;
|
||||
propertyBindings:Map;
|
||||
eventBindings:Map;
|
||||
variableBindings:Map;
|
||||
decoratorDirectives:List<AnnotatedType>;
|
||||
templateDirective:AnnotatedType;
|
||||
componentDirective:AnnotatedType;
|
||||
isViewRoot:boolean;
|
||||
hasBindings:boolean;
|
||||
inheritedProtoView:ProtoView;
|
||||
inheritedProtoElementInjector:ProtoElementInjector;
|
||||
inheritedElementBinder:ElementBinder;
|
||||
constructor(element:Element) {
|
||||
this.element = element;
|
||||
this._attrs = null;
|
||||
|
|
|
@ -10,6 +10,7 @@ import {AnnotatedType} from '../annotated_type';
|
|||
* all elements in a template.
|
||||
*/
|
||||
export class CompilePipeline {
|
||||
_control:CompileControl;
|
||||
constructor(steps:List<CompileStep>) {
|
||||
this._control = new CompileControl(steps);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ import {SelectorMatcher} from '../selector';
|
|||
import {CssSelector} from '../selector';
|
||||
|
||||
import {AnnotatedType} from '../annotated_type';
|
||||
import {Template} from '../../annotations/template';
|
||||
import {Component} from '../../annotations/component';
|
||||
import {Template} from '../../annotations/annotations';
|
||||
import {Component} from '../../annotations/annotations';
|
||||
import {CompileStep} from './compile_step';
|
||||
import {CompileElement} from './compile_element';
|
||||
import {CompileControl} from './compile_control';
|
||||
|
@ -28,6 +28,7 @@ import {Reflector} from '../reflector';
|
|||
* in the property bindings)
|
||||
*/
|
||||
export class DirectiveParser extends CompileStep {
|
||||
_selectorMatcher:SelectorMatcher;
|
||||
constructor(directives:List<AnnotatedType>) {
|
||||
this._selectorMatcher = new SelectorMatcher();
|
||||
for (var i=0; i<directives.length; i++) {
|
||||
|
|
|
@ -6,8 +6,7 @@ import {Parser} from 'change_detection/parser/parser';
|
|||
import {ClosureMap} from 'change_detection/parser/closure_map';
|
||||
import {ProtoRecordRange} from 'change_detection/record_range';
|
||||
|
||||
import {Directive} from '../../annotations/directive';
|
||||
import {Component} from '../../annotations/component';
|
||||
import {Component, Directive} from '../../annotations/annotations';
|
||||
import {AnnotatedType} from '../annotated_type';
|
||||
import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from '../view';
|
||||
import {ProtoElementInjector} from '../element_injector';
|
||||
|
@ -44,12 +43,13 @@ import {CompileControl} from './compile_control';
|
|||
* with the flag `isViewRoot`.
|
||||
*/
|
||||
export class ElementBinderBuilder extends CompileStep {
|
||||
_closureMap:ClosureMap;
|
||||
constructor(closureMap:ClosureMap) {
|
||||
this._closureMap = closureMap;
|
||||
}
|
||||
|
||||
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||
var elementBinder;
|
||||
var elementBinder = null;
|
||||
if (current.hasBindings) {
|
||||
var protoView = current.inheritedProtoView;
|
||||
elementBinder = protoView.bindElement(current.inheritedProtoElementInjector,
|
||||
|
|
|
@ -23,6 +23,7 @@ var BIND_NAME_REGEXP = RegExpWrapper.create('^(?:(?:(bind)|(let)|(on))-(.+))|\\[
|
|||
* - CompileElement#variableBindings
|
||||
*/
|
||||
export class PropertyBindingParser extends CompileStep {
|
||||
_parser:Parser;
|
||||
constructor(parser:Parser) {
|
||||
this._parser = parser;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ export function interpolationToExpression(value:string):string {
|
|||
* - CompileElement#textNodeBindings
|
||||
*/
|
||||
export class TextInterpolationParser extends CompileStep {
|
||||
_parser:Parser;
|
||||
constructor(parser:Parser) {
|
||||
this._parser = parser;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import {CompileControl} from './compile_control';
|
|||
* - CompileElement#propertyBindings
|
||||
*/
|
||||
export class ViewSplitter extends CompileStep {
|
||||
_parser:Parser;
|
||||
constructor(parser:Parser) {
|
||||
this._parser = parser;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
library facade.compiler.reflector;
|
||||
|
||||
import 'dart:mirrors';
|
||||
import '../annotations/directive.dart';
|
||||
import '../annotations/annotations.dart';
|
||||
import './annotated_type.dart';
|
||||
import 'package:facade/lang.dart';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Type, isPresent, BaseException} from 'facade/lang';
|
||||
import {Directive} from '../annotations/directive';
|
||||
import {Directive} from '../annotations/annotations';
|
||||
import {AnnotatedType} from './annotated_type';
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,6 +16,9 @@ var _SELECTOR_REGEXP =
|
|||
* of selecting subsets out of them.
|
||||
*/
|
||||
export class CssSelector {
|
||||
element:string;
|
||||
classNames:List;
|
||||
attrs:List;
|
||||
static parse(selector:string):CssSelector {
|
||||
var cssSelector = new CssSelector();
|
||||
var matcher = RegExpWrapper.matcher(_SELECTOR_REGEXP, selector);
|
||||
|
@ -91,6 +94,13 @@ export class CssSelector {
|
|||
* are contained in a given CssSelector.
|
||||
*/
|
||||
export class SelectorMatcher {
|
||||
_selectables:List;
|
||||
_elementMap:Map;
|
||||
_elementPartialMap:Map;
|
||||
_classMap:Map;
|
||||
_classPartialMap:Map;
|
||||
_attrValueMap:Map;
|
||||
_attrValuePartialMap:Map;
|
||||
constructor() {
|
||||
this._selectables = ListWrapper.create();
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import {Promise} from 'facade/async';
|
|||
* Strategy to load component templates.
|
||||
*/
|
||||
export class TemplateLoader {
|
||||
load(url:String):Promise<Document> {
|
||||
load(url:string):Promise<Document> {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import {DOM, Element, Node, Text, DocumentFragment, TemplateElement} from 'facade/dom';
|
||||
import {ListWrapper, MapWrapper} from 'facade/collection';
|
||||
import {ListWrapper, MapWrapper, List} from 'facade/collection';
|
||||
import {ProtoRecordRange, RecordRange, WatchGroupDispatcher} from 'change_detection/record_range';
|
||||
import {Record} from 'change_detection/record';
|
||||
import {AST} from 'change_detection/parser/ast';
|
||||
|
@ -9,7 +9,6 @@ import {ElementBinder} from './element_binder';
|
|||
import {AnnotatedType} from './annotated_type';
|
||||
import {SetterFn} from 'change_detection/parser/closure_map';
|
||||
import {FIELD, IMPLEMENTS, int, isPresent, isBlank} from 'facade/lang';
|
||||
import {List} from 'facade/collection';
|
||||
import {Injector} from 'di/di';
|
||||
import {NgElement} from 'core/dom/element';
|
||||
|
||||
|
@ -21,16 +20,16 @@ const NG_BINDING_CLASS = 'ng-binding';
|
|||
@IMPLEMENTS(WatchGroupDispatcher)
|
||||
export class View {
|
||||
/// This list matches the _nodes list. It is sparse, since only Elements have ElementInjector
|
||||
@FIELD('final rootElementInjectors:List<ElementInjector>')
|
||||
@FIELD('final elementInjectors:List<ElementInjector>')
|
||||
@FIELD('final bindElements:List<Element>')
|
||||
@FIELD('final textNodes:List<Text>')
|
||||
@FIELD('final recordRange:RecordRange')
|
||||
rootElementInjectors:List<ElementInjector>;
|
||||
elementInjectors:List<ElementInjector>;
|
||||
bindElements:List<Element>;
|
||||
textNodes:List<Text>;
|
||||
recordRange:RecordRange;
|
||||
/// When the view is part of render tree, the DocumentFragment is empty, which is why we need
|
||||
/// to keep track of the nodes.
|
||||
@FIELD('final nodes:List<Node>')
|
||||
@FIELD('final onChangeDispatcher:OnChangeDispatcher')
|
||||
@FIELD('childViews: List<View>')
|
||||
nodes:List<Node>;
|
||||
onChangeDispatcher:OnChangeDispatcher;
|
||||
childViews: List<View>;
|
||||
constructor(nodes:List<Node>, elementInjectors:List,
|
||||
rootElementInjectors:List, textNodes:List, bindElements:List,
|
||||
protoRecordRange:ProtoRecordRange, context) {
|
||||
|
@ -70,9 +69,12 @@ export class View {
|
|||
}
|
||||
|
||||
export class ProtoView {
|
||||
@FIELD('final element:Element')
|
||||
@FIELD('final elementBinders:List<ElementBinder>')
|
||||
@FIELD('final protoRecordRange:ProtoRecordRange')
|
||||
element:Element;
|
||||
elementBinders:List<ElementBinder>;
|
||||
protoRecordRange:ProtoRecordRange;
|
||||
variableBindings: Map;
|
||||
textNodesWithBindingCount:int;
|
||||
elementsWithBindingCount:int;
|
||||
constructor(
|
||||
template:Element,
|
||||
protoRecordRange:ProtoRecordRange) {
|
||||
|
@ -299,8 +301,8 @@ export class ProtoView {
|
|||
}
|
||||
|
||||
export class ElementPropertyMemento {
|
||||
@FIELD('final _elementIndex:int')
|
||||
@FIELD('final _propertyName:string')
|
||||
_elementIndex:int;
|
||||
_propertyName:string;
|
||||
constructor(elementIndex:int, propertyName:string) {
|
||||
this._elementIndex = elementIndex;
|
||||
this._propertyName = propertyName;
|
||||
|
@ -313,10 +315,10 @@ export class ElementPropertyMemento {
|
|||
}
|
||||
|
||||
export class DirectivePropertyMemento {
|
||||
@FIELD('final _elementInjectorIndex:int')
|
||||
@FIELD('final _directiveIndex:int')
|
||||
@FIELD('final _setterName:string')
|
||||
@FIELD('final _setter:SetterFn')
|
||||
_elementInjectorIndex:int;
|
||||
_directiveIndex:int;
|
||||
_setterName:string;
|
||||
_setter:SetterFn;
|
||||
constructor(
|
||||
elementInjectorIndex:number,
|
||||
directiveIndex:number,
|
||||
|
@ -341,8 +343,8 @@ export class DirectivePropertyMemento {
|
|||
// notify is called by change detection, but done is called by our wrapper on detect changes.
|
||||
export class OnChangeDispatcher {
|
||||
|
||||
@FIELD('_lastView:View')
|
||||
@FIELD('_lastTarget:DirectivePropertyMemento')
|
||||
_lastView:View;
|
||||
_lastTarget:DirectivePropertyMemento;
|
||||
constructor() {
|
||||
this._lastView = null;
|
||||
this._lastTarget = null;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
/**
|
||||
* Define public API for Angular here
|
||||
*/
|
||||
export * from './annotations/directive';
|
||||
export * from './annotations/decorator';
|
||||
export * from './annotations/component';
|
||||
export * from './annotations/annotations';
|
||||
export * from './annotations/template_config';
|
||||
|
||||
export * from './application';
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import {Element} from 'facade/dom';
|
||||
|
||||
export class NgElement {
|
||||
domElement:Element;
|
||||
constructor(domElement) {
|
||||
this.domElement = domElement;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import {FIELD} from 'facade/lang';
|
||||
import {OnChangeDispatcher} from '../compiler/view';
|
||||
import {ChangeDetector} from 'change_detection/change_detector';
|
||||
|
||||
export class LifeCycle {
|
||||
|
||||
@FIELD('final _changeDetection:ChangeDetection')
|
||||
@FIELD('final _onChangeDispatcher:OnChangeDispatcher')
|
||||
_changeDetector:ChangeDetector;
|
||||
_onChangeDispatcher:OnChangeDispatcher;
|
||||
constructor() {
|
||||
this._changeDetection = null;
|
||||
this._changeDetector = null;
|
||||
this._onChangeDispatcher = null;
|
||||
}
|
||||
|
||||
digest() {
|
||||
_changeDetection.detectChanges();
|
||||
_changeDetector.detectChanges();
|
||||
_onChangeDispatcher.done();
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach} from 'test_lib/test_lib';
|
||||
import {bootstrap, appDocumentToken, appElementToken, documentDependentBindings}
|
||||
from 'core/application';
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
import {DOM} from 'facade/dom';
|
||||
import {ListWrapper} from 'facade/collection';
|
||||
import {PromiseWrapper} from 'facade/async';
|
||||
|
@ -16,6 +16,7 @@ import {TemplateConfig} from 'core/annotations/template_config';
|
|||
})
|
||||
})
|
||||
class HelloRootCmp {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
this.greeting = 'hello';
|
||||
}
|
||||
|
@ -29,6 +30,7 @@ class HelloRootCmp {
|
|||
})
|
||||
})
|
||||
class HelloRootCmp2 {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
this.greeting = 'hello';
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import {Compiler} from 'core/compiler/compiler';
|
|||
import {ProtoView} from 'core/compiler/view';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
import {TemplateLoader} from 'core/compiler/template_loader';
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
import {CompileElement} from 'core/compiler/pipeline/compile_element';
|
||||
import {CompileStep} from 'core/compiler/pipeline/compile_step'
|
||||
|
@ -98,6 +98,7 @@ class MainComponent {}
|
|||
class NestedComponent {}
|
||||
|
||||
class TestableCompiler extends Compiler {
|
||||
steps:List;
|
||||
constructor(templateLoader:TemplateLoader, reflector:Reflector, parser, closureMap, steps:List<CompileStep>) {
|
||||
super(templateLoader, reflector, parser, closureMap);
|
||||
this.steps = steps;
|
||||
|
@ -108,6 +109,7 @@ class TestableCompiler extends Compiler {
|
|||
}
|
||||
|
||||
class MockStep extends CompileStep {
|
||||
processClosure:Function;
|
||||
constructor(process) {
|
||||
this.processClosure = process;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach} from 'test_lib/test_lib';
|
||||
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, FakeObject} from 'test_lib/test_lib';
|
||||
import {isBlank, isPresent, FIELD, IMPLEMENTS} from 'facade/lang';
|
||||
import {ListWrapper, MapWrapper, List} from 'facade/collection';
|
||||
import {ProtoElementInjector, PreBuiltObjects} from 'core/compiler/element_injector';
|
||||
import {Parent, Ancestor} from 'core/annotations/visibility';
|
||||
import {Injector, Inject, bind} from 'di/di';
|
||||
import {View} from 'core/compiler/view';
|
||||
import {ProtoRecordRange} from 'change_detection/record_range';
|
||||
import {NgElement} from 'core/dom/element';
|
||||
|
||||
@IMPLEMENTS(View)
|
||||
class DummyView {}
|
||||
//TODO: vsavkin: use a spy object
|
||||
class DummyView extends View {
|
||||
constructor() {
|
||||
super(null, null, null, null, null, new ProtoRecordRange(), null);
|
||||
}
|
||||
}
|
||||
|
||||
class Directive {
|
||||
}
|
||||
|
@ -18,28 +23,28 @@ class SomeOtherDirective {
|
|||
}
|
||||
|
||||
class NeedsDirective {
|
||||
@FIELD("dependency:Directive")
|
||||
dependency:Directive;
|
||||
constructor(dependency:Directive){
|
||||
this.dependency = dependency;
|
||||
}
|
||||
}
|
||||
|
||||
class NeedDirectiveFromParent {
|
||||
@FIELD("dependency:Directive")
|
||||
dependency:Directive;
|
||||
constructor(@Parent() dependency:Directive){
|
||||
this.dependency = dependency;
|
||||
}
|
||||
}
|
||||
|
||||
class NeedDirectiveFromAncestor {
|
||||
@FIELD("dependency:Directive")
|
||||
dependency:Directive;
|
||||
constructor(@Ancestor() dependency:Directive){
|
||||
this.dependency = dependency;
|
||||
}
|
||||
}
|
||||
|
||||
class NeedsService {
|
||||
@FIELD("service:Object")
|
||||
service:any;
|
||||
constructor(@Inject("service") service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
@ -54,7 +59,7 @@ class B_Needs_A {
|
|||
}
|
||||
|
||||
class NeedsView {
|
||||
@FIELD("view:Object")
|
||||
view:any;
|
||||
constructor(@Inject(View) view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ import {Lexer} from 'change_detection/parser/lexer';
|
|||
import {Compiler} from 'core/compiler/compiler';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
|
||||
export function main() {
|
||||
|
@ -87,6 +87,7 @@ export function main() {
|
|||
bind: {'elprop':'dirProp'}
|
||||
})
|
||||
class MyDir {
|
||||
dirProp:string;
|
||||
constructor() {
|
||||
this.dirProp = '';
|
||||
}
|
||||
|
@ -98,6 +99,7 @@ class MyDir {
|
|||
})
|
||||
})
|
||||
class MyComp {
|
||||
ctxProp:string;
|
||||
constructor() {
|
||||
this.ctxProp = 'initial value';
|
||||
}
|
||||
|
@ -112,12 +114,14 @@ class MyComp {
|
|||
})
|
||||
})
|
||||
class ChildComp {
|
||||
ctxProp:string;
|
||||
constructor(service: MyService) {
|
||||
this.ctxProp = service.greeting;
|
||||
}
|
||||
}
|
||||
|
||||
class MyService {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
this.greeting = 'hello';
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ import {CompileStep} from 'core/compiler/pipeline/compile_step';
|
|||
import {CompileElement} from 'core/compiler/pipeline/compile_element';
|
||||
import {CompileControl} from 'core/compiler/pipeline/compile_control';
|
||||
import {DOM} from 'facade/dom';
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {Template} from 'core/annotations/template';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {Template} from 'core/annotations/annotations';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
import {Parser} from 'change_detection/parser/parser';
|
||||
|
@ -165,6 +165,7 @@ export function main() {
|
|||
}
|
||||
|
||||
class MockStep extends CompileStep {
|
||||
processClosure:Function;
|
||||
constructor(process) {
|
||||
this.processClosure = process;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ import {CompileElement} from 'core/compiler/pipeline/compile_element';
|
|||
import {CompileStep} from 'core/compiler/pipeline/compile_step'
|
||||
import {CompileControl} from 'core/compiler/pipeline/compile_control';
|
||||
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {Template} from 'core/annotations/template';
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {Template} from 'core/annotations/annotations';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'core/compiler/view';
|
||||
import {ProtoElementInjector} from 'core/compiler/element_injector';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
|
@ -265,6 +265,7 @@ class SomeDecoratorDirective {
|
|||
bind: {'boundprop1': 'decorProp'}
|
||||
})
|
||||
class SomeDecoratorDirectiveWithBinding {
|
||||
decorProp;
|
||||
constructor() {
|
||||
this.decorProp = null;
|
||||
}
|
||||
|
@ -278,6 +279,7 @@ class SomeTemplateDirective {
|
|||
bind: {'boundprop2': 'templProp'}
|
||||
})
|
||||
class SomeTemplateDirectiveWithBinding {
|
||||
templProp;
|
||||
constructor() {
|
||||
this.templProp = null;
|
||||
}
|
||||
|
@ -291,12 +293,16 @@ class SomeComponentDirective {
|
|||
bind: {'boundprop3': 'compProp'}
|
||||
})
|
||||
class SomeComponentDirectiveWithBinding {
|
||||
compProp;
|
||||
constructor() {
|
||||
this.compProp = null;
|
||||
}
|
||||
}
|
||||
|
||||
class Context {
|
||||
prop1;
|
||||
prop2;
|
||||
prop3;
|
||||
constructor() {
|
||||
this.prop1 = null;
|
||||
this.prop2 = null;
|
||||
|
@ -305,6 +311,7 @@ class Context {
|
|||
}
|
||||
|
||||
class MockStep extends CompileStep {
|
||||
processClosure:Function;
|
||||
constructor(process) {
|
||||
this.processClosure = process;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ import {CompileElement} from 'core/compiler/pipeline/compile_element';
|
|||
import {CompileStep} from 'core/compiler/pipeline/compile_step'
|
||||
import {CompileControl} from 'core/compiler/pipeline/compile_control';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
import {Template} from 'core/annotations/template';
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Template} from 'core/annotations/annotations';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
|
||||
export function main() {
|
||||
describe('ElementBindingMarker', () => {
|
||||
|
@ -101,6 +101,7 @@ function assertBinding(pipelineElement, shouldBePresent) {
|
|||
}
|
||||
|
||||
class MockStep extends CompileStep {
|
||||
processClosure:Function;
|
||||
constructor(process) {
|
||||
this.processClosure = process;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {describe, beforeEach, it, expect, iit, ddescribe} from 'test_lib/test_lib';
|
||||
import {ListWrapper} from 'facade/collection';
|
||||
import {ListWrapper, List} from 'facade/collection';
|
||||
import {DOM} from 'facade/dom';
|
||||
import {isPresent, NumberWrapper} from 'facade/lang';
|
||||
|
||||
|
@ -106,6 +106,7 @@ export function main() {
|
|||
}
|
||||
|
||||
class MockStep extends CompileStep {
|
||||
processClosure:Function;
|
||||
constructor(process) {
|
||||
this.processClosure = process;
|
||||
}
|
||||
|
@ -115,6 +116,7 @@ class MockStep extends CompileStep {
|
|||
}
|
||||
|
||||
class LoggingStep extends CompileStep {
|
||||
logs:List;
|
||||
constructor(logs) {
|
||||
this.logs = logs;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {describe, beforeEach, it, expect, iit, ddescribe} from 'test_lib/test_lib';
|
||||
import {isPresent, isBlank} from 'facade/lang';
|
||||
import {DOM} from 'facade/dom';
|
||||
import {ListWrapper} from 'facade/collection';
|
||||
import {List, ListWrapper} from 'facade/collection';
|
||||
|
||||
import {ProtoElementInjectorBuilder} from 'core/compiler/pipeline/proto_element_injector_builder';
|
||||
import {CompilePipeline} from 'core/compiler/pipeline/compile_pipeline';
|
||||
|
@ -10,9 +10,9 @@ import {CompileStep} from 'core/compiler/pipeline/compile_step'
|
|||
import {CompileControl} from 'core/compiler/pipeline/compile_control';
|
||||
import {ProtoView} from 'core/compiler/view';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
import {Template} from 'core/annotations/template';
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Template} from 'core/annotations/annotations';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
import {ProtoElementInjector} from 'core/compiler/element_injector';
|
||||
|
||||
export function main() {
|
||||
|
@ -107,6 +107,7 @@ export function main() {
|
|||
|
||||
|
||||
class TestableProtoElementInjectorBuilder extends ProtoElementInjectorBuilder {
|
||||
debugObjects:List;
|
||||
constructor() {
|
||||
this.debugObjects = [];
|
||||
}
|
||||
|
@ -127,6 +128,7 @@ class TestableProtoElementInjectorBuilder extends ProtoElementInjectorBuilder {
|
|||
}
|
||||
|
||||
class MockStep extends CompileStep {
|
||||
processClosure:Function;
|
||||
constructor(process) {
|
||||
this.processClosure = process;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ export function main() {
|
|||
}
|
||||
|
||||
class MockStep extends CompileStep {
|
||||
processClosure:Function;
|
||||
constructor(process) {
|
||||
this.processClosure = process;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {ddescribe, describe, it, iit, expect, beforeEach} from 'test_lib/test_lib';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {AnnotatedType} from 'core/compiler/annotated_type';
|
||||
|
||||
@Decorator({
|
||||
|
|
|
@ -2,8 +2,8 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit} from 'test_lib/te
|
|||
import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'core/compiler/view';
|
||||
import {ProtoElementInjector, ElementInjector} from 'core/compiler/element_injector';
|
||||
import {Reflector} from 'core/compiler/reflector';
|
||||
import {Component} from 'core/annotations/component';
|
||||
import {Decorator} from 'core/annotations/decorator';
|
||||
import {Component} from 'core/annotations/annotations';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {ProtoRecordRange} from 'change_detection/record_range';
|
||||
import {ChangeDetector} from 'change_detection/change_detector';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
|
@ -296,7 +296,7 @@ export function main() {
|
|||
}
|
||||
|
||||
class SomeDirective {
|
||||
@FIELD('prop')
|
||||
prop;
|
||||
constructor() {
|
||||
this.prop = 'foo';
|
||||
}
|
||||
|
@ -308,6 +308,7 @@ class SomeService {}
|
|||
componentServices: [SomeService]
|
||||
})
|
||||
class SomeComponent {
|
||||
service: SomeService;
|
||||
constructor(service: SomeService) {
|
||||
this.service = service;
|
||||
}
|
||||
|
@ -317,6 +318,8 @@ class SomeComponent {
|
|||
selector: '[dec]'
|
||||
})
|
||||
class ServiceDependentDecorator {
|
||||
component: SomeComponent;
|
||||
service: SomeService;
|
||||
constructor(component: SomeComponent, service: SomeService) {
|
||||
this.component = component;
|
||||
this.service = service;
|
||||
|
@ -324,14 +327,14 @@ class ServiceDependentDecorator {
|
|||
}
|
||||
|
||||
class AnotherDirective {
|
||||
@FIELD('prop')
|
||||
prop:string;
|
||||
constructor() {
|
||||
this.prop = 'anotherFoo';
|
||||
}
|
||||
}
|
||||
|
||||
class MyEvaluationContext {
|
||||
@FIELD('foo')
|
||||
foo:string;
|
||||
constructor() {
|
||||
this.foo = 'bar';
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import {CONST} from "facade/lang";
|
|||
*
|
||||
*/
|
||||
export class Inject {
|
||||
token;
|
||||
@CONST()
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
|
@ -26,6 +27,7 @@ export class Inject {
|
|||
*
|
||||
*/
|
||||
export class InjectPromise {
|
||||
token;
|
||||
@CONST()
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
|
@ -43,6 +45,7 @@ export class InjectPromise {
|
|||
*
|
||||
*/
|
||||
export class InjectLazy {
|
||||
token;
|
||||
@CONST()
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
|
|
|
@ -4,9 +4,10 @@ import {reflector} from './reflector';
|
|||
import {Key} from './key';
|
||||
|
||||
export class Dependency {
|
||||
@FIELD('final key:Key')
|
||||
@FIELD('final asPromise:bool')
|
||||
@FIELD('final lazy:bool')
|
||||
key:Key;
|
||||
asPromise:boolean;
|
||||
lazy:boolean;
|
||||
properties:List;
|
||||
constructor(key:Key, asPromise:boolean, lazy:boolean, properties:List) {
|
||||
this.key = key;
|
||||
this.asPromise = asPromise;
|
||||
|
@ -16,6 +17,11 @@ export class Dependency {
|
|||
}
|
||||
|
||||
export class Binding {
|
||||
key:Key;
|
||||
factory:Function;
|
||||
dependencies:List;
|
||||
providedAsPromise:boolean;
|
||||
|
||||
constructor(key:Key, factory:Function, dependencies:List, providedAsPromise:boolean) {
|
||||
this.key = key;
|
||||
this.factory = factory;
|
||||
|
@ -29,6 +35,7 @@ export function bind(token):BindingBuilder {
|
|||
}
|
||||
|
||||
export class BindingBuilder {
|
||||
token;
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ function constructResolvingPath(keys:List) {
|
|||
export class KeyMetadataError extends Error {}
|
||||
|
||||
export class ProviderError extends Error {
|
||||
keys:List;
|
||||
constructResolvingMessage:Function;
|
||||
message;
|
||||
constructor(key:Key, constructResolvingMessage:Function) {
|
||||
this.keys = [key];
|
||||
this.constructResolvingMessage = constructResolvingMessage;
|
||||
|
@ -82,6 +85,7 @@ export class InstantiationError extends ProviderError {
|
|||
}
|
||||
|
||||
export class InvalidBindingError extends Error {
|
||||
message:string;
|
||||
constructor(binding) {
|
||||
this.message = `Invalid binding ${binding}`;
|
||||
}
|
||||
|
@ -92,6 +96,7 @@ export class InvalidBindingError extends Error {
|
|||
}
|
||||
|
||||
export class NoAnnotationError extends Error {
|
||||
message:string;
|
||||
constructor(typeOrFunc) {
|
||||
this.message = `Cannot resolve all parameters for ${stringify(typeOrFunc)}`;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {reflector} from './reflector';
|
|||
var _constructing = new Object();
|
||||
|
||||
class _Waiting {
|
||||
promise:Promise;
|
||||
constructor(promise:Promise) {
|
||||
this.promise = promise;
|
||||
}
|
||||
|
@ -20,6 +21,12 @@ function _isWaiting(obj):boolean {
|
|||
|
||||
|
||||
export class Injector {
|
||||
_bindings:List;
|
||||
_instances:List;
|
||||
_parent:Injector;
|
||||
_defaultBindings:boolean;
|
||||
_asyncStrategy: _AsyncInjectorStrategy;
|
||||
_syncStrategy:_SyncInjectorStrategy;
|
||||
constructor(bindings:List, {parent=null, defaultBindings=false}={}) {
|
||||
var flatten = _flattenBindings(bindings, MapWrapper.create());
|
||||
this._bindings = this._createListOfBindings(flatten);
|
||||
|
@ -116,6 +123,7 @@ export class Injector {
|
|||
|
||||
|
||||
class _SyncInjectorStrategy {
|
||||
injector:Injector;
|
||||
constructor(injector:Injector) {
|
||||
this.injector = injector;
|
||||
}
|
||||
|
@ -163,6 +171,7 @@ class _SyncInjectorStrategy {
|
|||
|
||||
|
||||
class _AsyncInjectorStrategy {
|
||||
injector:Injector;
|
||||
constructor(injector:Injector) {
|
||||
this.injector = injector;
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ import {MapWrapper, Map} from 'facade/collection';
|
|||
import {FIELD, int, isPresent} from 'facade/lang';
|
||||
|
||||
export class Key {
|
||||
@FIELD('final token')
|
||||
@FIELD('final id:int')
|
||||
@FIELD('metadata:Object')
|
||||
token;
|
||||
id:int;
|
||||
metadata:any;
|
||||
constructor(token, id:int) {
|
||||
this.token = token;
|
||||
this.id = id;
|
||||
|
@ -30,7 +30,7 @@ export class Key {
|
|||
}
|
||||
|
||||
export class KeyRegistry {
|
||||
@FIELD('final _allKeys:Map')
|
||||
_allKeys:Map;
|
||||
constructor() {
|
||||
this._allKeys = MapWrapper.create();
|
||||
}
|
||||
|
|
|
@ -13,12 +13,14 @@ class SynchronousUserList {
|
|||
}
|
||||
|
||||
class UserController {
|
||||
list:UserList;
|
||||
constructor(list:UserList) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncUserController {
|
||||
userList;
|
||||
constructor(@InjectPromise(UserList) userList) {
|
||||
this.userList = userList;
|
||||
}
|
||||
|
|
|
@ -21,18 +21,22 @@ class TurboEngine extends Engine {
|
|||
}
|
||||
|
||||
class Car {
|
||||
engine:Engine;
|
||||
constructor(engine:Engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
}
|
||||
|
||||
class CarWithLazyEngine {
|
||||
engineFactory;
|
||||
constructor(@InjectLazy(Engine) engineFactory) {
|
||||
this.engineFactory = engineFactory;
|
||||
}
|
||||
}
|
||||
|
||||
class CarWithDashboard {
|
||||
engine:Engine;
|
||||
dashboard:Dashboard;
|
||||
constructor(engine:Engine, dashboard:Dashboard) {
|
||||
this.engine = engine;
|
||||
this.dashboard = dashboard;
|
||||
|
@ -40,12 +44,14 @@ class CarWithDashboard {
|
|||
}
|
||||
|
||||
class SportsCar extends Car {
|
||||
engine:Engine;
|
||||
constructor(engine:Engine) {
|
||||
super(engine);
|
||||
}
|
||||
}
|
||||
|
||||
class CarWithInject {
|
||||
engine:Engine;
|
||||
constructor(@Inject(TurboEngine) engine:Engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import {describe, it, expect, beforeEach} from 'test_lib/test_lib';
|
||||
import {describe, iit, it, expect, beforeEach} from 'test_lib/test_lib';
|
||||
import {Key, KeyRegistry} from 'di/di';
|
||||
|
||||
export function main() {
|
||||
|
||||
describe("key", function () {
|
||||
var registry;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import {bootstrap, Component, Decorator, TemplateConfig, NgElement} from 'core/c
|
|||
})
|
||||
})
|
||||
class HelloCmp {
|
||||
greeting: string;
|
||||
constructor(service: GreetingService) {
|
||||
this.greeting = service.greeting;
|
||||
}
|
||||
|
@ -49,6 +50,7 @@ class RedDec {
|
|||
|
||||
// A service used by the HelloCmp component.
|
||||
class GreetingService {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
this.greeting = 'hello';
|
||||
}
|
||||
|
|
|
@ -159,3 +159,6 @@ dynamic getMapKey(value) {
|
|||
return value.isNaN ? _NAN_KEY : value;
|
||||
}
|
||||
|
||||
normalizeBlank(obj) {
|
||||
return isBlank(obj) ? null : obj;
|
||||
}
|
|
@ -194,3 +194,7 @@ export function looseIdentical(a, b):boolean {
|
|||
export function getMapKey(value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function normalizeBlank(obj) {
|
||||
return isBlank(obj) ? null : obj;
|
||||
}
|
|
@ -2,6 +2,7 @@ import {describe, it, iit, ddescribe, expect} from 'test_lib/test_lib';
|
|||
import {MapWrapper} from 'facade/collection';
|
||||
|
||||
class TestObj {
|
||||
prop;
|
||||
constructor(prop) {
|
||||
this.prop = prop;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ class Inject {}
|
|||
class Bar {}
|
||||
|
||||
class Provide {
|
||||
token;
|
||||
|
||||
@CONST()
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
|
@ -13,6 +15,8 @@ class Provide {
|
|||
}
|
||||
|
||||
class AnnotateMe {
|
||||
maybe;
|
||||
|
||||
@CONST()
|
||||
constructor({maybe = 'default'} = {}) {
|
||||
this.maybe = maybe;
|
||||
|
|
|
@ -13,6 +13,8 @@ var max = (a, b) => {
|
|||
};
|
||||
|
||||
class LexicalThis {
|
||||
zero;
|
||||
|
||||
constructor() {
|
||||
this.zero = 0;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import {ddescribe, describe, it, expect} from 'test_lib/test_lib';
|
||||
import {CONST} from './fixtures/annotations';
|
||||
|
||||
// Constructor
|
||||
// Define fields
|
||||
class Foo {
|
||||
a;
|
||||
b;
|
||||
|
||||
constructor(a, b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
|
@ -15,6 +16,8 @@ class Foo {
|
|||
}
|
||||
|
||||
class SubFoo extends Foo {
|
||||
c;
|
||||
|
||||
constructor(a, b) {
|
||||
this.c = 3;
|
||||
super(a, b);
|
||||
|
@ -25,6 +28,8 @@ class SubFoo extends Foo {
|
|||
class ConstClass {}
|
||||
|
||||
class Const {
|
||||
a;
|
||||
|
||||
@CONST
|
||||
constructor(a:number) {
|
||||
this.a = a;
|
||||
|
@ -32,6 +37,8 @@ class Const {
|
|||
}
|
||||
|
||||
class SubConst extends Const {
|
||||
b;
|
||||
|
||||
@CONST
|
||||
constructor(a:number, b:number) {
|
||||
super(a);
|
||||
|
|
|
@ -5,6 +5,8 @@ function sum(a, b) {
|
|||
}
|
||||
|
||||
class ConstructorWithNamedParams {
|
||||
sum;
|
||||
|
||||
constructor(a, {b=1, c=2}) {
|
||||
this.sum = a + b + c;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ class Bar {
|
|||
}
|
||||
|
||||
class Foo {
|
||||
a;
|
||||
b;
|
||||
|
||||
constructor(a: number, b: number) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
|
|
|
@ -25,7 +25,6 @@ import {
|
|||
} from 'traceur/src/syntax/trees/ParseTrees';
|
||||
|
||||
import {
|
||||
ClassFieldDeclaration,
|
||||
PropertyConstructorAssignment
|
||||
} from '../syntax/trees/ParseTrees';
|
||||
|
||||
|
@ -73,30 +72,6 @@ export class ClassTransformer extends ParseTreeTransformer {
|
|||
// Rename "constructor" to the class name.
|
||||
elementTree.name.literalToken.value = className;
|
||||
|
||||
// Collect all fields, defined in the constructor.
|
||||
elementTree.body.statements.forEach(function(statement) {
|
||||
var exp = statement.expression;
|
||||
if (exp &&
|
||||
exp.type === BINARY_EXPRESSION &&
|
||||
exp.operator.type === EQUAL &&
|
||||
exp.left.type === MEMBER_EXPRESSION &&
|
||||
exp.left.operand.type === THIS_EXPRESSION) {
|
||||
|
||||
var typeAnnotation;
|
||||
|
||||
if (exp.right.type === IDENTIFIER_EXPRESSION) {
|
||||
// `this.field = variable;`
|
||||
// we can infer the type of the field from the variable when it is a typed arg
|
||||
var varName = exp.right.getStringValue();
|
||||
typeAnnotation = argumentTypesMap[varName] || null;
|
||||
}
|
||||
|
||||
var fieldName = exp.left.memberName.value;
|
||||
var lvalue = new BindingIdentifier(tree.location, fieldName);
|
||||
fields.push(new ClassFieldDeclaration(tree.location, lvalue, typeAnnotation, isConst));
|
||||
}
|
||||
});
|
||||
|
||||
// Compute the initializer list
|
||||
var initializerList = [];
|
||||
var superCall = that._extractSuperCall(elementTree.body);
|
||||
|
@ -149,6 +124,11 @@ export class ClassTransformer extends ParseTreeTransformer {
|
|||
|
||||
// Add the field definitions to the beginning of the class.
|
||||
tree.elements = fields.concat(tree.elements);
|
||||
if (isConst) {
|
||||
tree.elements.forEach(function(element) {
|
||||
element.isFinal = true;
|
||||
});
|
||||
}
|
||||
|
||||
return super.transformClassDeclaration(tree);
|
||||
}
|
||||
|
|
|
@ -45,8 +45,11 @@ export class DartParseTreeWriter extends JavaScriptParseTreeWriter {
|
|||
}
|
||||
|
||||
if (tree.typeAnnotation === null) {
|
||||
this.write_(VAR);
|
||||
this.write_(tree.isFinal ? 'final' : VAR);
|
||||
} else {
|
||||
if (tree.isFinal) {
|
||||
this.write_('final');
|
||||
}
|
||||
this.writeType_(tree.typeAnnotation);
|
||||
}
|
||||
this.writeSpace_();
|
||||
|
@ -211,6 +214,7 @@ export class DartParseTreeWriter extends JavaScriptParseTreeWriter {
|
|||
case 'number': return 'num';
|
||||
case 'boolean': return 'bool';
|
||||
case 'string': return 'String';
|
||||
case 'any': return 'dynamic';
|
||||
case 'Promise': return 'Future';
|
||||
default: return typeName;
|
||||
}
|
||||
|
@ -244,25 +248,6 @@ export class DartParseTreeWriter extends JavaScriptParseTreeWriter {
|
|||
}
|
||||
}
|
||||
|
||||
visitClassFieldDeclaration(tree) {
|
||||
if (tree.isFinal) {
|
||||
// `final <type> name;` or `final name;` for untyped variable
|
||||
this.write_('final');
|
||||
this.writeSpace_();
|
||||
this.writeType_(tree.typeAnnotation);
|
||||
} else {
|
||||
// `<type> name;` or `var name;`
|
||||
if (tree.typeAnnotation) {
|
||||
this.writeType_(tree.typeAnnotation);
|
||||
} else {
|
||||
this.write_(VAR);
|
||||
this.writeSpace_();
|
||||
}
|
||||
}
|
||||
|
||||
this.write_(tree.lvalue.getStringValue());
|
||||
this.write_(SEMI_COLON);
|
||||
}
|
||||
|
||||
writeType_(typeAnnotation) {
|
||||
if (!typeAnnotation) {
|
||||
|
|
|
@ -4,36 +4,6 @@ import {PropertyMethodAssignment} from 'traceur/src/syntax/trees/ParseTrees';
|
|||
|
||||
import * as ParseTreeType from './ParseTreeType';
|
||||
|
||||
// Class field declaration
|
||||
export class ClassFieldDeclaration extends ParseTree {
|
||||
constructor(location, lvalue, typeAnnotation, isFinal) {
|
||||
this.location = location;
|
||||
this.lvalue = lvalue;
|
||||
this.typeAnnotation = typeAnnotation;
|
||||
this.isFinal = isFinal;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return CLASS_FIELD_DECLARATION;
|
||||
}
|
||||
|
||||
visit(visitor) {
|
||||
if (visitor.visitClassFieldDeclaration) {
|
||||
visitor.visitClassFieldDeclaration(this);
|
||||
}
|
||||
}
|
||||
|
||||
transform(transformer) {
|
||||
if (transformer.transformClassFieldDeclaration) {
|
||||
return transformer.transformClassFieldDeclaration(this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
var CLASS_FIELD_DECLARATION = ParseTreeType.CLASS_FIELD_DECLARATION;
|
||||
|
||||
// Class constructor
|
||||
export class PropertyConstructorAssignment extends PropertyMethodAssignment {
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue