From 044625a09852415b4275da5bc32c4a6f10ff157f Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Fri, 21 Nov 2014 21:19:23 -0800 Subject: [PATCH] chore: Make field declarations explicit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’; } } ``` --- .../src/compiler/compiler_benchmark.js | 5 +- .../change_detection/src/change_detector.js | 3 +- .../src/collection_changes.js | 62 +++++----- modules/change_detection/src/map_changes.js | 44 +++---- modules/change_detection/src/parser/ast.js | 64 +++++----- modules/change_detection/src/parser/lexer.js | 18 +-- modules/change_detection/src/parser/parser.js | 14 +-- modules/change_detection/src/record.js | 46 +++---- modules/change_detection/src/record_range.js | 24 ++-- .../test/change_detector_spec.js | 6 + .../test/parser/parser_spec.js | 3 + modules/core/src/annotations/annotations.js | 115 ++++++++++++++++++ modules/core/src/annotations/component.js | 71 ----------- modules/core/src/annotations/decorator.js | 25 ---- modules/core/src/annotations/directive.js | 25 ---- modules/core/src/annotations/template.js | 25 ---- .../core/src/annotations/template_config.js | 13 +- modules/core/src/compiler/annotated_type.js | 4 +- modules/core/src/compiler/compiler.js | 8 +- modules/core/src/compiler/element_binder.js | 17 +-- modules/core/src/compiler/element_injector.js | 100 ++++++++------- .../src/compiler/pipeline/compile_control.js | 8 +- .../src/compiler/pipeline/compile_element.js | 24 +++- .../src/compiler/pipeline/compile_pipeline.js | 1 + .../src/compiler/pipeline/directive_parser.js | 5 +- .../pipeline/element_binder_builder.js | 6 +- .../pipeline/property_binding_parser.js | 1 + .../pipeline/text_interpolation_parser.js | 1 + .../src/compiler/pipeline/view_splitter.js | 1 + modules/core/src/compiler/reflector.dart | 2 +- modules/core/src/compiler/reflector.es6 | 2 +- modules/core/src/compiler/selector.js | 10 ++ modules/core/src/compiler/template_loader.js | 2 +- modules/core/src/compiler/view.js | 44 +++---- modules/core/src/core.js | 4 +- modules/core/src/dom/element.js | 3 + modules/core/src/life_cycle/life_cycle.js | 10 +- modules/core/test/application_spec.js | 4 +- modules/core/test/compiler/compiler_spec.js | 4 +- .../test/compiler/element_injector_spec.js | 21 ++-- .../core/test/compiler/integration_spec.js | 8 +- .../pipeline/directive_parser_spec.js | 7 +- .../pipeline/element_binder_builder_spec.js | 13 +- .../pipeline/element_binding_marker_spec.js | 7 +- .../test/compiler/pipeline/pipeline_spec.js | 4 +- .../proto_element_injector_builder_spec.js | 10 +- .../pipeline/proto_view_builder_spec.js | 1 + modules/core/test/compiler/reflector_spec.js | 2 +- modules/core/test/compiler/view_spec.js | 13 +- modules/di/src/annotations.js | 3 + modules/di/src/binding.js | 13 +- modules/di/src/exceptions.js | 5 + modules/di/src/injector.js | 9 ++ modules/di/src/key.js | 8 +- modules/di/test/di/async_spec.js | 2 + modules/di/test/di/injector_spec.js | 6 + modules/di/test/di/key_spec.js | 3 +- modules/examples/src/hello_world/app.js | 2 + modules/facade/src/lang.dart | 3 + modules/facade/src/lang.es6 | 4 + modules/test_lib/test/test_lib_spec.js | 1 + tools/transpiler/spec/annotations_spec.js | 4 + tools/transpiler/spec/arrow_functions_spec.js | 2 + tools/transpiler/spec/classes_spec.js | 11 +- tools/transpiler/spec/functions_spec.js | 2 + tools/transpiler/spec/types_spec.js | 3 + .../src/codegeneration/ClassTransformer.js | 30 +---- .../outputgeneration/DartParseTreeWriter.js | 25 +--- .../transpiler/src/syntax/trees/ParseTrees.js | 30 ----- 69 files changed, 572 insertions(+), 504 deletions(-) create mode 100644 modules/core/src/annotations/annotations.js delete mode 100644 modules/core/src/annotations/component.js delete mode 100644 modules/core/src/annotations/decorator.js delete mode 100644 modules/core/src/annotations/directive.js delete mode 100644 modules/core/src/annotations/template.js diff --git a/modules/benchmarks/src/compiler/compiler_benchmark.js b/modules/benchmarks/src/compiler/compiler_benchmark.js index 5f6a82e2bb..9023155d2f 100644 --- a/modules/benchmarks/src/compiler/compiler_benchmark.js +++ b/modules/benchmarks/src/compiler/compiler_benchmark.js @@ -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(); } diff --git a/modules/change_detection/src/change_detector.js b/modules/change_detection/src/change_detector.js index f2e223e616..5d94d4d1c2 100644 --- a/modules/change_detection/src/change_detector.js +++ b/modules/change_detection/src/change_detector.js @@ -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; } diff --git a/modules/change_detection/src/collection_changes.js b/modules/change_detection/src/collection_changes.js index 07e13b290e..9296be4f0a 100644 --- a/modules/change_detection/src/collection_changes.js +++ b/modules/change_detection/src/collection_changes.js @@ -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 _previousItHead; - CollectionChangeItem _itHead, _itTail; - CollectionChangeItem _additionsHead, _additionsTail; - CollectionChangeItem _movesHead, _movesTail; - CollectionChangeItem _removalsHead, _removalsTail; - */ + _length:int; + _linkedRecords:_DuplicateMap; + _unlinkedRecords:_DuplicateMap; + _previousItHead:CollectionChangeRecord ; + _itHead:CollectionChangeRecord; + _itTail:CollectionChangeRecord ; + _additionsHead:CollectionChangeRecord; + _additionsTail:CollectionChangeRecord ; + _movesHead:CollectionChangeRecord; + _movesTail:CollectionChangeRecord ; + _removalsHead:CollectionChangeRecord; + _removalsTail:CollectionChangeRecord ; 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 _nextPrevious; - CollectionChangeItem _prev, _next; - CollectionChangeItem _prevDup, _nextDup; - CollectionChangeItem _prevRemoved, _nextRemoved; - CollectionChangeItem _nextAdded; - CollectionChangeItem _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. */ diff --git a/modules/change_detection/src/map_changes.js b/modules/change_detection/src/map_changes.js index b1b4f4d635..c2f2c69ba7 100644 --- a/modules/change_detection/src/map_changes.js +++ b/modules/change_detection/src/map_changes.js @@ -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(); - Map _map; + _records:Map; + _map:Map; - Map get map => _map; - - MapKeyValue _mapHead; - MapKeyValue _previousMapHead; - MapKeyValue _changesHead, _changesTail; - MapKeyValue _additionsHead, _additionsTail; - MapKeyValue _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 _nextPrevious; - //MapKeyValue _next; - //MapKeyValue _nextAdded; - //MapKeyValue _nextRemoved, _prevRemoved; - //MapKeyValue _nextChanged; + key; + _previousValue; + _currentValue; + + _nextPrevious:MapChangeRecord; + _next:MapChangeRecord; + _nextAdded:MapChangeRecord; + _nextRemoved:MapChangeRecord; + _prevRemoved:MapChangeRecord; + _nextChanged:MapChangeRecord; constructor(key) { this.key = key; diff --git a/modules/change_detection/src/parser/ast.js b/modules/change_detection/src/parser/ast.js index fe39d133f6..2d30c46138 100644 --- a/modules/change_detection/src/parser/ast.js +++ b/modules/change_detection/src/parser/ast.js @@ -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') + exp:AST; + name:string; + args:List; + allArgs:List; 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. diff --git a/modules/change_detection/src/parser/lexer.js b/modules/change_detection/src/parser/lexer.js index a4763627b9..bee586d185 100644 --- a/modules/change_detection/src/parser/lexer.js +++ b/modules/change_detection/src/parser/lexer.js @@ -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; diff --git a/modules/change_detection/src/parser/parser.js b/modules/change_detection/src/parser/parser.js index 6e4c1634cd..e49ffccd11 100644 --- a/modules/change_detection/src/parser/parser.js +++ b/modules/change_detection/src/parser/parser.js @@ -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') - @FIELD('final closureMap:ClosureMap') - @FIELD('final parseAction:boolean') - @FIELD('index:int') + input:string; + tokens:List; + closureMap:ClosureMap; + parseAction:boolean; + index:int; constructor(input:string, tokens:List, closureMap:ClosureMap, parseAction:boolean) { this.input = input; this.tokens = tokens; diff --git a/modules/change_detection/src/record.js b/modules/change_detection/src/record.js index 33462044dd..9dcb0b0b1e 100644 --- a/modules/change_detection/src/record.js +++ b/modules/change_detection/src/record.js @@ -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; diff --git a/modules/change_detection/src/record_range.js b/modules/change_detection/src/record_range.js index 9fbefa59ca..d1f6f0429a 100644 --- a/modules/change_detection/src/record_range.js +++ b/modules/change_detection/src/record_range.js @@ -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; diff --git a/modules/change_detection/test/change_detector_spec.js b/modules/change_detection/test/change_detector_spec.js index e54e1de46f..14f1c3ce09 100644 --- a/modules/change_detection/test/change_detector_spec.js +++ b/modules/change_detection/test/change_detector_spec.js @@ -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; diff --git a/modules/change_detection/test/parser/parser_spec.js b/modules/change_detection/test/parser/parser_spec.js index d5b9f6a2e2..fedae075c3 100644 --- a/modules/change_detection/test/parser/parser_spec.js +++ b/modules/change_detection/test/parser/parser_spec.js @@ -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; diff --git a/modules/core/src/annotations/annotations.js b/modules/core/src/annotations/annotations.js new file mode 100644 index 0000000000..f6333023df --- /dev/null +++ b/modules/core/src/annotations/annotations.js @@ -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 + }); + } +} diff --git a/modules/core/src/annotations/component.js b/modules/core/src/annotations/component.js deleted file mode 100644 index 3945647968..0000000000 --- a/modules/core/src/annotations/component.js +++ /dev/null @@ -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 {} - - - LightDOM: - - -CompA ShadowDOM: -
- -
- -CompB SHadowDOM: -
-*/ diff --git a/modules/core/src/annotations/decorator.js b/modules/core/src/annotations/decorator.js deleted file mode 100644 index b60b1fe33a..0000000000 --- a/modules/core/src/annotations/decorator.js +++ /dev/null @@ -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 - }); - } -} diff --git a/modules/core/src/annotations/directive.js b/modules/core/src/annotations/directive.js deleted file mode 100644 index 0e86898f93..0000000000 --- a/modules/core/src/annotations/directive.js +++ /dev/null @@ -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; - } -} diff --git a/modules/core/src/annotations/template.js b/modules/core/src/annotations/template.js deleted file mode 100644 index 12220e22f3..0000000000 --- a/modules/core/src/annotations/template.js +++ /dev/null @@ -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 - }); - } -} diff --git a/modules/core/src/annotations/template_config.js b/modules/core/src/annotations/template_config.js index d180dbc2e5..dee67a9012 100644 --- a/modules/core/src/annotations/template_config.js +++ b/modules/core/src/annotations/template_config.js @@ -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; + formatters:any; //List; + source:any;//List; @CONST() constructor({ url, @@ -10,8 +15,8 @@ export class TemplateConfig { formatters, source }: { - url: String, - inline: String, + url: string, + inline: string, directives: List, formatters: List, source: List diff --git a/modules/core/src/compiler/annotated_type.js b/modules/core/src/compiler/annotated_type.js index f2ec86cc3e..27d201c8a2 100644 --- a/modules/core/src/compiler/annotated_type.js +++ b/modules/core/src/compiler/annotated_type.js @@ -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; diff --git a/modules/core/src/compiler/compiler.js b/modules/core/src/compiler/compiler.js index b655a59bed..0a2490adeb 100644 --- a/modules/core/src/compiler/compiler.js +++ b/modules/core/src/compiler/compiler.js @@ -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)); diff --git a/modules/core/src/compiler/element_binder.js b/modules/core/src/compiler/element_binder.js index 6d1a704c2e..ad5b9b0530 100644 --- a/modules/core/src/compiler/element_binder.js +++ b/modules/core/src/compiler/element_binder.js @@ -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') - @FIELD('hasElementPropertyBindings:bool') + protoElementInjector:ProtoElementInjector; + componentDirective:AnnotatedType; + templateDirective:AnnotatedType; + textNodeIndices:List; + hasElementPropertyBindings:boolean; + nestedProtoView: ProtoView; + events:Map; constructor( protoElementInjector: ProtoElementInjector, componentDirective:AnnotatedType, templateDirective:AnnotatedType) { this.protoElementInjector = protoElementInjector; diff --git a/modules/core/src/compiler/element_injector.js b/modules/core/src/compiler/element_injector.js index 1de7cedc1f..ec47d1d8d6 100644 --- a/modules/core/src/compiler/element_injector.js +++ b/modules/core/src/compiler/element_injector.js @@ -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.`; } diff --git a/modules/core/src/compiler/pipeline/compile_control.js b/modules/core/src/compiler/pipeline/compile_control.js index a1bb786bf5..f7402a1a03 100644 --- a/modules/core/src/compiler/pipeline/compile_control.js +++ b/modules/core/src/compiler/pipeline/compile_control.js @@ -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; + _currentStepIndex:number; + _parent:CompileElement; + _current:CompileElement; + _results; constructor(steps) { this._steps = steps; this._currentStepIndex = 0; diff --git a/modules/core/src/compiler/pipeline/compile_element.js b/modules/core/src/compiler/pipeline/compile_element.js index 83245972ba..a2bffb8102 100644 --- a/modules/core/src/compiler/pipeline/compile_element.js +++ b/modules/core/src/compiler/pipeline/compile_element.js @@ -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; + templateDirective:AnnotatedType; + componentDirective:AnnotatedType; + isViewRoot:boolean; + hasBindings:boolean; + inheritedProtoView:ProtoView; + inheritedProtoElementInjector:ProtoElementInjector; + inheritedElementBinder:ElementBinder; constructor(element:Element) { this.element = element; this._attrs = null; diff --git a/modules/core/src/compiler/pipeline/compile_pipeline.js b/modules/core/src/compiler/pipeline/compile_pipeline.js index 7d23f9ba23..bad8f809d8 100644 --- a/modules/core/src/compiler/pipeline/compile_pipeline.js +++ b/modules/core/src/compiler/pipeline/compile_pipeline.js @@ -10,6 +10,7 @@ import {AnnotatedType} from '../annotated_type'; * all elements in a template. */ export class CompilePipeline { + _control:CompileControl; constructor(steps:List) { this._control = new CompileControl(steps); } diff --git a/modules/core/src/compiler/pipeline/directive_parser.js b/modules/core/src/compiler/pipeline/directive_parser.js index 713b7a80eb..5ef67748c7 100644 --- a/modules/core/src/compiler/pipeline/directive_parser.js +++ b/modules/core/src/compiler/pipeline/directive_parser.js @@ -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) { this._selectorMatcher = new SelectorMatcher(); for (var i=0; i { + load(url:string):Promise { return null; } } \ No newline at end of file diff --git a/modules/core/src/compiler/view.js b/modules/core/src/compiler/view.js index 300acd649b..458fce22ab 100644 --- a/modules/core/src/compiler/view.js +++ b/modules/core/src/compiler/view.js @@ -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') - @FIELD('final elementInjectors:List') - @FIELD('final bindElements:List') - @FIELD('final textNodes:List') - @FIELD('final recordRange:RecordRange') + rootElementInjectors:List; + elementInjectors:List; + bindElements:List; + textNodes:List; + 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') - @FIELD('final onChangeDispatcher:OnChangeDispatcher') - @FIELD('childViews: List') + nodes:List; + onChangeDispatcher:OnChangeDispatcher; + childViews: List; constructor(nodes:List, 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') - @FIELD('final protoRecordRange:ProtoRecordRange') + element:Element; + elementBinders:List; + 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; diff --git a/modules/core/src/core.js b/modules/core/src/core.js index 8744601b82..cd741494fb 100644 --- a/modules/core/src/core.js +++ b/modules/core/src/core.js @@ -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'; diff --git a/modules/core/src/dom/element.js b/modules/core/src/dom/element.js index 2cb4c1ccc6..f135bcb281 100644 --- a/modules/core/src/dom/element.js +++ b/modules/core/src/dom/element.js @@ -1,4 +1,7 @@ +import {Element} from 'facade/dom'; + export class NgElement { + domElement:Element; constructor(domElement) { this.domElement = domElement; } diff --git a/modules/core/src/life_cycle/life_cycle.js b/modules/core/src/life_cycle/life_cycle.js index e0128438b6..fb6388c4c8 100644 --- a/modules/core/src/life_cycle/life_cycle.js +++ b/modules/core/src/life_cycle/life_cycle.js @@ -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(); } } \ No newline at end of file diff --git a/modules/core/test/application_spec.js b/modules/core/test/application_spec.js index dcb78e0e66..5d5f75a728 100644 --- a/modules/core/test/application_spec.js +++ b/modules/core/test/application_spec.js @@ -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'; } diff --git a/modules/core/test/compiler/compiler_spec.js b/modules/core/test/compiler/compiler_spec.js index 5043817c53..14af477b63 100644 --- a/modules/core/test/compiler/compiler_spec.js +++ b/modules/core/test/compiler/compiler_spec.js @@ -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) { 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; } diff --git a/modules/core/test/compiler/element_injector_spec.js b/modules/core/test/compiler/element_injector_spec.js index 08e1c50881..4a80c99f0d 100644 --- a/modules/core/test/compiler/element_injector_spec.js +++ b/modules/core/test/compiler/element_injector_spec.js @@ -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; } diff --git a/modules/core/test/compiler/integration_spec.js b/modules/core/test/compiler/integration_spec.js index 8041e55b9e..4fa35d0d8e 100644 --- a/modules/core/test/compiler/integration_spec.js +++ b/modules/core/test/compiler/integration_spec.js @@ -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'; } diff --git a/modules/core/test/compiler/pipeline/directive_parser_spec.js b/modules/core/test/compiler/pipeline/directive_parser_spec.js index 12ef7d891b..d04f127a89 100644 --- a/modules/core/test/compiler/pipeline/directive_parser_spec.js +++ b/modules/core/test/compiler/pipeline/directive_parser_spec.js @@ -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; } diff --git a/modules/core/test/compiler/pipeline/element_binder_builder_spec.js b/modules/core/test/compiler/pipeline/element_binder_builder_spec.js index 723a38b83c..f1971a545d 100644 --- a/modules/core/test/compiler/pipeline/element_binder_builder_spec.js +++ b/modules/core/test/compiler/pipeline/element_binder_builder_spec.js @@ -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; } diff --git a/modules/core/test/compiler/pipeline/element_binding_marker_spec.js b/modules/core/test/compiler/pipeline/element_binding_marker_spec.js index 94f8943112..440f715385 100644 --- a/modules/core/test/compiler/pipeline/element_binding_marker_spec.js +++ b/modules/core/test/compiler/pipeline/element_binding_marker_spec.js @@ -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; } diff --git a/modules/core/test/compiler/pipeline/pipeline_spec.js b/modules/core/test/compiler/pipeline/pipeline_spec.js index 15efa04b0c..26b0192ee4 100644 --- a/modules/core/test/compiler/pipeline/pipeline_spec.js +++ b/modules/core/test/compiler/pipeline/pipeline_spec.js @@ -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; } diff --git a/modules/core/test/compiler/pipeline/proto_element_injector_builder_spec.js b/modules/core/test/compiler/pipeline/proto_element_injector_builder_spec.js index 9b609436b6..04c050b7f7 100644 --- a/modules/core/test/compiler/pipeline/proto_element_injector_builder_spec.js +++ b/modules/core/test/compiler/pipeline/proto_element_injector_builder_spec.js @@ -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; } diff --git a/modules/core/test/compiler/pipeline/proto_view_builder_spec.js b/modules/core/test/compiler/pipeline/proto_view_builder_spec.js index 90bed242bd..13e46e195e 100644 --- a/modules/core/test/compiler/pipeline/proto_view_builder_spec.js +++ b/modules/core/test/compiler/pipeline/proto_view_builder_spec.js @@ -75,6 +75,7 @@ export function main() { } class MockStep extends CompileStep { + processClosure:Function; constructor(process) { this.processClosure = process; } diff --git a/modules/core/test/compiler/reflector_spec.js b/modules/core/test/compiler/reflector_spec.js index a7315bb177..93d38738d6 100644 --- a/modules/core/test/compiler/reflector_spec.js +++ b/modules/core/test/compiler/reflector_spec.js @@ -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({ diff --git a/modules/core/test/compiler/view_spec.js b/modules/core/test/compiler/view_spec.js index b43583d611..788f6c0415 100644 --- a/modules/core/test/compiler/view_spec.js +++ b/modules/core/test/compiler/view_spec.js @@ -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'; }; diff --git a/modules/di/src/annotations.js b/modules/di/src/annotations.js index d364307f1e..91d289b723 100644 --- a/modules/di/src/annotations.js +++ b/modules/di/src/annotations.js @@ -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; diff --git a/modules/di/src/binding.js b/modules/di/src/binding.js index 8261bd8696..85c003b79c 100644 --- a/modules/di/src/binding.js +++ b/modules/di/src/binding.js @@ -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; } diff --git a/modules/di/src/exceptions.js b/modules/di/src/exceptions.js index ff72a59776..8573b3aa21 100644 --- a/modules/di/src/exceptions.js +++ b/modules/di/src/exceptions.js @@ -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)}`; } diff --git a/modules/di/src/injector.js b/modules/di/src/injector.js index 3dba34e167..23aa6ae36d 100644 --- a/modules/di/src/injector.js +++ b/modules/di/src/injector.js @@ -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; } diff --git a/modules/di/src/key.js b/modules/di/src/key.js index 9e08abfdba..7ce42d17ae 100644 --- a/modules/di/src/key.js +++ b/modules/di/src/key.js @@ -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(); } diff --git a/modules/di/test/di/async_spec.js b/modules/di/test/di/async_spec.js index cdbdb1df30..8bdd4f1a93 100644 --- a/modules/di/test/di/async_spec.js +++ b/modules/di/test/di/async_spec.js @@ -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; } diff --git a/modules/di/test/di/injector_spec.js b/modules/di/test/di/injector_spec.js index ed9fe97fc8..6b49d82e68 100644 --- a/modules/di/test/di/injector_spec.js +++ b/modules/di/test/di/injector_spec.js @@ -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; } diff --git a/modules/di/test/di/key_spec.js b/modules/di/test/di/key_spec.js index 1b9c3ccffd..40137d7a15 100644 --- a/modules/di/test/di/key_spec.js +++ b/modules/di/test/di/key_spec.js @@ -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; diff --git a/modules/examples/src/hello_world/app.js b/modules/examples/src/hello_world/app.js index e16aadaef5..a4b1cce9f2 100644 --- a/modules/examples/src/hello_world/app.js +++ b/modules/examples/src/hello_world/app.js @@ -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'; } diff --git a/modules/facade/src/lang.dart b/modules/facade/src/lang.dart index 989c7fd9e2..1081250722 100644 --- a/modules/facade/src/lang.dart +++ b/modules/facade/src/lang.dart @@ -159,3 +159,6 @@ dynamic getMapKey(value) { return value.isNaN ? _NAN_KEY : value; } +normalizeBlank(obj) { + return isBlank(obj) ? null : obj; +} \ No newline at end of file diff --git a/modules/facade/src/lang.es6 b/modules/facade/src/lang.es6 index 552bffd571..7aa158b0e0 100644 --- a/modules/facade/src/lang.es6 +++ b/modules/facade/src/lang.es6 @@ -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; +} \ No newline at end of file diff --git a/modules/test_lib/test/test_lib_spec.js b/modules/test_lib/test/test_lib_spec.js index ef9870c4d2..0ae6f07f6c 100644 --- a/modules/test_lib/test/test_lib_spec.js +++ b/modules/test_lib/test/test_lib_spec.js @@ -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; } diff --git a/tools/transpiler/spec/annotations_spec.js b/tools/transpiler/spec/annotations_spec.js index 7209d4dd69..a69fa9c3ca 100644 --- a/tools/transpiler/spec/annotations_spec.js +++ b/tools/transpiler/spec/annotations_spec.js @@ -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; diff --git a/tools/transpiler/spec/arrow_functions_spec.js b/tools/transpiler/spec/arrow_functions_spec.js index d6f4437458..e984b06038 100644 --- a/tools/transpiler/spec/arrow_functions_spec.js +++ b/tools/transpiler/spec/arrow_functions_spec.js @@ -13,6 +13,8 @@ var max = (a, b) => { }; class LexicalThis { + zero; + constructor() { this.zero = 0; } diff --git a/tools/transpiler/spec/classes_spec.js b/tools/transpiler/spec/classes_spec.js index a9dcb1dd53..67c4d5d6f7 100644 --- a/tools/transpiler/spec/classes_spec.js +++ b/tools/transpiler/spec/classes_spec.js @@ -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); diff --git a/tools/transpiler/spec/functions_spec.js b/tools/transpiler/spec/functions_spec.js index 097142c4de..ef2f19f33c 100644 --- a/tools/transpiler/spec/functions_spec.js +++ b/tools/transpiler/spec/functions_spec.js @@ -5,6 +5,8 @@ function sum(a, b) { } class ConstructorWithNamedParams { + sum; + constructor(a, {b=1, c=2}) { this.sum = a + b + c; } diff --git a/tools/transpiler/spec/types_spec.js b/tools/transpiler/spec/types_spec.js index d936e65b38..478b0f385d 100644 --- a/tools/transpiler/spec/types_spec.js +++ b/tools/transpiler/spec/types_spec.js @@ -30,6 +30,9 @@ class Bar { } class Foo { + a; + b; + constructor(a: number, b: number) { this.a = a; this.b = b; diff --git a/tools/transpiler/src/codegeneration/ClassTransformer.js b/tools/transpiler/src/codegeneration/ClassTransformer.js index 0dd5fc7a3a..05f8a26c3c 100644 --- a/tools/transpiler/src/codegeneration/ClassTransformer.js +++ b/tools/transpiler/src/codegeneration/ClassTransformer.js @@ -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); } diff --git a/tools/transpiler/src/outputgeneration/DartParseTreeWriter.js b/tools/transpiler/src/outputgeneration/DartParseTreeWriter.js index 77b2371d44..55c3cb4f7e 100644 --- a/tools/transpiler/src/outputgeneration/DartParseTreeWriter.js +++ b/tools/transpiler/src/outputgeneration/DartParseTreeWriter.js @@ -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 name;` or `final name;` for untyped variable - this.write_('final'); - this.writeSpace_(); - this.writeType_(tree.typeAnnotation); - } else { - // ` 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) { diff --git a/tools/transpiler/src/syntax/trees/ParseTrees.js b/tools/transpiler/src/syntax/trees/ParseTrees.js index ff3e62b22c..6a991cbc63 100644 --- a/tools/transpiler/src/syntax/trees/ParseTrees.js +++ b/tools/transpiler/src/syntax/trees/ParseTrees.js @@ -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 { /**