feat(dart/transform): Record Type interfaces

To support interface-based lifecycle methods (#2220), we need to be able
to query for the `interface`s a class supports. Record implemented
interfaces to allow mirror-less querying at runtime.

Closes #2204
This commit is contained in:
Tim Blasi 2015-06-03 14:22:24 -07:00
parent e5419febe4
commit dc6e7eb19b
10 changed files with 110 additions and 4 deletions

View File

@ -66,8 +66,7 @@ class _DirectiveMetadataVisitor extends Object
callOnChange: false,
callOnCheck: false,
callOnInit: false,
callOnAllChangesDone: false
);
callOnAllChangesDone: false);
}
@override

View File

@ -192,6 +192,15 @@ class CreateNgDepsVisitor extends Object with SimpleAstVisitor<Object> {
}
writer.print(''', 'annotations': ''');
node.accept(_metaVisitor);
if (node.implementsClause != null &&
node.implementsClause.interfaces != null &&
node.implementsClause.interfaces.isNotEmpty) {
writer.print(''', 'interfaces': const [''');
node.implementsClause.interfaces.forEach((interface) {
writer.print('${interface.name}');
});
writer.print(']');
}
writer.print('})');
return null;
}

View File

@ -2,7 +2,17 @@ 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;
show
bootstrap,
Component,
Directive,
View,
NgElement,
onChange,
onDestroy,
onInit,
onCheck,
onAllChangesDone;
var _visited = false;
void initReflector(reflector) {
@ -13,7 +23,8 @@ void initReflector(reflector) {
'factory': () => new HelloCmp(),
'parameters': const [const []],
'annotations': const [
const Component(lifecycle: [onChange, onDestroy, onInit, onCheck, onAllChangesDone])
const Component(
lifecycle: [onChange, onDestroy, onInit, onCheck, onAllChangesDone])
]
});
}

View File

@ -42,6 +42,15 @@ void allTests() {
_testNgDeps('should inline `templateUrl`s expressed as adjacent strings.',
'split_url_expression_files/hello.dart');
_testNgDeps('should report implemented types as `interfaces`.',
'interfaces_files/soup.dart');
_testNgDeps('should not include transitively implemented types.',
'interface_chain_files/soup.dart');
_testNgDeps('should not include superclasses in `interfaces`.',
'superclass_files/soup.dart');
}
void _testNgDeps(String name, String inputPath,

View File

@ -0,0 +1,17 @@
library dinner.soup.ng_deps.dart;
import 'soup.dart';
import 'package:angular2/src/core/annotations_impl/annotations.dart';
var _visited = false;
void initReflector(reflector) {
if (_visited) return;
_visited = true;
reflector
..registerType(ChangingSoupComponent, {
'factory': () => new ChangingSoupComponent(),
'parameters': const [],
'annotations': const [const Component(selector: '[soup]')],
'interfaces': const [PrimaryInterface]
});
}

View File

@ -0,0 +1,12 @@
library dinner.soup;
import 'package:angular2/src/core/annotations_impl/annotations.dart';
@Component(selector: '[soup]')
class ChangingSoupComponent implements PrimaryInterface {}
class TernaryInterface {}
class SecondaryInterface implements TernaryInterface {}
class PrimaryInterface implements SecondaryInterface {}

View File

@ -0,0 +1,17 @@
library dinner.soup.ng_deps.dart;
import 'soup.dart';
import 'package:angular2/src/core/annotations_impl/annotations.dart';
var _visited = false;
void initReflector(reflector) {
if (_visited) return;
_visited = true;
reflector
..registerType(ChangingSoupComponent, {
'factory': () => new ChangingSoupComponent(),
'parameters': const [],
'annotations': const [const Component(selector: '[soup]')],
'interfaces': const [OnChange]
});
}

View File

@ -0,0 +1,6 @@
library dinner.soup;
import 'package:angular2/src/core/annotations_impl/annotations.dart';
@Component(selector: '[soup]')
class ChangingSoupComponent implements OnChange {}

View File

@ -0,0 +1,16 @@
library dinner.soup.ng_deps.dart;
import 'soup.dart';
import 'package:angular2/src/core/annotations_impl/annotations.dart';
var _visited = false;
void initReflector(reflector) {
if (_visited) return;
_visited = true;
reflector
..registerType(ChangingSoupComponent, {
'factory': () => new ChangingSoupComponent(),
'parameters': const [],
'annotations': const [const Component(selector: '[soup]')]
});
}

View File

@ -0,0 +1,10 @@
library dinner.soup;
import 'package:angular2/src/core/annotations_impl/annotations.dart';
@Component(selector: '[soup]')
class ChangingSoupComponent extends Super {}
class Iface {}
class Super implements Iface {}