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, callOnChange: false,
callOnCheck: false, callOnCheck: false,
callOnInit: false, callOnInit: false,
callOnAllChangesDone: false callOnAllChangesDone: false);
);
} }
@override @override

View File

@ -192,6 +192,15 @@ class CreateNgDepsVisitor extends Object with SimpleAstVisitor<Object> {
} }
writer.print(''', 'annotations': '''); writer.print(''', 'annotations': ''');
node.accept(_metaVisitor); 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('})'); writer.print('})');
return null; return null;
} }

View File

@ -2,7 +2,17 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
import 'hello.dart'; import 'hello.dart';
import 'package:angular2/angular2.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; var _visited = false;
void initReflector(reflector) { void initReflector(reflector) {
@ -13,7 +23,8 @@ void initReflector(reflector) {
'factory': () => new HelloCmp(), 'factory': () => new HelloCmp(),
'parameters': const [const []], 'parameters': const [const []],
'annotations': 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.', _testNgDeps('should inline `templateUrl`s expressed as adjacent strings.',
'split_url_expression_files/hello.dart'); '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, 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 {}