From c9901c5fe0e5464fa8671789cf7ec90c45109362 Mon Sep 17 00:00:00 2001 From: vsavkin Date: Fri, 2 Oct 2015 16:21:49 -0700 Subject: [PATCH] feat(core): support properties and events in addition to inputs and outputs to make transition easier Closes #4482 --- .../src/core/linker/directive_resolver.ts | 6 +++- modules/angular2/src/core/metadata.dart | 14 +++++++-- modules/angular2/src/core/metadata.ts | 8 +++++ .../angular2/src/core/metadata/directives.ts | 30 +++++++++++++++++-- .../core/linker/directive_resolver_spec.ts | 24 +++++++++++++-- modules/angular2/test/public_api_spec.ts | 8 +++++ .../common/directive_metadata_reader.dart | 6 ++++ tools/build/dartanalyzer.js | 5 ++++ 8 files changed, 93 insertions(+), 8 deletions(-) diff --git a/modules/angular2/src/core/linker/directive_resolver.ts b/modules/angular2/src/core/linker/directive_resolver.ts index f9344bf715..10897a8539 100644 --- a/modules/angular2/src/core/linker/directive_resolver.ts +++ b/modules/angular2/src/core/linker/directive_resolver.ts @@ -1,5 +1,5 @@ import {resolveForwardRef, Injectable} from 'angular2/src/core/di'; -import {Type, isPresent, stringify} from 'angular2/src/core/facade/lang'; +import {Type, isPresent, isBlank, stringify} from 'angular2/src/core/facade/lang'; import {BaseException} from 'angular2/src/core/facade/exceptions'; import {ListWrapper, StringMap, StringMapWrapper} from 'angular2/src/core/facade/collection'; import { @@ -110,6 +110,10 @@ export class DirectiveResolver { var mergedQueries = isPresent(dm.queries) ? StringMapWrapper.merge(dm.queries, queries) : queries; + // TODO: remove after migrating from properties to inputs + if (mergedInputs.length == 0 && isPresent(dm.properties)) mergedInputs = dm.properties; + if (mergedOutputs.length == 0 && isPresent(dm.events)) mergedOutputs = dm.events; + if (dm instanceof ComponentMetadata) { return new ComponentMetadata({ selector: dm.selector, diff --git a/modules/angular2/src/core/metadata.dart b/modules/angular2/src/core/metadata.dart index 8b2e0e3d14..890f9a14a5 100644 --- a/modules/angular2/src/core/metadata.dart +++ b/modules/angular2/src/core/metadata.dart @@ -15,13 +15,18 @@ export './metadata/view.dart'; */ class Directive extends DirectiveMetadata { const Directive({String selector, List inputs, - List outputs, Map host, + List outputs, + @deprecated List properties, + @deprecated List events, + Map host, List bindings, String exportAs, String moduleId, Map queries}) : super( selector: selector, inputs: inputs, outputs: outputs, + properties: properties, + events: events, host: host, bindings: bindings, exportAs: exportAs, @@ -34,7 +39,10 @@ class Directive extends DirectiveMetadata { */ class Component extends ComponentMetadata { const Component({String selector, List inputs, - List outputs, Map host, + List outputs, + @deprecated List properties, + @deprecated List events, + Map host, List bindings, String exportAs, String moduleId, Map queries, List viewBindings, ChangeDetectionStrategy changeDetection}) @@ -42,6 +50,8 @@ class Component extends ComponentMetadata { selector: selector, inputs: inputs, outputs: outputs, + properties: properties, + events: events, host: host, bindings: bindings, exportAs: exportAs, diff --git a/modules/angular2/src/core/metadata.ts b/modules/angular2/src/core/metadata.ts index d7f3847ca6..4b45e02969 100644 --- a/modules/angular2/src/core/metadata.ts +++ b/modules/angular2/src/core/metadata.ts @@ -149,6 +149,8 @@ export interface DirectiveFactory { selector?: string, inputs?: string[], outputs?: string[], + properties?: string[], + events?: string[], host?: StringMap, bindings?: any[], exportAs?: string, @@ -159,6 +161,8 @@ export interface DirectiveFactory { selector?: string, inputs?: string[], outputs?: string[], + properties?: string[], + events?: string[], host?: StringMap, bindings?: any[], exportAs?: string, @@ -215,6 +219,8 @@ export interface ComponentFactory { selector?: string, inputs?: string[], outputs?: string[], + properties?: string[], + events?: string[], host?: StringMap, bindings?: any[], exportAs?: string, @@ -227,6 +233,8 @@ export interface ComponentFactory { selector?: string, inputs?: string[], outputs?: string[], + properties?: string[], + events?: string[], host?: StringMap, bindings?: any[], exportAs?: string, diff --git a/modules/angular2/src/core/metadata/directives.ts b/modules/angular2/src/core/metadata/directives.ts index a8e1b12a03..c693f93a5f 100644 --- a/modules/angular2/src/core/metadata/directives.ts +++ b/modules/angular2/src/core/metadata/directives.ts @@ -467,6 +467,12 @@ export class DirectiveMetadata extends InjectableMetadata { */ inputs: string[]; + /** + * @deprecated + * Same as `inputs`. This is to enable easier migration. + */ + properties: string[]; + /** * Enumerates the set of event-bound output properties. * @@ -514,6 +520,12 @@ export class DirectiveMetadata extends InjectableMetadata { */ outputs: string[]; + /** + * @deprecated + * Same as `outputs`. This is to enable easier migration. + */ + events: string[]; + /** * Specify the events, actions, properties and attributes related to the host element. * @@ -738,10 +750,13 @@ export class DirectiveMetadata extends InjectableMetadata { */ queries: StringMap; - constructor({selector, inputs, outputs, host, bindings, exportAs, moduleId, queries}: { + constructor({selector, inputs, outputs, properties, events, host, bindings, exportAs, moduleId, + queries}: { selector?: string, inputs?: string[], outputs?: string[], + properties?: string[], + events?: string[], host?: StringMap, bindings?: any[], exportAs?: string, @@ -753,6 +768,11 @@ export class DirectiveMetadata extends InjectableMetadata { this.inputs = inputs; this.outputs = outputs; this.host = host; + + // TODO: remove this once properties and events are removed. + this.properties = properties; + this.events = events; + this.exportAs = exportAs; this.moduleId = moduleId; this.queries = queries; @@ -856,11 +876,13 @@ export class ComponentMetadata extends DirectiveMetadata { */ viewBindings: any[]; - constructor({selector, inputs, outputs, host, exportAs, moduleId, bindings, viewBindings, - changeDetection = ChangeDetectionStrategy.Default, queries}: { + constructor({selector, inputs, outputs, properties, events, host, exportAs, moduleId, bindings, + viewBindings, changeDetection = ChangeDetectionStrategy.Default, queries}: { selector?: string, inputs?: string[], outputs?: string[], + properties?: string[], + events?: string[], host?: StringMap, bindings?: any[], exportAs?: string, @@ -873,6 +895,8 @@ export class ComponentMetadata extends DirectiveMetadata { selector: selector, inputs: inputs, outputs: outputs, + properties: properties, + events: events, host: host, exportAs: exportAs, moduleId: moduleId, diff --git a/modules/angular2/test/core/linker/directive_resolver_spec.ts b/modules/angular2/test/core/linker/directive_resolver_spec.ts index d77abb9136..c758f397f8 100644 --- a/modules/angular2/test/core/linker/directive_resolver_spec.ts +++ b/modules/angular2/test/core/linker/directive_resolver_spec.ts @@ -26,7 +26,7 @@ class SomeChildDirective extends SomeDirective { } @Directive({selector: 'someDirective', inputs: ['c']}) -class SomeDirectiveWithProperties { +class SomeDirectiveWithInputs { @Input() a; @Input("renamed") b; c; @@ -39,6 +39,15 @@ class SomeDirectiveWithOutputs { c; } +@Directive({selector: 'someDirective', properties: ['a']}) +class SomeDirectiveWithProperties { +} + +@Directive({selector: 'someDirective', events: ['a']}) +class SomeDirectiveWithEvents { +} + + @Directive({selector: 'someDirective'}) class SomeDirectiveWithSetterProps { @@ -125,7 +134,7 @@ export function main() { describe('inputs', () => { it('should append directive inputs', () => { - var directiveMetadata = resolver.resolve(SomeDirectiveWithProperties); + var directiveMetadata = resolver.resolve(SomeDirectiveWithInputs); expect(directiveMetadata.inputs).toEqual(['c', 'a', 'b: renamed']); }); @@ -133,6 +142,12 @@ export function main() { var directiveMetadata = resolver.resolve(SomeDirectiveWithSetterProps); expect(directiveMetadata.inputs).toEqual(['a: renamed']); }); + + it('should use properties as inputs', () => { + var directiveMetadata = resolver.resolve(SomeDirectiveWithProperties); + expect(directiveMetadata.inputs).toEqual(['a']); + }); + }); describe('outputs', () => { @@ -145,6 +160,11 @@ export function main() { var directiveMetadata = resolver.resolve(SomeDirectiveWithGetterOutputs); expect(directiveMetadata.outputs).toEqual(['a: renamed']); }); + + it('should use events as outputs', () => { + var directiveMetadata = resolver.resolve(SomeDirectiveWithEvents); + expect(directiveMetadata.outputs).toEqual(['a']); + }); }); describe('host', () => { diff --git a/modules/angular2/test/public_api_spec.ts b/modules/angular2/test/public_api_spec.ts index a500ce0cb2..64f3ae3b02 100644 --- a/modules/angular2/test/public_api_spec.ts +++ b/modules/angular2/test/public_api_spec.ts @@ -157,10 +157,12 @@ var NG_API = [ 'Component.bindings', 'Component.changeDetection', 'Component.outputs', + 'Component.events', 'Component.exportAs', 'Component.host', 'Component.moduleId', 'Component.inputs', + 'Component.properties', 'Component.queries', 'Component.selector', 'Component.viewBindings', @@ -168,10 +170,12 @@ var NG_API = [ 'ComponentMetadata.bindings', 'ComponentMetadata.changeDetection', 'ComponentMetadata.outputs', + 'ComponentMetadata.events', 'ComponentMetadata.exportAs', 'ComponentMetadata.host', 'ComponentMetadata.moduleId', 'ComponentMetadata.inputs', + 'ComponentMetadata.properties', 'ComponentMetadata.queries', 'ComponentMetadata.selector', 'ComponentMetadata.viewBindings', @@ -370,19 +374,23 @@ var NG_API = [ 'Directive', 'Directive.bindings', 'Directive.outputs', + 'Directive.events', 'Directive.exportAs', 'Directive.host', 'Directive.moduleId', 'Directive.inputs', + 'Directive.properties', 'Directive.queries', 'Directive.selector', 'DirectiveMetadata', 'DirectiveMetadata.bindings', 'DirectiveMetadata.outputs', + 'DirectiveMetadata.events', 'DirectiveMetadata.exportAs', 'DirectiveMetadata.host', 'DirectiveMetadata.moduleId', 'DirectiveMetadata.inputs', + 'DirectiveMetadata.properties', 'DirectiveMetadata.queries', 'DirectiveMetadata.selector', 'DirectiveResolver', diff --git a/modules_dart/transform/lib/src/transform/common/directive_metadata_reader.dart b/modules_dart/transform/lib/src/transform/common/directive_metadata_reader.dart index 209091e575..305754de50 100644 --- a/modules_dart/transform/lib/src/transform/common/directive_metadata_reader.dart +++ b/modules_dart/transform/lib/src/transform/common/directive_metadata_reader.dart @@ -235,6 +235,9 @@ class _DirectiveMetadataVisitor extends Object case 'inputs': _populateProperties(node.expression); break; + case 'properties': + _populateProperties(node.expression); + break; case 'host': _populateHost(node.expression); break; @@ -247,6 +250,9 @@ class _DirectiveMetadataVisitor extends Object case 'outputs': _populateEvents(node.expression); break; + case 'events': + _populateEvents(node.expression); + break; } return null; } diff --git a/tools/build/dartanalyzer.js b/tools/build/dartanalyzer.js index 5c1f68ab68..8bbb4c6496 100644 --- a/tools/build/dartanalyzer.js +++ b/tools/build/dartanalyzer.js @@ -175,6 +175,11 @@ _AnalyzerOutputLine.prototype = { return true; } } + + if (this.errorCode.match(/DEPRECATED_MEMBER_USE/i)) { + return true; + } + // TODO: https://github.com/angular/ts2dart/issues/168 if (this.errorCode.match(/UNUSED_CATCH_STACK/i)) { return true;