fix(transformers): Fix @Input/@Output annotations with setters/getters

Fix @Input annotations to work with setter methods in dart, and fix @Output
annotations to work with getter methods in Dart when using transformers.

Closes #5251

Closes #5259
This commit is contained in:
Ted Sander 2015-11-12 12:34:32 -08:00
parent 7f6289c1bf
commit d9f362a713
3 changed files with 45 additions and 29 deletions

View File

@ -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;

View File

@ -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 {

View File

@ -22,30 +22,41 @@ class ComponentOnly {}
@Component(
selector: 'component-with-outputs',
template: '<dep1></dep1><dep2></dep2>',
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: '<dep1></dep1><dep2></dep2>',
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: '<dep1></dep1><dep2></dep2>',
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: '<dep1></dep1><dep2></dep2>',
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) {}
}