diff --git a/modules_dart/transform/lib/src/transform/common/eager_transformer_wrapper.dart b/modules_dart/transform/lib/src/transform/common/eager_transformer_wrapper.dart new file mode 100644 index 0000000000..96b7d17590 --- /dev/null +++ b/modules_dart/transform/lib/src/transform/common/eager_transformer_wrapper.dart @@ -0,0 +1,45 @@ +library angular2.src.transform.common.eager_transformer_wrapper; + +import 'package:barback/barback.dart'; + +abstract class EagerTransformerWrapper { + EagerTransformerWrapper._(); + factory EagerTransformerWrapper(wrapped) { + return wrapped is AggregateTransformer + ? new _EagerAggregateTransformerWrapper(wrapped) + : new _EagerTransformerWrapper(wrapped); + } +} + +class _EagerTransformerWrapper extends EagerTransformerWrapper + implements Transformer { + final Transformer _wrapped; + _EagerTransformerWrapper(this._wrapped) : super._(); + + @override + String get allowedExtensions => _wrapped.allowedExtensions; + + @override + apply(Transform transform) => _wrapped.apply(transform); + + @override + isPrimary(AssetId id) => _wrapped.isPrimary(id); + + @override + toString() => _wrapped.toString(); +} + +class _EagerAggregateTransformerWrapper extends EagerTransformerWrapper + implements AggregateTransformer { + final AggregateTransformer _wrapped; + _EagerAggregateTransformerWrapper(this._wrapped) : super._(); + + @override + apply(AggregateTransform transform) => _wrapped.apply(transform); + + @override + classifyPrimary(AssetId id) => _wrapped.classifyPrimary(id); + + @override + toString() => _wrapped.toString(); +} diff --git a/modules_dart/transform/lib/src/transform/common/options.dart b/modules_dart/transform/lib/src/transform/common/options.dart index f4c6ef8b08..f5d1e5038d 100644 --- a/modules_dart/transform/lib/src/transform/common/options.dart +++ b/modules_dart/transform/lib/src/transform/common/options.dart @@ -15,6 +15,7 @@ const PLATFORM_DIRECTIVES = 'platform_directives'; const INIT_REFLECTOR_PARAM = 'init_reflector'; const INLINE_VIEWS_PARAM = 'inline_views'; const MIRROR_MODE_PARAM = 'mirror_mode'; +const LAZY_TRANSFORMERS = 'lazy_transformers'; /// Provides information necessary to transform an Angular2 app. class TransformerOptions { @@ -56,6 +57,13 @@ class TransformerOptions { /// at any time. final bool inlineViews; + /// Whether to make transformers lazy. + /// If this is `true`, and in `debug` mode only, the transformers will be + /// lazy (will only build assets that are requested). + /// This is undocumented, for testing purposes only, and may change or break + /// at any time. + final bool lazyTransformers; + TransformerOptions._internal( this.entryPoints, this.entryPointGlobs, @@ -66,6 +74,7 @@ class TransformerOptions { {this.reflectPropertiesAsAttributes, this.platformDirectives, this.inlineViews, + this.lazyTransformers, this.formatCode}); factory TransformerOptions(List entryPoints, @@ -76,6 +85,7 @@ class TransformerOptions { bool inlineViews: false, bool reflectPropertiesAsAttributes: true, List platformDirectives, + bool lazyTransformers: false, bool formatCode: false}) { var annotationMatcher = new AnnotationMatcher() ..addAll(customAnnotationDescriptors); @@ -87,6 +97,7 @@ class TransformerOptions { reflectPropertiesAsAttributes: reflectPropertiesAsAttributes, platformDirectives: platformDirectives, inlineViews: inlineViews, + lazyTransformers: lazyTransformers, formatCode: formatCode); } } diff --git a/modules_dart/transform/lib/src/transform/common/options_reader.dart b/modules_dart/transform/lib/src/transform/common/options_reader.dart index 140431f2eb..18d8566a4a 100644 --- a/modules_dart/transform/lib/src/transform/common/options_reader.dart +++ b/modules_dart/transform/lib/src/transform/common/options_reader.dart @@ -42,6 +42,8 @@ TransformerOptions parseBarbackSettings(BarbackSettings settings) { reflectPropertiesAsAttributes: reflectPropertiesAsAttributes, platformDirectives: platformDirectives, inlineViews: _readBool(config, INLINE_VIEWS_PARAM, defaultValue: false), + lazyTransformers: + _readBool(config, LAZY_TRANSFORMERS, defaultValue: false), formatCode: formatCode); } 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 c5dc4fb725..8d1c0d844a 100644 --- a/modules_dart/transform/lib/src/transform/deferred_rewriter/transformer.dart +++ b/modules_dart/transform/lib/src/transform/deferred_rewriter/transformer.dart @@ -14,11 +14,16 @@ 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. -class DeferredRewriter extends Transformer { +class DeferredRewriter extends Transformer implements LazyTransformer { final TransformerOptions options; DeferredRewriter(this.options); + @override + declareOutputs(DeclaringTransform transform) { + transform.declareOutput(transform.primaryId); + } + @override bool isPrimary(AssetId id) => id.extension.endsWith('dart') && _isNotGenerated(id); 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 5270d588f1..6483ac23ed 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 @@ -30,12 +30,17 @@ import 'ng_meta_linker.dart'; /// /// This transformer is part of a multi-phase transform. /// See `angular2/src/transform/transformer.dart` for transformer ordering. -class DirectiveMetadataLinker extends Transformer { +class DirectiveMetadataLinker extends Transformer implements LazyTransformer { final _encoder = const JsonEncoder.withIndent(' '); @override bool isPrimary(AssetId id) => id.path.endsWith(SUMMARY_META_EXTENSION); + @override + declareOutputs(DeclaringTransform transform) { + transform.declareOutput(_ngLinkedAssetId(transform.primaryId)); + } + @override Future apply(Transform transform) { return zone.exec(() { @@ -45,13 +50,9 @@ class DirectiveMetadataLinker extends Transformer { new AssetReader.fromTransform(transform), primaryId).then((ngMeta) { if (ngMeta != null) { final outputId = _ngLinkedAssetId(primaryId); - if (!ngMeta.isEmpty) { - transform.addOutput(new Asset.fromString( - outputId, _encoder.convert(ngMeta.toJson()))); - } else { - // Not outputting an asset could confuse barback. - transform.addOutput(new Asset.fromString(outputId, '')); - } + // Not outputting an asset could confuse barback. + var output = ngMeta.isEmpty ? '' : _encoder.convert(ngMeta.toJson()); + transform.addOutput(new Asset.fromString(outputId, output)); } }); }, log: transform.logger); 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 de31b4ea24..d934d493af 100644 --- a/modules_dart/transform/lib/src/transform/directive_processor/transformer.dart +++ b/modules_dart/transform/lib/src/transform/directive_processor/transformer.dart @@ -21,7 +21,7 @@ import 'rewriter.dart'; /// /// This transformer is part of a multi-phase transform. /// See `angular2/src/transform/transformer.dart` for transformer ordering. -class DirectiveProcessor extends Transformer { +class DirectiveProcessor extends Transformer implements LazyTransformer { final TransformerOptions options; final _encoder = const JsonEncoder.withIndent(' '); @@ -30,6 +30,11 @@ class DirectiveProcessor extends Transformer { @override bool isPrimary(AssetId id) => id.extension.endsWith('dart'); + @override + declareOutputs(DeclaringTransform transform) { + transform.declareOutput(_ngSummaryAssetId(transform.primaryId)); + } + @override Future apply(Transform transform) async { Html5LibDomAdapter.makeCurrent(); 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 2cde0b7e51..dc24d34eb6 100644 --- a/modules_dart/transform/lib/src/transform/reflection_remover/transformer.dart +++ b/modules_dart/transform/lib/src/transform/reflection_remover/transformer.dart @@ -21,7 +21,7 @@ import 'remove_reflection_capabilities.dart'; /// have already been run and that a .ng_deps.dart file has been generated for /// {@link options.entryPoint}. The instantiation of {@link ReflectionCapabilities} is /// replaced by calling `setupReflection` in that .ng_deps.dart file. -class ReflectionRemover extends Transformer { +class ReflectionRemover extends Transformer implements LazyTransformer { final TransformerOptions options; ReflectionRemover(this.options); @@ -30,6 +30,11 @@ class ReflectionRemover extends Transformer { bool isPrimary(AssetId id) => options.entryPointGlobs != null && options.entryPointGlobs.any((g) => g.matches(id.path)); + @override + declareOutputs(DeclaringTransform transform) { + transform.declareOutput(transform.primaryId); + } + @override Future apply(Transform transform) async { return zone.exec(() async { diff --git a/modules_dart/transform/lib/src/transform/stylesheet_compiler/transformer.dart b/modules_dart/transform/lib/src/transform/stylesheet_compiler/transformer.dart index ec52a41bd0..541f35dc9f 100644 --- a/modules_dart/transform/lib/src/transform/stylesheet_compiler/transformer.dart +++ b/modules_dart/transform/lib/src/transform/stylesheet_compiler/transformer.dart @@ -12,7 +12,7 @@ import 'package:angular2/src/transform/common/zone.dart' as zone; import 'processor.dart'; /// Pre-compiles CSS stylesheet files to Dart code for Angular 2. -class StylesheetCompiler extends Transformer { +class StylesheetCompiler extends Transformer implements LazyTransformer { StylesheetCompiler(); @override @@ -20,13 +20,29 @@ class StylesheetCompiler extends Transformer { return id.path.endsWith(CSS_EXTENSION); } + @override + declareOutputs(DeclaringTransform transform) { + // Note: we check this assumption below. + _getExpectedOutputs(transform.primaryId).forEach(transform.declareOutput); + } + + List _getExpectedOutputs(AssetId cssId) => + [shimmedStylesheetAssetId(cssId), nonShimmedStylesheetAssetId(cssId)]; + @override Future apply(Transform transform) async { final reader = new AssetReader.fromTransform(transform); return zone.exec(() async { Html5LibDomAdapter.makeCurrent(); - var outputs = await processStylesheet(reader, transform.primaryInput.id); + var primaryId = transform.primaryInput.id; + var outputs = await processStylesheet(reader, primaryId); + var expectedIds = _getExpectedOutputs(primaryId); outputs.forEach((Asset compiledStylesheet) { + var id = compiledStylesheet.id; + if (!expectedIds.contains(id)) { + throw new StateError( + 'Unexpected output for css processing of $primaryId: $id'); + } transform.addOutput(compiledStylesheet); }); }, log: transform.logger); 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 b2ee438233..b5069918c0 100644 --- a/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart +++ b/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart @@ -23,7 +23,7 @@ import 'generator.dart'; /// /// This transformer is part of a multi-phase transform. /// See `angular2/src/transform/transformer.dart` for transformer ordering. -class TemplateCompiler extends Transformer { +class TemplateCompiler extends Transformer implements LazyTransformer { final TransformerOptions options; TemplateCompiler(this.options); @@ -31,6 +31,12 @@ class TemplateCompiler extends Transformer { @override bool isPrimary(AssetId id) => id.path.endsWith(META_EXTENSION); + @override + declareOutputs(DeclaringTransform transform) { + transform.declareOutput(ngDepsAssetId(transform.primaryId)); + transform.declareOutput(templatesAssetId(transform.primaryId)); + } + @override Future apply(Transform transform) async { return zone.exec(() async { diff --git a/modules_dart/transform/lib/src/transform/transformer.dart b/modules_dart/transform/lib/src/transform/transformer.dart index a23d168677..4843c0075d 100644 --- a/modules_dart/transform/lib/src/transform/transformer.dart +++ b/modules_dart/transform/lib/src/transform/transformer.dart @@ -3,6 +3,7 @@ library angular2.src.transform.transformer; import 'package:barback/barback.dart'; import 'package:dart_style/dart_style.dart'; +import 'common/eager_transformer_wrapper.dart'; import 'common/formatter.dart' as formatter; import 'common/options.dart'; import 'common/options_reader.dart'; @@ -42,6 +43,10 @@ class AngularTransformerGroup extends TransformerGroup { ], ]; } + if (options.modeName == BarbackMode.RELEASE || !options.lazyTransformers) { + phases = phases + .map((phase) => phase.map((t) => new EagerTransformerWrapper(t))); + } return new AngularTransformerGroup._(phases, formatCode: options.formatCode); }