feat(dart/transform): Use the render Compiler and the DirectiveParser
Update the `TemplateCompile` step to use the full render `Compiler`. Provide `DirectiveMetadata` for `ViewDefinition` objects and use it to run the `DirectiveParser` step of the render compile pipeline.
This commit is contained in:
parent
401c9efad7
commit
44f829dbc6
|
@ -83,7 +83,16 @@ class Html5LibDomAdapter implements DomAdapter {
|
|||
throw 'not implemented';
|
||||
}
|
||||
String nodeName(node) {
|
||||
throw 'not implemented';
|
||||
switch (node.nodeType) {
|
||||
case Node.ELEMENT_NODE:
|
||||
return (node as Element).localName;
|
||||
case Node.TEXT_NODE:
|
||||
return '#text';
|
||||
default:
|
||||
throw 'not implemented for type ${node.nodeType}. '
|
||||
'See http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1950641247'
|
||||
' for node types definitions.';
|
||||
}
|
||||
}
|
||||
String nodeValue(node) => node.data;
|
||||
String type(node) {
|
||||
|
@ -179,9 +188,8 @@ class Html5LibDomAdapter implements DomAdapter {
|
|||
getElementsByTagName(element, String name) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
List classList(element) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
List classList(element) => element.classes.toList();
|
||||
|
||||
addClass(element, String classname) {
|
||||
element.classes.add(classname);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ import 'parser.dart';
|
|||
DirectiveMetadata readDirectiveMetadata(RegisteredType t) {
|
||||
var visitor = new _DirectiveMetadataVisitor();
|
||||
t.annotations.accept(visitor);
|
||||
if (visitor.meta != null) {
|
||||
visitor.meta.id = '${t.typeName}';
|
||||
}
|
||||
return visitor.meta;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ class NgDeps {
|
|||
final List<ImportDirective> imports = [];
|
||||
final List<ExportDirective> exports = [];
|
||||
final List<RegisteredType> registeredTypes = [];
|
||||
FunctionDeclaration setupMethod;
|
||||
LibraryDirective lib = null;
|
||||
FunctionDeclaration setupMethod = null;
|
||||
|
||||
NgDeps(this.code);
|
||||
}
|
||||
|
@ -76,6 +77,12 @@ class NgDeps {
|
|||
class _ParseNgDepsVisitor extends Object with RecursiveAstVisitor<Object> {
|
||||
NgDeps ngDeps = null;
|
||||
|
||||
@override
|
||||
Object visitLibraryDirective(LibraryDirective node) {
|
||||
ngDeps.lib = node;
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Object visitImportDirective(ImportDirective node) {
|
||||
ngDeps.imports.add(node);
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:angular2/src/render/api.dart';
|
|||
import 'package:angular2/src/render/dom/compiler/compile_step.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/compile_step_factory.dart'
|
||||
as base;
|
||||
import 'package:angular2/src/render/dom/compiler/directive_parser.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/property_binding_parser.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/text_interpolation_parser.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/view_splitter.dart';
|
||||
|
@ -20,6 +21,7 @@ class CompileStepFactory implements base.CompileStepFactory {
|
|||
return [
|
||||
new ViewSplitter(_parser),
|
||||
new PropertyBindingParser(_parser),
|
||||
new DirectiveParser(_parser, template.directives),
|
||||
new TextInterpolationParser(_parser)
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2,24 +2,22 @@ library angular2.transform.template_compiler.generator;
|
|||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:angular2/src/change_detection/parser/lexer.dart' as ng;
|
||||
import 'package:angular2/src/change_detection/parser/parser.dart' as ng;
|
||||
import 'package:angular2/src/render/api.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/compile_pipeline.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/compiler.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/template_loader.dart';
|
||||
import "package:angular2/src/services/xhr.dart" show XHR;
|
||||
import 'package:angular2/src/reflection/reflection.dart';
|
||||
import 'package:angular2/src/services/url_resolver.dart';
|
||||
import 'package:angular2/src/transform/common/asset_reader.dart';
|
||||
import 'package:angular2/src/transform/common/logging.dart';
|
||||
import 'package:angular2/src/transform/common/names.dart';
|
||||
import 'package:angular2/src/transform/common/parser.dart';
|
||||
import 'package:angular2/src/transform/common/property_utils.dart' as prop;
|
||||
import 'package:barback/barback.dart';
|
||||
|
||||
import 'compile_step_factory.dart';
|
||||
import 'recording_reflection_capabilities.dart';
|
||||
import 'view_definition_creator.dart';
|
||||
import 'xhr_impl.dart';
|
||||
|
||||
/// Reads the `.ng_deps.dart` file represented by `entryPoint` and parses any
|
||||
|
@ -28,42 +26,40 @@ import 'xhr_impl.dart';
|
|||
///
|
||||
/// This method assumes a {@link DomAdapter} has been registered.
|
||||
Future<String> processTemplates(AssetReader reader, AssetId entryPoint) async {
|
||||
var parser = new Parser(reader);
|
||||
NgDeps ngDeps = await parser.parse(entryPoint);
|
||||
var viewDefResults = await createViewDefinitions(reader, entryPoint);
|
||||
var extractor = new _TemplateExtractor(new XhrImpl(reader, entryPoint));
|
||||
|
||||
var registrations = new StringBuffer();
|
||||
for (var rType in ngDeps.registeredTypes) {
|
||||
var values = await extractor.extractTemplates(rType);
|
||||
for (var viewDef in viewDefResults.viewDefinitions.values) {
|
||||
var values = await extractor.extractTemplates(viewDef);
|
||||
if (values == null) continue;
|
||||
var calls = _generateGetters('${rType.typeName}', values.getterNames);
|
||||
var calls = _generateGetters(values.getterNames);
|
||||
if (calls.isNotEmpty) {
|
||||
registrations.write('..${REGISTER_GETTERS_METHOD_NAME}'
|
||||
'({${calls.join(', ')}})');
|
||||
}
|
||||
calls = _generateSetters('${rType.typeName}', values.setterNames);
|
||||
calls = _generateSetters(values.setterNames);
|
||||
if (calls.isNotEmpty) {
|
||||
registrations.write('..${REGISTER_SETTERS_METHOD_NAME}'
|
||||
'({${calls.join(', ')}})');
|
||||
}
|
||||
calls = _generateMethods('${rType.typeName}', values.methodNames);
|
||||
calls = _generateMethods(values.methodNames);
|
||||
if (calls.isNotEmpty) {
|
||||
registrations.write('..${REGISTER_METHODS_METHOD_NAME}'
|
||||
'({${calls.join(', ')}})');
|
||||
}
|
||||
}
|
||||
|
||||
var code = ngDeps.code;
|
||||
var code = viewDefResults.ngDeps.code;
|
||||
if (registrations.length == 0) return code;
|
||||
var codeInjectIdx = ngDeps.registeredTypes.last.registerMethod.end;
|
||||
var codeInjectIdx =
|
||||
viewDefResults.ngDeps.registeredTypes.last.registerMethod.end;
|
||||
return '${code.substring(0, codeInjectIdx)}'
|
||||
'${registrations}'
|
||||
'${code.substring(codeInjectIdx)}';
|
||||
}
|
||||
|
||||
Iterable<String> _generateGetters(
|
||||
String typeName, Iterable<String> getterNames) {
|
||||
// TODO(kegluneq): Include `typeName` where possible.
|
||||
Iterable<String> _generateGetters(Iterable<String> getterNames) {
|
||||
return getterNames.map((getterName) {
|
||||
if (!prop.isValid(getterName)) {
|
||||
// TODO(kegluenq): Eagerly throw here once #1295 is addressed.
|
||||
|
@ -74,8 +70,7 @@ Iterable<String> _generateGetters(
|
|||
});
|
||||
}
|
||||
|
||||
Iterable<String> _generateSetters(
|
||||
String typeName, Iterable<String> setterName) {
|
||||
Iterable<String> _generateSetters(Iterable<String> setterName) {
|
||||
return setterName.map((setterName) {
|
||||
if (!prop.isValid(setterName)) {
|
||||
// TODO(kegluenq): Eagerly throw here once #1295 is addressed.
|
||||
|
@ -87,8 +82,7 @@ Iterable<String> _generateSetters(
|
|||
});
|
||||
}
|
||||
|
||||
Iterable<String> _generateMethods(
|
||||
String typeName, Iterable<String> methodNames) {
|
||||
Iterable<String> _generateMethods(Iterable<String> methodNames) {
|
||||
return methodNames.map((methodName) {
|
||||
if (!prop.isValid(methodName)) {
|
||||
// TODO(kegluenq): Eagerly throw here once #1295 is addressed.
|
||||
|
@ -104,85 +98,25 @@ Iterable<String> _generateMethods(
|
|||
/// template code if necessary, and determines what values will be
|
||||
/// reflectively accessed from that template.
|
||||
class _TemplateExtractor {
|
||||
final CompileStepFactory _factory;
|
||||
final _TemplateExtractVisitor _visitor = new _TemplateExtractVisitor();
|
||||
final TemplateLoader _loader;
|
||||
final RenderCompiler _compiler;
|
||||
|
||||
_TemplateExtractor(XHR xhr)
|
||||
: _loader = new TemplateLoader(xhr, new UrlResolver()),
|
||||
_factory = new CompileStepFactory(new ng.Parser(new ng.Lexer()));
|
||||
_TemplateExtractor(XHR xhr) : _compiler = new DomCompiler(
|
||||
new CompileStepFactory(new ng.Parser(new ng.Lexer())),
|
||||
new TemplateLoader(xhr, new UrlResolver()));
|
||||
|
||||
Future<RecordingReflectionCapabilities> extractTemplates(RegisteredType t) {
|
||||
return _processTemplate(_processRegisteredType(t));
|
||||
}
|
||||
|
||||
Future<RecordingReflectionCapabilities> _processTemplate(
|
||||
Future<RecordingReflectionCapabilities> extractTemplates(
|
||||
ViewDefinition viewDef) async {
|
||||
// Check for "imperative views".
|
||||
if (viewDef.template == null && viewDef.absUrl == null) return null;
|
||||
|
||||
var recordingCapabilities = new RecordingReflectionCapabilities();
|
||||
var savedReflectionCapabilities = reflector.reflectionCapabilities;
|
||||
var recordingCapabilities = new RecordingReflectionCapabilities();
|
||||
reflector.reflectionCapabilities = recordingCapabilities;
|
||||
|
||||
// TODO(kegluneq): Rewrite url to inline `template` where possible.
|
||||
// See [https://github.com/angular/angular/issues/1035].
|
||||
var domNode = await _loader.load(viewDef);
|
||||
|
||||
new CompilePipeline(_factory.createSteps(viewDef, [])).process(
|
||||
domNode, '$domNode');
|
||||
await _compiler.compile(viewDef);
|
||||
|
||||
reflector.reflectionCapabilities = savedReflectionCapabilities;
|
||||
return recordingCapabilities;
|
||||
}
|
||||
|
||||
ViewDefinition _processRegisteredType(RegisteredType t) {
|
||||
_visitor.reset();
|
||||
t.annotations.accept(_visitor);
|
||||
return _visitor.viewDef;
|
||||
}
|
||||
}
|
||||
|
||||
/// Visitor responsible for processing the `annotations` property of a
|
||||
/// {@link RegisterType} object and pulling out template information.
|
||||
class _TemplateExtractVisitor extends Object with RecursiveAstVisitor<Object> {
|
||||
ViewDefinition viewDef = new ViewDefinition();
|
||||
|
||||
void reset() {
|
||||
viewDef = new ViewDefinition();
|
||||
}
|
||||
|
||||
@override
|
||||
Object visitNamedExpression(NamedExpression node) {
|
||||
// TODO(kegluneq): Remove this limitation.
|
||||
if (node.name is! Label || node.name.label is! SimpleIdentifier) {
|
||||
logger.error(
|
||||
'Angular 2 currently only supports simple identifiers in directives.'
|
||||
' Source: ${node}');
|
||||
return null;
|
||||
}
|
||||
var keyString = '${node.name.label}';
|
||||
if (keyString == 'template' || keyString == 'templateUrl') {
|
||||
if (node.expression is! SimpleStringLiteral) {
|
||||
logger.error(
|
||||
'Angular 2 currently only supports string literals in directives.'
|
||||
' Source: ${node}');
|
||||
return null;
|
||||
}
|
||||
var valueString = stringLiteralToString(node.expression);
|
||||
if (keyString == 'templateUrl') {
|
||||
if (viewDef.absUrl != null) {
|
||||
logger.error(
|
||||
'Found multiple values for "templateUrl". Source: ${node}');
|
||||
}
|
||||
viewDef.absUrl = valueString;
|
||||
} else {
|
||||
if (viewDef.template != null) {
|
||||
logger.error('Found multiple values for "template". Source: ${node}');
|
||||
}
|
||||
viewDef.template = valueString;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
library angular2.transform.template_compiler.view_definition_creator;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:angular2/src/render/api.dart';
|
||||
import 'package:angular2/src/render/dom/convert.dart';
|
||||
import 'package:angular2/src/transform/common/asset_reader.dart';
|
||||
import 'package:angular2/src/transform/common/logging.dart';
|
||||
import 'package:angular2/src/transform/common/names.dart';
|
||||
import 'package:angular2/src/transform/common/parser.dart';
|
||||
import 'package:barback/barback.dart';
|
||||
import 'package:code_transformers/assets.dart';
|
||||
|
||||
/// Creates [ViewDefinition] objects for all `View` `Directive`s defined in
|
||||
/// `entryPoint`.
|
||||
Future<ViewDefinitionResults> createViewDefinitions(
|
||||
AssetReader reader, AssetId entryPoint) async {
|
||||
return await new _ViewDefinitionCreator(reader, entryPoint).createViewDefs();
|
||||
}
|
||||
|
||||
class ViewDefinitionResults {
|
||||
final NgDeps ngDeps;
|
||||
final Map<RegisteredType, ViewDefinition> viewDefinitions;
|
||||
ViewDefinitionResults._(this.ngDeps, this.viewDefinitions);
|
||||
}
|
||||
|
||||
String _getComponentId(AssetId assetId, String className) =>
|
||||
'$assetId:$className';
|
||||
|
||||
/// Creates [ViewDefinition] objects for all `View` `Directive`s defined in
|
||||
/// `entryPoint`.
|
||||
class _ViewDefinitionCreator {
|
||||
final AssetReader reader;
|
||||
final AssetId entryPoint;
|
||||
final Future<NgDeps> ngDepsFuture;
|
||||
|
||||
_ViewDefinitionCreator(AssetReader reader, AssetId entryPoint)
|
||||
: this.reader = reader,
|
||||
this.entryPoint = entryPoint,
|
||||
ngDepsFuture = new Parser(reader).parse(entryPoint);
|
||||
|
||||
Future<ViewDefinitionResults> createViewDefs() async {
|
||||
var ngDeps = await ngDepsFuture;
|
||||
|
||||
var retVal = <RegisteredType, ViewDefinition>{};
|
||||
var visitor = new _TemplateExtractVisitor(await _createMetadataMap());
|
||||
ngDeps.registeredTypes.forEach((rType) {
|
||||
visitor.reset();
|
||||
rType.annotations.accept(visitor);
|
||||
if (visitor.viewDef != null) {
|
||||
var typeName = '${rType.typeName}';
|
||||
if (visitor._metadataMap.containsKey(typeName)) {
|
||||
visitor.viewDef.componentId = visitor._metadataMap[typeName].id;
|
||||
} else {
|
||||
logger.warning('Missing component "$typeName" in metadata map',
|
||||
asset: entryPoint);
|
||||
visitor.viewDef.componentId = _getComponentId(entryPoint, typeName);
|
||||
}
|
||||
retVal[rType] = visitor.viewDef;
|
||||
}
|
||||
});
|
||||
return new ViewDefinitionResults._(ngDeps, retVal);
|
||||
}
|
||||
|
||||
/// Creates a map from [AssetId] to import prefix for `.dart` libraries
|
||||
/// imported by `entryPoint`, excluding any `.ng_deps.dart` files it imports.
|
||||
/// Unprefixed imports have `null` as their value. `entryPoint` is included
|
||||
/// in the map with no prefix.
|
||||
Future<Map<AssetId, String>> _createImportAssetToPrefixMap() async {
|
||||
// TODO(kegluneq): Support `part` directives.
|
||||
var ngDeps = await ngDepsFuture;
|
||||
|
||||
var importAssetToPrefix = <AssetId, String>{};
|
||||
// Include the `.ng_meta.dart` file associated with `entryPoint`.
|
||||
importAssetToPrefix[new AssetId(
|
||||
entryPoint.package, toMetaExtension(entryPoint.path))] = null;
|
||||
|
||||
for (ImportDirective node in ngDeps.imports) {
|
||||
var uri = stringLiteralToString(node.uri);
|
||||
if (uri.endsWith('.dart') && !uri.endsWith(DEPS_EXTENSION)) {
|
||||
var prefix = node.prefix != null && node.prefix.name != null
|
||||
? '${node.prefix.name}'
|
||||
: null;
|
||||
importAssetToPrefix[
|
||||
uriToAssetId(entryPoint, uri, logger, null /* span */)] = prefix;
|
||||
}
|
||||
}
|
||||
return importAssetToPrefix;
|
||||
}
|
||||
|
||||
/// Reads the `.ng_meta.json` files associated with all of `entryPoint`'s
|
||||
/// imports and creates a map `Type` name, prefixed if appropriate to the
|
||||
/// associated [DirectiveMetadata].
|
||||
///
|
||||
/// For example, if in `entryPoint` we have:
|
||||
///
|
||||
/// ```
|
||||
/// import 'component.dart' as prefix;
|
||||
/// ```
|
||||
///
|
||||
/// and in 'component.dart' we have:
|
||||
///
|
||||
/// ```
|
||||
/// @Component(...)
|
||||
/// class MyComponent {...}
|
||||
/// ```
|
||||
///
|
||||
/// This method will look for `component.ng_meta.json`to contain the
|
||||
/// serialized [DirectiveMetadata] `MyComponent` and any other `Directive`s
|
||||
/// declared in `component.dart`. We use this information to build a map:
|
||||
///
|
||||
/// ```
|
||||
/// {
|
||||
/// "prefix.MyComponent": [DirectiveMetadata for MyComponent],
|
||||
/// ...<any other entries>...
|
||||
/// }
|
||||
/// ```
|
||||
Future<Map<String, DirectiveMetadata>> _createMetadataMap() async {
|
||||
var importAssetToPrefix = await _createImportAssetToPrefixMap();
|
||||
|
||||
var retVal = <String, DirectiveMetadata>{};
|
||||
for (var importAssetId in importAssetToPrefix.keys) {
|
||||
var metaAssetId = new AssetId(
|
||||
importAssetId.package, toMetaExtension(importAssetId.path));
|
||||
if (await reader.hasInput(metaAssetId)) {
|
||||
try {
|
||||
var json = await reader.readAsString(metaAssetId);
|
||||
var jsonMap = JSON.decode(json);
|
||||
jsonMap.forEach((className, metaDataMap) {
|
||||
var prefixStr = importAssetToPrefix[importAssetId];
|
||||
var key = prefixStr != null ? '$prefixStr.$className' : className;
|
||||
var value = directiveMetadataFromMap(metaDataMap)
|
||||
..id = _getComponentId(importAssetId, className);
|
||||
retVal[key] = value;
|
||||
});
|
||||
} catch (ex, stackTrace) {
|
||||
logger.warning('Failed to decode: $ex, $stackTrace',
|
||||
asset: metaAssetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/// Visitor responsible for processing the `annotations` property of a
|
||||
/// {@link RegisterType} object and pulling out [ViewDefinition] information.
|
||||
class _TemplateExtractVisitor extends Object with RecursiveAstVisitor<Object> {
|
||||
ViewDefinition viewDef = null;
|
||||
final Map<String, DirectiveMetadata> _metadataMap;
|
||||
|
||||
_TemplateExtractVisitor(this._metadataMap);
|
||||
|
||||
void reset() {
|
||||
viewDef = null;
|
||||
}
|
||||
|
||||
/// These correspond to the annotations themselves.
|
||||
@override
|
||||
Object visitInstanceCreationExpression(InstanceCreationExpression node) {
|
||||
if ('${node.constructorName.type}' == 'View') {
|
||||
viewDef = new ViewDefinition(directives: <DirectiveMetadata>[]);
|
||||
node.visitChildren(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// These correspond to the annotation parameters.
|
||||
@override
|
||||
Object visitNamedExpression(NamedExpression node) {
|
||||
// TODO(kegluneq): Remove this limitation.
|
||||
if (node.name is! Label || node.name.label is! SimpleIdentifier) {
|
||||
logger.error(
|
||||
'Angular 2 currently only supports simple identifiers in directives.'
|
||||
' Source: ${node}');
|
||||
return null;
|
||||
}
|
||||
var keyString = '${node.name.label}';
|
||||
if (keyString == 'directives') {
|
||||
_readDirectives(node.expression);
|
||||
}
|
||||
if (keyString == 'template' || keyString == 'templateUrl') {
|
||||
if (node.expression is! SimpleStringLiteral) {
|
||||
logger.error(
|
||||
'Angular 2 currently only supports string literals in directives.'
|
||||
' Source: ${node}');
|
||||
return null;
|
||||
}
|
||||
var valueString = stringLiteralToString(node.expression);
|
||||
if (keyString == 'templateUrl') {
|
||||
if (viewDef.absUrl != null) {
|
||||
logger.error(
|
||||
'Found multiple values for "templateUrl". Source: ${node}');
|
||||
}
|
||||
viewDef.absUrl = valueString;
|
||||
} else {
|
||||
// keyString == 'template'
|
||||
if (viewDef.template != null) {
|
||||
logger.error('Found multiple values for "template". Source: ${node}');
|
||||
}
|
||||
viewDef.template = valueString;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void _readDirectives(Expression node) {
|
||||
if (node is! ListLiteral) {
|
||||
logger.error(
|
||||
'Angular 2 currently only supports list literals as values for'
|
||||
' "directives". Source: $node');
|
||||
return;
|
||||
}
|
||||
var directiveList = (node as ListLiteral);
|
||||
for (var node in directiveList.elements) {
|
||||
if (node is! SimpleIdentifier && node is! PrefixedIdentifier) {
|
||||
logger.error(
|
||||
'Angular 2 currently only supports simple and prefixed identifiers '
|
||||
'as values for "directives". Source: $node');
|
||||
return;
|
||||
}
|
||||
var name = '$node';
|
||||
if (_metadataMap.containsKey(name)) {
|
||||
viewDef.directives.add(_metadataMap[name]);
|
||||
} else {
|
||||
logger.warning('Could not find Directive entry for $name');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,6 +57,8 @@ void allTests() {
|
|||
outputs: {
|
||||
'a|web/bar.ng_deps.dart':
|
||||
'simple_annotation_files/expected/bar.ng_deps.dart',
|
||||
'a|web/bar.ng_meta.json':
|
||||
'simple_annotation_files/expected/bar.ng_meta.json',
|
||||
'a|web/index.ng_deps.dart':
|
||||
'simple_annotation_files/expected/index.ng_deps.dart'
|
||||
}),
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"MyComponent":{"id":"MyComponent","selector":"[soup]","compileChildren":true,"hostListeners":{},"hostProperties":{},"properties":{},"readAttributes":[],"type":1,"version":1}}
|
|
@ -58,6 +58,32 @@ void allTests() {
|
|||
var output = await processTemplates(reader, new AssetId('a', inputPath));
|
||||
_formatThenExpectEquals(output, expected);
|
||||
});
|
||||
|
||||
it('should parse `View` directives with a single dependency.', () async {
|
||||
var inputPath = 'template_compiler/one_directive_files/hello.ng_deps.dart';
|
||||
var expected = readFile(
|
||||
'template_compiler/one_directive_files/expected/hello.ng_deps.dart');
|
||||
|
||||
var output = await processTemplates(reader, new AssetId('a', inputPath));
|
||||
_formatThenExpectEquals(output, expected);
|
||||
});
|
||||
|
||||
it('should parse `View` directives with a single prefixed dependency.',
|
||||
() async {
|
||||
var inputPath = 'template_compiler/with_prefix_files/hello.ng_deps.dart';
|
||||
var expected = readFile(
|
||||
'template_compiler/with_prefix_files/expected/hello.ng_deps.dart');
|
||||
|
||||
var output = await processTemplates(reader, new AssetId('a', inputPath));
|
||||
_formatThenExpectEquals(output, expected);
|
||||
|
||||
inputPath = 'template_compiler/with_prefix_files/goodbye.ng_deps.dart';
|
||||
expected = readFile(
|
||||
'template_compiler/with_prefix_files/expected/goodbye.ng_deps.dart');
|
||||
|
||||
output = await processTemplates(reader, new AssetId('a', inputPath));
|
||||
_formatThenExpectEquals(output, expected);
|
||||
});
|
||||
}
|
||||
|
||||
void _formatThenExpectEquals(String actual, String expected) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"HelloCmp":
|
||||
{
|
||||
"id":"HelloCmp",
|
||||
"selector":"hello-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"HelloCmp":
|
||||
{
|
||||
"id":"HelloCmp",
|
||||
"selector":"hello-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"HelloCmp":
|
||||
{
|
||||
"id":"HelloCmp",
|
||||
"selector":"hello-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
library examples.hello_world.index_common_dart.ng_deps.dart;
|
||||
|
||||
import 'hello.dart';
|
||||
import 'package:angular2/angular2.dart'
|
||||
show bootstrap, Component, Directive, View, NgElement;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(HelloCmp, {
|
||||
'factory': () => new HelloCmp(),
|
||||
'parameters': const [const []],
|
||||
'annotations': const [
|
||||
const Component(selector: 'hello-app'),
|
||||
const View(template: 'goodbye-app', directives: const [GoodbyeCmp])
|
||||
]
|
||||
})
|
||||
..registerType(GoodbyeCmp, {
|
||||
'factory': () => new GoodbyeCmp(),
|
||||
'parameters': const [const []],
|
||||
'annotations': const [
|
||||
const Component(selector: 'goodbye-app'),
|
||||
const View(template: 'Goodbye')
|
||||
]
|
||||
});
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
library examples.hello_world.index_common_dart.ng_deps.dart;
|
||||
|
||||
import 'hello.dart';
|
||||
import 'package:angular2/angular2.dart'
|
||||
show bootstrap, Component, Directive, View, NgElement;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(HelloCmp, {
|
||||
'factory': () => new HelloCmp(),
|
||||
'parameters': const [const []],
|
||||
'annotations': const [
|
||||
const Component(selector: 'hello-app'),
|
||||
const View(template: 'goodbye-app', directives: const [GoodbyeCmp])
|
||||
]
|
||||
})
|
||||
..registerType(GoodbyeCmp, {
|
||||
'factory': () => new GoodbyeCmp(),
|
||||
'parameters': const [const []],
|
||||
'annotations': const [
|
||||
const Component(selector: 'goodbye-app'),
|
||||
const View(template: 'Goodbye')
|
||||
]
|
||||
});
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"HelloCmp":
|
||||
{
|
||||
"id":"HelloCmp",
|
||||
"selector":"hello-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
},
|
||||
"GoodbyeCmp":{
|
||||
"id":"GoodbyeCmp",
|
||||
"selector":"goodbye-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"HelloCmp":
|
||||
{
|
||||
"id":"HelloCmp",
|
||||
"selector":"hello-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"HelloCmp":
|
||||
{
|
||||
"id":"HelloCmp",
|
||||
"selector":"hello-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
library examples.hello_world.index_common_dart.ng_deps.dart;
|
||||
|
||||
import 'goodbye.dart';
|
||||
import 'package:angular2/angular2.dart'
|
||||
show bootstrap, Component, Directive, View, NgElement;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(GoodbyeCmp, {
|
||||
'factory': () => new GoodbyeCmp(),
|
||||
'parameters': const [const []],
|
||||
'annotations': const [
|
||||
const Component(selector: 'goodbye-app'),
|
||||
const View(template: 'Goodbye {{name}}')
|
||||
]
|
||||
})
|
||||
..registerGetters({'name': (o) => o.name})
|
||||
..registerSetters({'name': (o, v) => o.name = v});
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
library examples.hello_world.index_common_dart.ng_deps.dart;
|
||||
|
||||
import 'hello.dart';
|
||||
import 'goodbye.dart' as prefix;
|
||||
import 'goodbye.ng_deps.dart' as i0;
|
||||
import 'package:angular2/angular2.dart'
|
||||
show bootstrap, Component, Directive, View, NgElement;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(HelloCmp, {
|
||||
'factory': () => new HelloCmp(),
|
||||
'parameters': const [const []],
|
||||
'annotations': const [
|
||||
const Component(selector: 'hello-app'),
|
||||
const View(
|
||||
template: 'goodbye-app', directives: const [prefix.GoodbyeCmp])
|
||||
]
|
||||
});
|
||||
i0.initReflector(reflector);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
library examples.hello_world.index_common_dart.ng_deps.dart;
|
||||
|
||||
import 'goodbye.dart';
|
||||
import 'package:angular2/angular2.dart'
|
||||
show bootstrap, Component, Directive, View, NgElement;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(GoodbyeCmp, {
|
||||
'factory': () => new GoodbyeCmp(),
|
||||
'parameters': const [const []],
|
||||
'annotations': const [
|
||||
const Component(selector: 'goodbye-app'),
|
||||
const View(template: 'Goodbye {{name}}')
|
||||
]
|
||||
});
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"GoodbyeCmp":{
|
||||
"id":"GoodbyeCmp",
|
||||
"selector":"goodbye-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
library examples.hello_world.index_common_dart.ng_deps.dart;
|
||||
|
||||
import 'hello.dart';
|
||||
import 'goodbye.dart' as prefix;
|
||||
import 'goodbye.ng_deps.dart' as i0;
|
||||
import 'package:angular2/angular2.dart'
|
||||
show bootstrap, Component, Directive, View, NgElement;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(HelloCmp, {
|
||||
'factory': () => new HelloCmp(),
|
||||
'parameters': const [const []],
|
||||
'annotations': const [
|
||||
const Component(selector: 'hello-app'),
|
||||
const View(
|
||||
template: 'goodbye-app', directives: const [prefix.GoodbyeCmp])
|
||||
]
|
||||
});
|
||||
i0.initReflector(reflector);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"HelloCmp":
|
||||
{
|
||||
"id":"HelloCmp",
|
||||
"selector":"hello-app",
|
||||
"compileChildren":true,
|
||||
"hostListeners":{},
|
||||
"hostProperties":{},
|
||||
"properties":{},
|
||||
"readAttributes":[],
|
||||
"type":1,
|
||||
"version":1
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ function getSourceTree() {
|
|||
var tsInputTree = modulesFunnel(['**/*.js', '**/*.ts', '**/*.dart'], ['rtts_assert/**/*']);
|
||||
var transpiled = ts2dart.transpile(tsInputTree);
|
||||
// Native sources, dart only examples, etc.
|
||||
var dartSrcs = modulesFunnel(['**/*.dart']);
|
||||
var dartSrcs = modulesFunnel(['**/*.dart', '**/*.ng_meta.json']);
|
||||
return mergeTrees([transpiled, dartSrcs]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue