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 bdddc5c519..e75ee18277 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 @@ -232,21 +232,11 @@ class _DirectiveMetadataVisitor extends Object for (var variable in node.fields.variables) { for (var meta in node.metadata) { if (_isAnnotation(meta, 'Output')) { - final renamed = _getRenamedValue(meta); - if (renamed != null) { - _outputs.add('${variable.name}: ${renamed}'); - } else { - _outputs.add('${variable.name}'); - } + _addPropertyToType(_outputs, variable.name.toString(), meta); } if (_isAnnotation(meta, 'Input')) { - final renamed = _getRenamedValue(meta); - if (renamed != null) { - _inputs.add('${variable.name}: ${renamed}'); - } else { - _inputs.add('${variable.name}'); - } + _addPropertyToType(_inputs, variable.name.toString(), meta); } if (_isAnnotation(meta, 'HostBinding')) { @@ -265,6 +255,14 @@ class _DirectiveMetadataVisitor extends Object @override Object visitMethodDeclaration(MethodDeclaration node) { for (var meta in node.metadata) { + if (_isAnnotation(meta, 'Output') && node.isGetter) { + _addPropertyToType(_outputs, node.name.toString(), meta); + } + + if (_isAnnotation(meta, 'Input') && node.isSetter) { + _addPropertyToType(_inputs, node.name.toString(), meta); + } + if (_isAnnotation(meta, 'HostListener')) { if (meta.arguments.arguments.length == 0 || meta.arguments.arguments.length > 2) { @@ -280,6 +278,15 @@ class _DirectiveMetadataVisitor extends Object return null; } + void _addPropertyToType(List type, String name, Annotation meta) { + final renamed = _getRenamedValue(meta); + if (renamed != null) { + type.add('${name}: ${renamed}'); + } else { + type.add('${name}'); + } + } + //TODO Use AnnotationMatcher instead of string matching bool _isAnnotation(Annotation node, String annotationName) { var id = node.name; diff --git a/modules_dart/transform/test/transform/directive_processor/all_tests.dart b/modules_dart/transform/test/transform/directive_processor/all_tests.dart index 3dcd45c830..3adae444b6 100644 --- a/modules_dart/transform/test/transform/directive_processor/all_tests.dart +++ b/modules_dart/transform/test/transform/directive_processor/all_tests.dart @@ -498,14 +498,14 @@ void allTests() { it('should merge `outputs` from the annotation and fields.', () async { var model = await _testCreateModel('directives_files/components.dart'); - expect(model.types['ComponentWithOutputs'].outputs) - .toEqual({'a': 'a', 'b': 'b', 'c': 'renamed'}); + expect(model.types['ComponentWithOutputs'].outputs).toEqual( + {'a': 'a', 'b': 'b', 'c': 'renamed', 'd': 'd', 'e': 'get-renamed'}); }); it('should merge `inputs` from the annotation and fields.', () async { var model = await _testCreateModel('directives_files/components.dart'); - expect(model.types['ComponentWithInputs'].inputs) - .toEqual({'a': 'a', 'b': 'b', 'c': 'renamed'}); + expect(model.types['ComponentWithInputs'].inputs).toEqual( + {'a': 'a', 'b': 'b', 'c': 'renamed', 'd': 'd', 'e': 'set-renamed'}); }); it('should merge host bindings from the annotation and fields.', () async { diff --git a/modules_dart/transform/test/transform/directive_processor/directives_files/components.dart b/modules_dart/transform/test/transform/directive_processor/directives_files/components.dart index beb545c825..31d27bd734 100644 --- a/modules_dart/transform/test/transform/directive_processor/directives_files/components.dart +++ b/modules_dart/transform/test/transform/directive_processor/directives_files/components.dart @@ -22,30 +22,41 @@ class ComponentOnly {} @Component( selector: 'component-with-outputs', template: '', - outputs: ['a'] -) + outputs: ['a']) class ComponentWithOutputs { @Output() Object b; @Output('renamed') Object c; + + Object _d; + @Output() Object get d => _d; + + Object _e; + @Output('get-renamed') Object get e => _e; } @Component( selector: 'component-with-inputs', template: '', - inputs: ['a'] -) + inputs: ['a']) class ComponentWithInputs { @Input() Object b; @Input('renamed') Object c; + + Object _d; + @Input() void set d(Object value) { + _d = value; + } + + Object _e; + @Input('set-renamed') void set e(Object value) { + _e = value; + } } @Component( selector: 'component-with-inputs', template: '', - host: { - '[a]':'a' - } -) + host: {'[a]': 'a'}) class ComponentWithHostBindings { @HostBinding() Object b; @HostBinding('renamed') Object c; @@ -54,11 +65,9 @@ class ComponentWithHostBindings { @Component( selector: 'component-with-inputs', template: '', - host: { - '(a)':'onA()' - } -) + host: {'(a)': 'onA()'}) class ComponentWithHostListeners { @HostListener('b') void onB() {} - @HostListener('c', ['\$event.target', '\$event.target.value']) void onC(t,v) {} + @HostListener('c', ['\$event.target', '\$event.target.value']) void onC( + t, v) {} }