diff --git a/modules/angular2/pubspec.yaml b/modules/angular2/pubspec.yaml index 5597f90add..82266fc98a 100644 --- a/modules/angular2/pubspec.yaml +++ b/modules/angular2/pubspec.yaml @@ -27,7 +27,7 @@ dev_dependencies: quiver: '^0.21.4' test: '^0.12.6' transformers: -- angular2 +- angular2/transform/codegen - $dart2js: commandLineOptions: - --show-package-warnings diff --git a/modules_dart/transform/lib/src/transform/deferred_rewriter/transformer.dart b/modules_dart/transform/lib/src/transform/deferred_rewriter/transformer.dart index a7be78d571..b414f7fed4 100644 --- a/modules_dart/transform/lib/src/transform/deferred_rewriter/transformer.dart +++ b/modules_dart/transform/lib/src/transform/deferred_rewriter/transformer.dart @@ -6,18 +6,21 @@ import 'package:barback/barback.dart'; import 'package:angular2/src/transform/common/asset_reader.dart'; import 'package:angular2/src/transform/common/names.dart'; -import 'package:angular2/src/transform/common/options.dart'; import 'package:angular2/src/transform/common/zone.dart' as zone; import 'rewriter.dart'; -/// Transformer responsible for rewriting deferred library loads to enable -/// initializing the reflector in a deferred way to keep the code with the -/// deferred library. +/// Transformer which rewrites deferred imports and `loadLibrary` calls. +/// +/// Deferred imports with associated initialization code are rewritten to +/// point to their associated generated code file. +/// `loadLibrary` calls for libraries with associated initialization methods +/// are rewritten to initialize after the library is loaded and before use. class DeferredRewriter extends AggregateTransformer implements LazyTransformer { - final TransformerOptions options; + DeferredRewriter(); - DeferredRewriter(this.options); + /// Ctor which tells pub that this can be run as a standalone transformer. + DeferredRewriter.asPlugin(BarbackSettings _); @override declareOutputs(DeclaringTransform transform) { @@ -41,45 +44,51 @@ class DeferredRewriter extends AggregateTransformer implements LazyTransformer { @override Future apply(AggregateTransform transform) async { - return zone.exec(() async { - final dartAsset = await _assetToProcess(transform); - if (dartAsset == null) return; + final dartAsset = await _assetToProcess(transform); + if (dartAsset == null) return null; + return applyImpl(transform, dartAsset.id); + } + /// Transforms the asset with id [id]. + /// + /// [transform] must be an [AggregateTransform] or [Transform]. + Future applyImpl(dynamic transform, AssetId id) { + assert(transform is AggregateTransform || transform is Transform); + + return zone.exec(() async { var transformedCode = await rewriteDeferredLibraries( - new AssetReader.fromTransform(transform), dartAsset.id); + new AssetReader.fromTransform(transform), id); if (transformedCode != null) { - transform - .addOutput(new Asset.fromString(dartAsset.id, transformedCode)); + transform.addOutput(new Asset.fromString(id, transformedCode)); } }, log: transform.logger); } - - /// Returns the asset we need to process or `null` if none exists. - /// - /// Consumes the .dart.deferredCount asset if it is present. - Future _assetToProcess(AggregateTransform transform) async { - // We only need to process .dart files that have an associated - // .dart.deferredCount file with a value != "0". - // - // The .dart.deferredCount file is generated by a previous phase for files - // which have deferred imports. An absent .dart.deferredCount asset is the - // treated the same as a .dart.deferredCount asset with value "0". - var dartAsset, deferredCountAsset; - await for (Asset a in transform.primaryInputs) { - if (a.id.path.endsWith(DEFERRED_EXTENSION)) { - deferredCountAsset = a; - } else if (a.id.path.endsWith('.dart')) { - dartAsset = a; - } - } - if (deferredCountAsset == null) return null; - // No longer necessary. - transform.consumePrimary(deferredCountAsset.id); - if ((await deferredCountAsset.readAsString()) == "0") return null; - return dartAsset; - } } -// Visible for testing +/// Returns the asset we need to process or `null` if none exists. +/// +/// Consumes the .dart.deferredCount asset if it is present. +Future _assetToProcess(AggregateTransform transform) async { + // We only need to process .dart files that have an associated + // .dart.deferredCount file with a value != "0". + // + // The .dart.deferredCount file is generated by a previous phase for files + // which have deferred imports. An absent .dart.deferredCount asset is the + // treated the same as a .dart.deferredCount asset with value "0". + var dartAsset, deferredCountAsset; + await for (Asset a in transform.primaryInputs) { + if (a.id.path.endsWith(DEFERRED_EXTENSION)) { + deferredCountAsset = a; + } else if (a.id.path.endsWith('.dart')) { + dartAsset = a; + } + } + if (deferredCountAsset == null) return null; + // No longer necessary. + transform.consumePrimary(deferredCountAsset.id); + if ((await deferredCountAsset.readAsString()) == "0") return null; + return dartAsset; +} + Future rewriteDeferredLibraries(AssetReader reader, AssetId id) => rewriteLibrary(id, reader); diff --git a/modules_dart/transform/lib/src/transform/quick_transformer.dart b/modules_dart/transform/lib/src/transform/quick_transformer.dart deleted file mode 100644 index 55f9718c12..0000000000 --- a/modules_dart/transform/lib/src/transform/quick_transformer.dart +++ /dev/null @@ -1,68 +0,0 @@ -library angular2.src.transform.quick_transformer; - -import 'package:barback/barback.dart'; -import 'package:dart_style/dart_style.dart'; - -import 'common/formatter.dart' as formatter; -import 'common/options.dart'; -import 'common/options_reader.dart'; -import 'deferred_rewriter/transformer.dart'; -// import 'directive_metadata_linker/transformer.dart'; -// import 'directive_processor/transformer.dart'; -import 'inliner_for_test/transformer.dart'; -import 'reflection_remover/transformer.dart'; -// import 'stylesheet_compiler/transformer.dart'; -// import 'template_compiler/transformer.dart'; - -export 'common/options.dart'; - -/// Replaces Angular 2 mirror use with generated code. -/// -/// Typical users should not use this implementation and should instead use -/// package:angular2/transformer.dart. -/// -/// This alternative excludes phases that generate new [Asset]s, including only -/// the phases that replace existing [Asset]s. -/// -/// This can be used if all code that would be generated already exists as real -/// files, rather than needing to be generated by [Transformer]s. -class AngularTransformerGroup extends TransformerGroup { - AngularTransformerGroup._(phases, {bool formatCode: false}) : super(phases) { - if (formatCode) { - formatter.init(new DartFormatter()); - } - } - - factory AngularTransformerGroup(TransformerOptions options) { - var phases; - if (options.inlineViews) { - phases = [ - [new InlinerForTest(options)] - ]; - } else { - // Only the phases that replace [Asset]s. - phases = [ - [new ReflectionRemover(options)], - [new DeferredRewriter(options)], - ]; - /* - phases = [ - [new DirectiveProcessor(options)], - [new DirectiveMetadataLinker()], - [new ReflectionRemover(options)], - [ - new DeferredRewriter(options), - new StylesheetCompiler(), - new TemplateCompiler(options) - ], - ]; - */ - } - return new AngularTransformerGroup._(phases, - formatCode: options.formatCode); - } - - factory AngularTransformerGroup.asPlugin(BarbackSettings settings) { - return new AngularTransformerGroup(parseBarbackSettings(settings)); - } -} diff --git a/modules_dart/transform/lib/src/transform/reflection_remover/transformer.dart b/modules_dart/transform/lib/src/transform/reflection_remover/transformer.dart index c86f69b747..6236160fad 100644 --- a/modules_dart/transform/lib/src/transform/reflection_remover/transformer.dart +++ b/modules_dart/transform/lib/src/transform/reflection_remover/transformer.dart @@ -8,6 +8,7 @@ import 'package:angular2/src/transform/common/asset_reader.dart'; import 'package:angular2/src/transform/common/mirror_mode.dart'; import 'package:angular2/src/transform/common/names.dart'; import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/common/options_reader.dart'; import 'package:angular2/src/transform/common/zone.dart' as zone; import 'remove_reflection_capabilities.dart'; @@ -26,8 +27,13 @@ class ReflectionRemover extends Transformer implements LazyTransformer { ReflectionRemover(this.options); + /// Ctor which tells pub that this can be run as a standalone transformer. + factory ReflectionRemover.asPlugin(BarbackSettings settings) => + new ReflectionRemover(parseBarbackSettings(settings)); + @override - bool isPrimary(AssetId id) => options.entryPointGlobs != null && + bool isPrimary(AssetId id) => + options.entryPointGlobs != null && options.entryPointGlobs.any((g) => g.matches(id.path)); @override diff --git a/modules_dart/transform/lib/src/transform/transformer.dart b/modules_dart/transform/lib/src/transform/transformer.dart index 4843c0075d..0583685e96 100644 --- a/modules_dart/transform/lib/src/transform/transformer.dart +++ b/modules_dart/transform/lib/src/transform/transformer.dart @@ -37,7 +37,7 @@ class AngularTransformerGroup extends TransformerGroup { [new DirectiveMetadataLinker()], [new ReflectionRemover(options)], [ - new DeferredRewriter(options), + new DeferredRewriter(), new StylesheetCompiler(), new TemplateCompiler(options) ], diff --git a/modules_dart/transform/lib/transform/codegen.dart b/modules_dart/transform/lib/transform/codegen.dart new file mode 100644 index 0000000000..e48b2c97d0 --- /dev/null +++ b/modules_dart/transform/lib/transform/codegen.dart @@ -0,0 +1,56 @@ +library angular2.transform.codegen.dart; + +import 'package:barback/barback.dart'; +import 'package:dart_style/dart_style.dart'; + +import 'package:angular2/src/transform/common/eager_transformer_wrapper.dart'; +import 'package:angular2/src/transform/common/formatter.dart' as formatter; +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/common/options_reader.dart'; +import 'package:angular2/src/transform/directive_metadata_linker/transformer.dart'; +import 'package:angular2/src/transform/directive_processor/transformer.dart'; +import 'package:angular2/src/transform/inliner_for_test/transformer.dart'; +import 'package:angular2/src/transform/stylesheet_compiler/transformer.dart'; +import 'package:angular2/src/transform/template_compiler/transformer.dart'; + +export 'package:angular2/src/transform/common/options.dart'; + +/// Generates code to replace mirror use in Angular 2 apps. +/// +/// This transformer can be used along with others as a faster alternative to +/// the single angular2 transformer. +/// +/// See [the wiki][] for details. +/// +/// [the wiki]: https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer +class CodegenTransformer extends TransformerGroup { + CodegenTransformer._(phases, {bool formatCode: false}) : super(phases) { + if (formatCode) { + formatter.init(new DartFormatter()); + } + } + + factory CodegenTransformer(TransformerOptions options) { + var phases; + if (options.inlineViews) { + phases = [ + [new InlinerForTest(options)] + ]; + } else { + phases = [ + [new DirectiveProcessor(options)], + [new DirectiveMetadataLinker()], + [new StylesheetCompiler(), new TemplateCompiler(options),], + ]; + } + if (options.modeName == BarbackMode.RELEASE || !options.lazyTransformers) { + phases = phases + .map((phase) => phase.map((t) => new EagerTransformerWrapper(t))); + } + return new CodegenTransformer._(phases, formatCode: options.formatCode); + } + + factory CodegenTransformer.asPlugin(BarbackSettings settings) { + return new CodegenTransformer(parseBarbackSettings(settings)); + } +} diff --git a/modules_dart/transform/lib/transform/deferred_rewriter.dart b/modules_dart/transform/lib/transform/deferred_rewriter.dart new file mode 100644 index 0000000000..c0f54ed2cb --- /dev/null +++ b/modules_dart/transform/lib/transform/deferred_rewriter.dart @@ -0,0 +1,45 @@ +library angular2.transform.deferred_rewriter.dart; + +import 'dart:async'; + +import 'package:barback/barback.dart'; + +import 'package:angular2/src/transform/deferred_rewriter/transformer.dart' + as base show DeferredRewriter; + +// TODO(kegluneq): Make this a TransformerGroup and add an AggregateTransformer +// that counts the number of transformed files & primary inputs. +// If the number of primary inputs is >> transformed files, output an error +// telling the user to use $include or $exclude in their pubspec. + +/// Rewrites `deferred` imports that need Angular 2 initialization. +/// +/// This transformer can be used along with others as a faster alternative to +/// the single angular2 transformer. +/// +/// See [the wiki][] for details. +/// +/// [the wiki]: https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer +class DeferredRewriter extends Transformer implements DeclaringTransformer { + final base.DeferredRewriter _impl; + + /// Ctor which tells pub that this can be run as a standalone transformer. + DeferredRewriter.asPlugin(BarbackSettings _) + : _impl = new base.DeferredRewriter(); + + /// Signal that we process all .dart files. + /// + /// Instead, use the standard, built-in $exclude and $include transformer + /// parameters to control which files this transformer runs on. + /// See [https://www.dartlang.org/tools/pub/assets-and-transformers.html] for + /// details. + @override + String get allowedExtensions => '.dart'; + + @override + declareOutputs(transform) => _impl.declareOutputs(transform); + + @override + Future apply(transform) => + _impl.applyImpl(transform, transform.primaryInput.id); +} diff --git a/modules_dart/transform/lib/transform/reflection_remover.dart b/modules_dart/transform/lib/transform/reflection_remover.dart new file mode 100644 index 0000000000..ee3ba329c0 --- /dev/null +++ b/modules_dart/transform/lib/transform/reflection_remover.dart @@ -0,0 +1,65 @@ +library angular2.transform.reflection_remover.dart; + +import 'dart:async'; + +import 'package:barback/barback.dart'; + +import 'package:angular2/src/transform/common/options.dart'; +import 'package:angular2/src/transform/common/options_reader.dart'; +import 'package:angular2/src/transform/reflection_remover/transformer.dart' + as base show ReflectionRemover; + +// TODO(kegluneq): Make this a TransformerGroup and add an AggregateTransformer +// that counts the number of transformed files & primary inputs. +// If the number of primary inputs is >> transformed files, output an error +// telling the user to use $include or $exclude in their pubspec. + +/// Removes the transitive dart:mirrors import from Angular 2 entrypoints. +/// +/// This transformer can be used along with others as a faster alternative to +/// the single angular2 transformer. +/// +/// See [the wiki][] for details. +/// +/// [the wiki]: https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer +class ReflectionRemover extends Transformer implements DeclaringTransformer { + final base.ReflectionRemover _impl; + + ReflectionRemover._(this._impl); + + /// Ctor which tells pub that this can be run as a standalone transformer. + factory ReflectionRemover.asPlugin(BarbackSettings settings) { + final options = parseBarbackSettings(settings); + final entryPoints = options.entryPoints; + if (entryPoints != null && entryPoints.isNotEmpty) { + // TODO(kegluneq): Add a goo.gl link with more info. + throw new ArgumentError.value( + entryPoints.join(', '), + ENTRY_POINT_PARAM, + "Do not use '$ENTRY_POINT_PARAM' when specifying the Angular 2 " + "reflection_remover transformer. Instead, use pub's built-in " + r"$include and $exclude parameters to filter which files are " + "processed."); + } + return new ReflectionRemover._(new base.ReflectionRemover(options)); + } + + /// Signal that we process all .dart files. + /// + /// The underlying ReflectionRemover implementation respects the entry_points + /// transformer parameter, but this is inefficient and can be expensive for + /// large numbers of files. + /// + /// Instead, use the standard, built-in $exclude and $include transformer + /// parameters to control which files this transformer runs on. + /// See [https://www.dartlang.org/tools/pub/assets-and-transformers.html] for + /// details. + @override + String get allowedExtensions => '.dart'; + + @override + declareOutputs(transform) => _impl.declareOutputs(transform); + + @override + Future apply(transform) => _impl.apply(transform); +}