From ca5e31bc774bc6f3d1f335753aaad9e733e7bd0e Mon Sep 17 00:00:00 2001 From: Tim Blasi Date: Wed, 14 Oct 2015 12:46:35 -0700 Subject: [PATCH] feat(dart/transform): Avoid overwriting assets For easier debugging, avoid overwriting assets in Dart transform steps where possible. --- .../lib/src/transform/common/names.dart | 14 +++++----- .../ng_deps_linker.dart | 20 +++++++------ .../ng_meta_linker.dart | 2 +- .../transformer.dart | 28 +++++++++++++++---- .../directive_processor/transformer.dart | 17 ++++++----- .../template_compiler/transformer.dart | 13 +++++---- .../directive_metadata_linker/all_tests.dart | 9 +++--- 7 files changed, 63 insertions(+), 40 deletions(-) diff --git a/modules_dart/transform/lib/src/transform/common/names.dart b/modules_dart/transform/lib/src/transform/common/names.dart index 09efe11320..bf2675e570 100644 --- a/modules_dart/transform/lib/src/transform/common/names.dart +++ b/modules_dart/transform/lib/src/transform/common/names.dart @@ -8,9 +8,7 @@ const CSS_EXTENSION = '.css'; const SHIMMED_STYLESHEET_EXTENSION = '.css.shim.dart'; const NON_SHIMMED_STYLESHEET_EXTENSION = '.css.dart'; const DEPS_EXTENSION = '.ng_deps.dart'; -const DEPS_JSON_EXTENSION = '.ng_deps.json'; const META_EXTENSION = '.ng_meta.json'; -const TEMPLATE_EXTENSION = '.template.dart'; const REFLECTION_CAPABILITIES_NAME = 'ReflectionCapabilities'; const REFLECTOR_IMPORT = 'package:angular2/src/core/reflection/reflection.dart'; const REFLECTOR_PREFIX = '_ngRef'; @@ -18,14 +16,16 @@ const REGISTER_TYPE_METHOD_NAME = 'registerType'; const REGISTER_GETTERS_METHOD_NAME = 'registerGetters'; const REGISTER_SETTERS_METHOD_NAME = 'registerSetters'; const REGISTER_METHODS_METHOD_NAME = 'registerMethods'; +const SUMMARY_META_EXTENSION = '.ng_summary.json'; +const TEMPLATE_EXTENSION = '.template.dart'; /// Note that due to the implementation of `_toExtension`, ordering is /// important. For example, putting '.dart' first in this list will cause /// incorrect behavior. const ALL_EXTENSIONS = const [ DEPS_EXTENSION, - DEPS_JSON_EXTENSION, META_EXTENSION, + SUMMARY_META_EXTENSION, TEMPLATE_EXTENSION, '.dart' ]; @@ -38,10 +38,6 @@ String toMetaExtension(String uri) => String toDepsExtension(String uri) => _toExtension(uri, ALL_EXTENSIONS, DEPS_EXTENSION); -/// Returns `uri` with its extension updated to [DEPS_JSON_EXTENSION]. -String toJsonExtension(String uri) => - _toExtension(uri, ALL_EXTENSIONS, DEPS_JSON_EXTENSION); - /// Returns `uri` with its extension updated to [TEMPLATES_EXTENSION]. String toTemplateExtension(String uri) => _toExtension(uri, ALL_EXTENSIONS, TEMPLATE_EXTENSION); @@ -54,6 +50,10 @@ String toShimmedStylesheetExtension(String uri) => String toNonShimmedStylesheetExtension(String uri) => _toExtension(uri, const [CSS_EXTENSION], NON_SHIMMED_STYLESHEET_EXTENSION); +/// Returns `uri` with its extension updated to [SUMMARY_META_EXTENSION]. +String toSummaryExtension(String uri) => + _toExtension(uri, ALL_EXTENSIONS, SUMMARY_META_EXTENSION); + /// Returns `uri` with its extension updated to `toExtension` if its /// extension is currently in `fromExtension`. String _toExtension( diff --git a/modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_deps_linker.dart b/modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_deps_linker.dart index 531057a11d..84b5f0d342 100644 --- a/modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_deps_linker.dart +++ b/modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_deps_linker.dart @@ -33,9 +33,11 @@ Future linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader, return ngDepsModel; } + final seen = new Set(); for (var i = ngDepsModel.imports.length - 1; i >= 0; --i) { var import = ngDepsModel.imports[i]; - if (linkedDepsMap.containsKey(import.uri)) { + if (linkedDepsMap.containsKey(import.uri) && !seen.contains(import.uri)) { + seen.add(import.uri); var linkedModel = new ImportModel() ..isNgDeps = true ..uri = toDepsExtension(import.uri) @@ -46,7 +48,8 @@ Future linkNgDeps(NgDepsModel ngDepsModel, AssetReader reader, } for (var i = 0, iLen = ngDepsModel.exports.length; i < iLen; ++i) { var export = ngDepsModel.exports[i]; - if (linkedDepsMap.containsKey(export.uri)) { + if (linkedDepsMap.containsKey(export.uri) && !seen.contains(export.uri)) { + seen.add(export.uri); var linkedModel = new ImportModel() ..isNgDeps = true ..uri = toDepsExtension(export.uri) @@ -73,16 +76,15 @@ Future> _processNgImports(NgDepsModel model, return Future .wait( importsAndExports.where(_isNotDartDirective).map((dynamic directive) { - // The uri of the import or export with .dart replaced with .ng_meta.json. - // This is the json file containing Angular 2 codegen info, if one exists. - var linkedJsonUri = - resolver.resolve(assetUri, toMetaExtension(directive.uri)); - return reader.hasInput(fromUri(linkedJsonUri)).then((hasInput) { + // Check whether the import or export generated summary NgMeta information. + final summaryJsonUri = + resolver.resolve(assetUri, toSummaryExtension(directive.uri)); + return reader.hasInput(fromUri(summaryJsonUri)).then((hasInput) { if (hasInput) { - retVal[directive.uri] = linkedJsonUri; + retVal[directive.uri] = summaryJsonUri; } }, onError: (err, stack) { - logger.warning('Error while looking for $linkedJsonUri. ' + logger.warning('Error while looking for $summaryJsonUri. ' 'Message: $err\n' 'Stack: $stack'); }); diff --git a/modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_meta_linker.dart b/modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_meta_linker.dart index 651900c984..fb3cd1562e 100644 --- a/modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_meta_linker.dart +++ b/modules_dart/transform/lib/src/transform/directive_metadata_linker/ng_meta_linker.dart @@ -64,7 +64,7 @@ Future _linkRecursive(NgMeta ngMeta, AssetReader reader, AssetId assetId, return Future.wait(ngMeta.ngDeps.exports .where((export) => !isDartCoreUri(export.uri)) .map((export) => - _urlResolver.resolve(assetUri, toMetaExtension(export.uri))) + _urlResolver.resolve(assetUri, toSummaryExtension(export.uri))) .where((uri) => !seen.contains(uri)) .map((uri) async { seen.add(uri); diff --git a/modules_dart/transform/lib/src/transform/directive_metadata_linker/transformer.dart b/modules_dart/transform/lib/src/transform/directive_metadata_linker/transformer.dart index e8656dcecb..7dc63a7b11 100644 --- a/modules_dart/transform/lib/src/transform/directive_metadata_linker/transformer.dart +++ b/modules_dart/transform/lib/src/transform/directive_metadata_linker/transformer.dart @@ -10,19 +10,30 @@ import 'package:barback/barback.dart'; import 'ng_meta_linker.dart'; -/// Transformer responsible for processing .ng_meta.json files created by +/// Transformer responsible for processing .ng_summary.json files created by /// {@link DirectiveProcessor} and "linking" them. /// /// This step ensures that for libraries that export, all `Directive`s reachable /// from that library are declared in its associated .ng_meta.json file. /// +/// Said another way, after this step there should be an entry in this `NgMeta` +/// object for all `Directives` visible from its associated `.dart` file. +/// +/// This step also ensures that, if `a.dart` imports `b.dart`, `a.ng_deps.dart` +/// imports `b.ng_deps.dart` (if it exists) and we note that this is a +/// ngDeps dependency, ensuring that a's `initReflector` function calls b's +/// `initReflector' function. +/// /// See `common/ng_meta.dart` for the JSON format of these files are serialized /// to. +/// +/// This transformer is part of a multi-phase transform. +/// See `angular2/src/transform/transformer.dart` for transformer ordering. class DirectiveMetadataLinker extends Transformer { final _encoder = const JsonEncoder.withIndent(' '); @override - bool isPrimary(AssetId id) => id.path.endsWith(META_EXTENSION); + bool isPrimary(AssetId id) => id.path.endsWith(SUMMARY_META_EXTENSION); @override Future apply(Transform transform) { @@ -32,14 +43,21 @@ class DirectiveMetadataLinker extends Transformer { return linkDirectiveMetadata( new AssetReader.fromTransform(transform), primaryId).then((ngMeta) { if (ngMeta != null) { + final outputId = _ngLinkedAssetId(primaryId); if (!ngMeta.isEmpty) { transform.addOutput(new Asset.fromString( - primaryId, _encoder.convert(ngMeta.toJson()))); + outputId, _encoder.convert(ngMeta.toJson()))); } else { // Not outputting an asset could confuse barback. - transform.addOutput(new Asset.fromString(primaryId, '')); + transform.addOutput(new Asset.fromString(outputId, '')); } - } }); + } + }); }); } } + +AssetId _ngLinkedAssetId(AssetId primaryInputId) { + return new AssetId( + primaryInputId.package, toMetaExtension(primaryInputId.path)); +} diff --git a/modules_dart/transform/lib/src/transform/directive_processor/transformer.dart b/modules_dart/transform/lib/src/transform/directive_processor/transformer.dart index 1fcfde8677..10c3dfe790 100644 --- a/modules_dart/transform/lib/src/transform/directive_processor/transformer.dart +++ b/modules_dart/transform/lib/src/transform/directive_processor/transformer.dart @@ -13,14 +13,13 @@ import 'package:barback/barback.dart'; import 'rewriter.dart'; /// Transformer responsible for processing all .dart assets and creating -/// .ng_deps.dart files which register @Injectable annotated classes with the -/// reflector. +/// .ng_summary.json files which summarize those assets. /// -/// This will also create .ng_deps.dart files for classes annotated -/// with @Component, @View, @Directive, etc. +/// See `angular2/src/transform/common/ng_meta.dart` for the structure of these +/// output files. /// -/// This transformer is the first phase in a two-phase transform. It should -/// be followed by {@link DirectiveLinker}. +/// This transformer is part of a multi-phase transform. +/// See `angular2/src/transform/transformer.dart` for transformer ordering. class DirectiveProcessor extends Transformer { final TransformerOptions options; final _encoder = const JsonEncoder.withIndent(' '); @@ -42,12 +41,12 @@ class DirectiveProcessor extends Transformer { return; } transform.addOutput(new Asset.fromString( - _ngMetaAssetId(primaryId), _encoder.convert(ngMeta.toJson()))); + _ngSummaryAssetId(primaryId), _encoder.convert(ngMeta.toJson()))); }); } } -AssetId _ngMetaAssetId(AssetId primaryInputId) { +AssetId _ngSummaryAssetId(AssetId primaryInputId) { return new AssetId( - primaryInputId.package, toMetaExtension(primaryInputId.path)); + primaryInputId.package, toSummaryExtension(primaryInputId.path)); } diff --git a/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart b/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart index 7d82b21aa9..ab34152d62 100644 --- a/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart +++ b/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart @@ -13,12 +13,15 @@ import 'package:barback/barback.dart'; import 'generator.dart'; -/// {@link Transformer} responsible for detecting and processing Angular 2 templates. +/// {@link Transformer} responsible for processing Angular 2 templates. /// -/// {@link TemplateCompiler} uses the Angular 2 `Compiler` to process the templates, -/// extracting information about what reflection is necessary to render and -/// use that template. It then generates code in place of those reflective -/// accesses. +/// {@link TemplateCompiler} uses the Angular 2 `TemplateCompiler` to process +/// the templates, extracting information about what reflection is necessary to +/// render and use that template. It then generates code in place of those +/// reflective accesses. +/// +/// This transformer is part of a multi-phase transform. +/// See `angular2/src/transform/transformer.dart` for transformer ordering. class TemplateCompiler extends Transformer { final TransformerOptions options; diff --git a/modules_dart/transform/test/transform/directive_metadata_linker/all_tests.dart b/modules_dart/transform/test/transform/directive_metadata_linker/all_tests.dart index 2a5d2addba..461aa5a8cf 100644 --- a/modules_dart/transform/test/transform/directive_metadata_linker/all_tests.dart +++ b/modules_dart/transform/test/transform/directive_metadata_linker/all_tests.dart @@ -5,6 +5,7 @@ import 'dart:convert'; import 'package:angular2/src/transform/common/asset_reader.dart'; import 'package:angular2/src/transform/common/logging.dart' as log; +import 'package:angular2/src/transform/common/names.dart'; import 'package:angular2/src/transform/common/model/import_export_model.pb.dart'; import 'package:angular2/src/transform/directive_metadata_linker/ng_meta_linker.dart'; import 'package:barback/barback.dart'; @@ -49,9 +50,9 @@ void allTests() { bazNgMeta = new NgMeta(ngDeps: new NgDepsModel()); barNgMeta.types[bazComponentMeta.type.name] = bazComponentMeta; - fooAssetId = new AssetId('a', 'lib/foo.ng_meta.json'); - barAssetId = new AssetId('a', 'lib/bar.ng_meta.json'); - bazAssetId = new AssetId('a', 'lib/baz.ng_meta.json'); + fooAssetId = new AssetId('a', toSummaryExtension('lib/foo.dart')); + barAssetId = new AssetId('a', toSummaryExtension('lib/bar.dart')); + bazAssetId = new AssetId('a', toSummaryExtension('lib/baz.dart')); updateReader(); }); @@ -102,7 +103,7 @@ void allTests() { fooNgMeta.ngDeps.exports .add(new ExportModel()..uri = 'package:bar/bar.dart'); updateReader(); - reader.addAsset(new AssetId('bar', 'lib/bar.ng_meta.json'), + reader.addAsset(new AssetId('bar', toSummaryExtension('lib/bar.dart')), JSON.encode(barNgMeta.toJson())); var extracted = await _testLink(reader, fooAssetId);