diff --git a/modules/angular2/src/transform/common/directive_metadata_reader.dart b/modules/angular2/src/transform/common/directive_metadata_reader.dart index dd63cb984a..d398508969 100644 --- a/modules/angular2/src/transform/common/directive_metadata_reader.dart +++ b/modules/angular2/src/transform/common/directive_metadata_reader.dart @@ -47,6 +47,7 @@ class _DirectiveMetadataVisitor extends Object properties: {}, hostListeners: {}, hostProperties: {}, + hostAttributes: {}, readAttributes: []); super.visitInstanceCreationExpression(node); } @@ -80,6 +81,9 @@ class _DirectiveMetadataVisitor extends Object case 'hostProperties': _populateHostProperties(node.expression); break; + case 'hostAttributes': + _populateHostAttributes(node.expression); + break; case 'hostListeners': _populateHostListeners(node.expression); } @@ -155,4 +159,20 @@ class _DirectiveMetadataVisitor extends Object meta.hostProperties[sKey] = sVal; } } + + void _populateHostAttributes(Expression hostAttributeValue) { + if (hostAttributeValue is! MapLiteral) { + logger.error('Angular 2 currently only supports map literal values for ' + 'Directive#hostAttributes.' + ' Source: ${hostAttributeValue}'); + return; + } + for (MapLiteralEntry entry in (hostAttributeValue as MapLiteral).entries) { + var sKey = + _expressionToString(entry.key, 'Directive#hostAttributes keys'); + var sVal = + _expressionToString(entry.value, 'Directive#hostAttributes values'); + meta.hostAttributes[sKey] = sVal; + } + } } diff --git a/modules/angular2/src/transform/directive_metadata_extractor/transformer.dart b/modules/angular2/src/transform/directive_metadata_extractor/transformer.dart index 6a4bb3abba..7271c03b74 100644 --- a/modules/angular2/src/transform/directive_metadata_extractor/transformer.dart +++ b/modules/angular2/src/transform/directive_metadata_extractor/transformer.dart @@ -16,6 +16,8 @@ import 'extractor.dart'; /// These files contain commented Json-formatted representations of all /// `Directive`s in the associated file. class DirectiveMetadataExtractor extends Transformer { + final _encoder = const JsonEncoder.withIndent(' '); + DirectiveMetadataExtractor(); @override @@ -36,7 +38,7 @@ class DirectiveMetadataExtractor extends Transformer { jsonMap[k] = directiveMetadataToMap(v); }); transform.addOutput(new Asset.fromString( - _outputAssetId(fromAssetId), JSON.encode(jsonMap))); + _outputAssetId(fromAssetId), _encoder.convert(jsonMap))); } } catch (ex, stackTrace) { log.logger.error('Extracting ng metadata failed.\n' diff --git a/modules/angular2/src/transform/template_compiler/view_definition_creator.dart b/modules/angular2/src/transform/template_compiler/view_definition_creator.dart index ff6e18bb75..8aa4280c51 100644 --- a/modules/angular2/src/transform/template_compiler/view_definition_creator.dart +++ b/modules/angular2/src/transform/template_compiler/view_definition_creator.dart @@ -29,6 +29,10 @@ class ViewDefinitionResults { String _getComponentId(AssetId assetId, String className) => '$assetId:$className'; +// TODO(kegluenq): Improve this test. +bool _isViewAnnotation(InstanceCreationExpression node) => + '${node.constructorName.type}' == 'View'; + /// Creates [ViewDefinition] objects for all `View` `Directive`s defined in /// `entryPoint`. class _ViewDefinitionCreator { @@ -108,8 +112,9 @@ class _ViewDefinitionCreator { /// ``` /// /// 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: + /// serialized [DirectiveMetadata] for `MyComponent` and any other + /// `Directive`s declared in `component.dart`. We use this information to + /// build a map: /// /// ``` /// { @@ -146,7 +151,7 @@ class _ViewDefinitionCreator { } /// Visitor responsible for processing the `annotations` property of a -/// {@link RegisterType} object and pulling out [ViewDefinition] information. +/// [RegisterType] object and pulling out [ViewDefinition] information. class _TemplateExtractVisitor extends Object with RecursiveAstVisitor { ViewDefinition viewDef = null; final Map _metadataMap; @@ -160,7 +165,7 @@ class _TemplateExtractVisitor extends Object with RecursiveAstVisitor { /// These correspond to the annotations themselves. @override Object visitInstanceCreationExpression(InstanceCreationExpression node) { - if ('${node.constructorName.type}' == 'View') { + if (_isViewAnnotation(node)) { viewDef = new ViewDefinition(directives: []); node.visitChildren(this); } @@ -182,6 +187,10 @@ class _TemplateExtractVisitor extends Object with RecursiveAstVisitor { _readDirectives(node.expression); } if (keyString == 'template' || keyString == 'templateUrl') { + // This could happen in a non-View annotation with a `template` or + // `templateUrl` property. + if (viewDef == null) return null; + if (node.expression is! SimpleStringLiteral) { logger.error( 'Angular 2 currently only supports string literals in directives.' @@ -207,6 +216,10 @@ class _TemplateExtractVisitor extends Object with RecursiveAstVisitor { } void _readDirectives(Expression node) { + // This could happen in a non-View annotation with a `directives` + // parameter. + if (viewDef == null) return; + if (node is! ListLiteral) { logger.error( 'Angular 2 currently only supports list literals as values for' diff --git a/modules/angular2/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json b/modules/angular2/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json index a0ae1769f7..5abbe1c03b 100644 --- a/modules/angular2/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json +++ b/modules/angular2/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json @@ -1 +1,14 @@ -{"MyComponent":{"id":"MyComponent","selector":"[soup]","compileChildren":true,"hostListeners":{},"hostProperties":{},"properties":{},"readAttributes":[],"type":1,"version":1}} \ No newline at end of file +{ + "MyComponent": { + "id": "MyComponent", + "selector": "[soup]", + "compileChildren": true, + "hostListeners": {}, + "hostProperties": {}, + "hostAttributes": {}, + "properties": {}, + "readAttributes": [], + "type": 1, + "version": 1 + } +} \ No newline at end of file