From f19970a481ed57ec02fc098a427e0c874ce2962e Mon Sep 17 00:00:00 2001 From: vsavkin Date: Thu, 28 May 2015 17:28:53 -0700 Subject: [PATCH] feat(transformers): added support for lifecycle events --- modules/angular2/src/render/dom/convert.ts | 14 ++++++++-- .../common/directive_metadata_reader.dart | 28 ++++++++++++++++++- .../angular2/test/render/dom/convert_spec.ts | 24 ++++++++++++++-- .../all_tests.dart | 10 +++++++ .../lifecycle.ng_deps.dart | 19 +++++++++++++ .../expected/bar.ng_meta.json | 5 ++++ 6 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/lifecycle.ng_deps.dart diff --git a/modules/angular2/src/render/dom/convert.ts b/modules/angular2/src/render/dom/convert.ts index 80cf3a2c55..960274466a 100644 --- a/modules/angular2/src/render/dom/convert.ts +++ b/modules/angular2/src/render/dom/convert.ts @@ -18,7 +18,12 @@ export function directiveMetadataToMap(meta: DirectiveMetadata): Map): DirectiveMetada hostAttributes:>_cloneIfPresent(MapWrapper.get(map, 'hostAttributes')), properties:>_cloneIfPresent(MapWrapper.get(map, 'properties')), readAttributes:>_cloneIfPresent(MapWrapper.get(map, 'readAttributes')), - type:MapWrapper.get(map, 'type') + type:MapWrapper.get(map, 'type'), + callOnDestroy:MapWrapper.get(map, 'callOnDestroy'), + callOnCheck:MapWrapper.get(map, 'callOnCheck'), + callOnChange:MapWrapper.get(map, 'callOnChange'), + callOnInit:MapWrapper.get(map, 'callOnInit'), + callOnAllChangesDone:MapWrapper.get(map, 'callOnAllChangesDone') }); } diff --git a/modules/angular2/src/transform/common/directive_metadata_reader.dart b/modules/angular2/src/transform/common/directive_metadata_reader.dart index 6adcac4902..3ba0b2322c 100644 --- a/modules/angular2/src/transform/common/directive_metadata_reader.dart +++ b/modules/angular2/src/transform/common/directive_metadata_reader.dart @@ -60,7 +60,13 @@ class _DirectiveMetadataVisitor extends Object hostListeners: {}, hostProperties: {}, hostAttributes: {}, - readAttributes: []); + readAttributes: [], + callOnDestroy: false, + callOnChange: false, + callOnCheck: false, + callOnInit: false, + callOnAllChangesDone: false + ); } @override @@ -126,6 +132,10 @@ class _DirectiveMetadataVisitor extends Object break; case 'hostListeners': _populateHostListeners(node.expression); + break; + case 'lifecycle': + _populateLifecycle(node.expression); + break; } return null; } @@ -214,4 +224,20 @@ class _DirectiveMetadataVisitor extends Object _populateMap( hostAttributeValue, meta.hostAttributes, 'Directive#hostAttributes'); } + + void _populateLifecycle(Expression lifecycleValue) { + _checkMeta(); + if (lifecycleValue is! ListLiteral) { + throw new FormatException( + 'Angular 2 expects a List but could not understand the value for lifecycle. ' + '$lifecycleValue'); + } + ListLiteral l = lifecycleValue; + var lifecycleEvents = l.elements.map((s) => s.toSource()); + meta.callOnDestroy = lifecycleEvents.contains("onDestroy"); + meta.callOnChange = lifecycleEvents.contains("onChange"); + meta.callOnCheck = lifecycleEvents.contains("onCheck"); + meta.callOnInit = lifecycleEvents.contains("onInit"); + meta.callOnAllChangesDone = lifecycleEvents.contains("onAllChangesDone"); + } } diff --git a/modules/angular2/test/render/dom/convert_spec.ts b/modules/angular2/test/render/dom/convert_spec.ts index b810c2847a..71a479c19d 100644 --- a/modules/angular2/test/render/dom/convert_spec.ts +++ b/modules/angular2/test/render/dom/convert_spec.ts @@ -15,7 +15,12 @@ export function main() { properties: ['propKey: propVal'], readAttributes: ['read1', 'read2'], selector: 'some-comp', - type: DirectiveMetadata.COMPONENT_TYPE + type: DirectiveMetadata.COMPONENT_TYPE, + callOnDestroy: true, + callOnChange: true, + callOnCheck: true, + callOnInit: true, + callOnAllChangesDone: true }); var map = directiveMetadataToMap(someComponent); expect(MapWrapper.get(map, 'compileChildren')).toEqual(false); @@ -30,6 +35,11 @@ export function main() { expect(MapWrapper.get(map, 'readAttributes')).toEqual(['read1', 'read2']); expect(MapWrapper.get(map, 'selector')).toEqual('some-comp'); expect(MapWrapper.get(map, 'type')).toEqual(DirectiveMetadata.COMPONENT_TYPE); + expect(MapWrapper.get(map, 'callOnDestroy')).toEqual(true); + expect(MapWrapper.get(map, 'callOnCheck')).toEqual(true); + expect(MapWrapper.get(map, 'callOnChange')).toEqual(true); + expect(MapWrapper.get(map, 'callOnInit')).toEqual(true); + expect(MapWrapper.get(map, 'callOnAllChangesDone')).toEqual(true); }); it('mapToDirectiveMetadata', () => { @@ -42,7 +52,12 @@ export function main() { ['properties', ['propKey: propVal']], ['readAttributes', ['readTest1', 'readTest2']], ['selector', 'testSelector'], - ['type', DirectiveMetadata.DIRECTIVE_TYPE] + ['type', DirectiveMetadata.DIRECTIVE_TYPE], + ['callOnDestroy', true], + ['callOnCheck', true], + ['callOnInit', true], + ['callOnChange', true], + ['callOnAllChangesDone', true] ]); var meta = directiveMetadataFromMap(map); expect(meta.compileChildren).toEqual(false); @@ -56,6 +71,11 @@ export function main() { expect(meta.readAttributes).toEqual(['readTest1', 'readTest2']); expect(meta.selector).toEqual('testSelector'); expect(meta.type).toEqual(DirectiveMetadata.DIRECTIVE_TYPE); + expect(meta.callOnDestroy).toEqual(true); + expect(meta.callOnCheck).toEqual(true); + expect(meta.callOnInit).toEqual(true); + expect(meta.callOnChange).toEqual(true); + expect(meta.callOnAllChangesDone).toEqual(true); }); }); } diff --git a/modules/angular2/test/transform/directive_metadata_extractor/all_tests.dart b/modules/angular2/test/transform/directive_metadata_extractor/all_tests.dart index 79ff6c7c15..12137f69fd 100644 --- a/modules/angular2/test/transform/directive_metadata_extractor/all_tests.dart +++ b/modules/angular2/test/transform/directive_metadata_extractor/all_tests.dart @@ -78,6 +78,16 @@ void allTests() { expect(metadata.hostListeners['keyDown']).toEqual('onKeyDown(\$event)'); }); + it('should parse lifecycle events.', () async { + var metadata = await readMetadata('directive_metadata_extractor/' + 'directive_metadata_files/lifecycle.ng_deps.dart'); + expect(metadata.callOnDestroy).toBe(true); + expect(metadata.callOnChange).toBe(true); + expect(metadata.callOnCheck).toBe(true); + expect(metadata.callOnInit).toBe(true); + expect(metadata.callOnAllChangesDone).toBe(true); + }); + it('should fail when a class is annotated with multiple Directives.', () async { var ngDeps = await parser.parse(new AssetId('a', diff --git a/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/lifecycle.ng_deps.dart b/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/lifecycle.ng_deps.dart new file mode 100644 index 0000000000..91165f53e7 --- /dev/null +++ b/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/lifecycle.ng_deps.dart @@ -0,0 +1,19 @@ +library examples.hello_world.index_common_dart.ng_deps.dart; + +import 'hello.dart'; +import 'package:angular2/angular2.dart' + show bootstrap, Component, Directive, View, NgElement, onChange, onDestroy, onInit, onCheck, onAllChangesDone; + +var _visited = false; +void initReflector(reflector) { + if (_visited) return; + _visited = true; + reflector + ..registerType(HelloCmp, { + 'factory': () => new HelloCmp(), + 'parameters': const [const []], + 'annotations': const [ + const Component(lifecycle: [onChange, onDestroy, onInit, onCheck, onAllChangesDone]) + ] + }); +} diff --git a/modules/angular2/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json b/modules/angular2/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json index 1d2415ab77..23e312aaf1 100644 --- a/modules/angular2/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json +++ b/modules/angular2/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json @@ -10,6 +10,11 @@ "properties": [], "readAttributes": [], "type": 1, + "callOnDestroy": false, + "callOnCheck": false, + "callOnInit": false, + "callOnChange": false, + "callOnAllChangesDone": false, "version": 1 } } \ No newline at end of file