Chromium Code Reviews| Index: sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart |
| diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart |
| index 18bf853d4262d8f5e6644cfd32df034ab2f914b1..97f4754c2f6777edad64fa20198c947f6f08bbe8 100644 |
| --- a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart |
| +++ b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart |
| @@ -6,19 +6,15 @@ library pub.load_all_transformers; |
| import 'dart:async'; |
| -import 'package:barback/barback.dart'; |
| - |
| import '../log.dart' as log; |
| import '../package_graph.dart'; |
| import '../utils.dart'; |
| import 'asset_environment.dart'; |
| import 'barback_server.dart'; |
| -import 'dart2js_transformer.dart'; |
| -import 'excluding_transformer.dart'; |
| import 'rewrite_import_transformer.dart'; |
| -import 'transformer_config.dart'; |
| +import 'transformer_cache.dart'; |
| import 'transformer_id.dart'; |
| -import 'transformer_isolate.dart'; |
| +import 'transformer_loader.dart'; |
| import 'transformers_needed_by_transformers.dart'; |
| /// Loads all transformers depended on by packages in [environment]. |
| @@ -30,7 +26,7 @@ import 'transformers_needed_by_transformers.dart'; |
| /// Any built-in transformers that are provided by the environment will |
| /// automatically be added to the end of the root package's cascade. |
| Future loadAllTransformers(AssetEnvironment environment, |
| - BarbackServer transformerServer) { |
| + BarbackServer transformerServer) async { |
| var transformersNeededByTransformers = |
| computeTransformersNeededByTransformers(environment.graph); |
| @@ -50,7 +46,7 @@ Future loadAllTransformers(AssetEnvironment environment, |
| var packagesThatUseTransformers = |
| _packagesThatUseTransformers(environment.graph); |
| - var loader = new _TransformerLoader(environment, transformerServer); |
| + var loader = new TransformerLoader(environment, transformerServer); |
| // Add a rewrite transformer for each package, so that we can resolve |
| // "package:" imports while loading transformers. |
| @@ -60,45 +56,56 @@ Future loadAllTransformers(AssetEnvironment environment, |
| } |
| environment.barback.updateTransformers(r'$pub', [[rewrite]]); |
| - return Future.forEach(phasedTransformers, (phase) { |
| - /// Load all the transformers in [phase], then add them to the appropriate |
| - /// locations in the transformer graphs of the packages that use them. |
| - return loader.load(phase).then((_) { |
| - // Only update packages that use transformers in [phase]. |
| - var packagesToUpdate = unionAll(phase.map((id) => |
| - packagesThatUseTransformers[id])); |
| - return Future.wait(packagesToUpdate.map((packageName) { |
| - var package = environment.graph.packages[packageName]; |
| - return loader.transformersForPhases(package.pubspec.transformers) |
| - .then((phases) { |
| + // Only save compiled snapshots when a physical entrypoint package is being |
| + // used. There's no physical entrypoint when e.g. globally activating a cached |
| + // package. |
| + var cache = environment.rootPackage.dir == null ? null : |
| + environment.graph.loadTransformerCache(); |
| - // Make sure [rewrite] is still the first phase so that future |
| - // transformers' "package:" imports will work. |
| - phases.insert(0, new Set.from([rewrite])); |
| - environment.barback.updateTransformers(packageName, phases); |
| - }); |
| - })); |
| - }); |
| - }).then((_) { |
| - /// Reset the transformers for each package to get rid of [rewrite], which |
| - /// is no longer needed. |
| - return Future.wait(environment.graph.packages.values.map((package) { |
| - return loader.transformersForPhases(package.pubspec.transformers) |
| - .then((phases) { |
| - var transformers = environment.getBuiltInTransformers(package); |
| - if (transformers != null) phases.add(transformers); |
| + var first = true; |
| + for (var phase in phasedTransformers) { |
| + var snapshotPath = cache == null || !first ? null : |
|
Bob Nystrom
2014/09/12 21:17:17
Document why we're only doing this for the first p
nweiz
2014/09/16 00:10:53
Done.
|
| + cache.snapshotPath(phase); |
| + first = false; |
| - // TODO(nweiz): remove the [newFuture] here when issue 17305 is fixed. |
| - // If no transformer in [phases] applies to a source input, |
| - // [updateTransformers] may cause a [BuildResult] to be scheduled for |
| - // immediate emission. Issue 17305 means that the caller will be unable |
| - // to receive this result unless we delay the update to after this |
| - // function returns. |
| - newFuture(() => |
| - environment.barback.updateTransformers(package.name, phases)); |
| - }); |
| + /// Load all the transformers in [phase], then add them to the appropriate |
| + /// locations in the transformer graphs of the packages that use them. |
| + await loader.load(phase, snapshot: snapshotPath); |
| + |
| + // Only update packages that use transformers in [phase]. |
| + var packagesToUpdate = unionAll(phase.map((id) => |
| + packagesThatUseTransformers[id])); |
| + await Future.wait(packagesToUpdate.map((packageName) async { |
| + var package = environment.graph.packages[packageName]; |
| + var phases = await loader.transformersForPhases( |
| + package.pubspec.transformers); |
| + |
| + // Make sure [rewrite] is still the first phase so that future |
| + // transformers' "package:" imports will work. |
| + phases.insert(0, new Set.from([rewrite])); |
| + environment.barback.updateTransformers(packageName, phases); |
| })); |
| - }); |
| + } |
| + |
| + cache.save(); |
| + |
| + /// Reset the transformers for each package to get rid of [rewrite], which |
| + /// is no longer needed. |
| + await Future.wait(environment.graph.packages.values.map((package) async { |
| + var phases = await loader.transformersForPhases( |
| + package.pubspec.transformers); |
| + var transformers = environment.getBuiltInTransformers(package); |
| + if (transformers != null) phases.add(transformers); |
| + |
| + // TODO(nweiz): remove the [newFuture] here when issue 17305 is fixed. |
| + // If no transformer in [phases] applies to a source input, |
| + // [updateTransformers] may cause a [BuildResult] to be scheduled for |
| + // immediate emission. Issue 17305 means that the caller will be unable |
| + // to receive this result unless we delay the update to after this |
| + // function returns. |
| + newFuture(() => |
| + environment.barback.updateTransformers(package.name, phases)); |
| + })); |
| } |
| /// Given [transformerDependencies], a directed acyclic graph, returns a list of |
| @@ -146,111 +153,3 @@ Map<TransformerId, Set<String>> _packagesThatUseTransformers( |
| } |
| return results; |
| } |
| - |
| -/// A class that loads transformers defined in specific files. |
| -class _TransformerLoader { |
| - final AssetEnvironment _environment; |
| - |
| - final BarbackServer _transformerServer; |
| - |
| - final _isolates = new Map<TransformerId, TransformerIsolate>(); |
| - |
| - final _transformers = new Map<TransformerConfig, Set<Transformer>>(); |
| - |
| - /// The packages that use each transformer id. |
| - /// |
| - /// Used for error reporting. |
| - final _transformerUsers = new Map<TransformerId, Set<String>>(); |
| - |
| - _TransformerLoader(this._environment, this._transformerServer) { |
| - for (var package in _environment.graph.packages.values) { |
| - for (var config in unionAll(package.pubspec.transformers)) { |
| - _transformerUsers.putIfAbsent(config.id, () => new Set<String>()) |
| - .add(package.name); |
| - } |
| - } |
| - } |
| - |
| - /// Loads a transformer plugin isolate that imports the transformer libraries |
| - /// indicated by [ids]. |
| - /// |
| - /// Once the returned future completes, transformer instances from this |
| - /// isolate can be created using [transformersFor] or [transformersForPhase]. |
| - /// |
| - /// This will skip any ids that have already been loaded. |
| - Future load(Iterable<TransformerId> ids) { |
| - ids = ids.where((id) => !_isolates.containsKey(id)).toList(); |
| - if (ids.isEmpty) return new Future.value(); |
| - |
| - return log.progress("Loading ${toSentence(ids)} transformers", () { |
| - return TransformerIsolate.spawn(_environment, _transformerServer, ids); |
| - }).then((isolate) { |
| - for (var id in ids) { |
| - _isolates[id] = isolate; |
| - } |
| - }); |
| - } |
| - |
| - /// Instantiates and returns all transformers in the library indicated by |
| - /// [config] with the given configuration. |
| - /// |
| - /// If this is called before the library has been loaded into an isolate via |
| - /// [load], it will return an empty set. |
| - Future<Set<Transformer>> transformersFor(TransformerConfig config) { |
| - if (_transformers.containsKey(config)) { |
| - return new Future.value(_transformers[config]); |
| - } else if (_isolates.containsKey(config.id)) { |
| - return _isolates[config.id].create(config).then((transformers) { |
| - if (transformers.isNotEmpty) { |
| - _transformers[config] = transformers; |
| - return transformers; |
| - } |
| - |
| - var message = "No transformers"; |
| - if (config.configuration.isNotEmpty) { |
| - message += " that accept configuration"; |
| - } |
| - |
| - var location; |
| - if (config.id.path == null) { |
| - location = 'package:${config.id.package}/transformer.dart or ' |
| - 'package:${config.id.package}/${config.id.package}.dart'; |
| - } else { |
| - location = 'package:$config.dart'; |
| - } |
| - |
| - var users = toSentence(ordered(_transformerUsers[config.id])); |
| - fail("$message were defined in $location,\n" |
| - "required by $users."); |
| - }); |
| - } else if (config.id.package != '\$dart2js') { |
| - return new Future.value(new Set()); |
| - } |
| - |
| - var transformer; |
| - try { |
| - transformer = new Dart2JSTransformer.withSettings(_environment, |
| - new BarbackSettings(config.configuration, _environment.mode)); |
| - } on FormatException catch (error, stackTrace) { |
| - fail(error.message, error, stackTrace); |
| - } |
| - |
| - // Handle any exclusions. |
| - _transformers[config] = new Set.from( |
| - [ExcludingTransformer.wrap(transformer, config)]); |
| - return new Future.value(_transformers[config]); |
| - } |
| - |
| - /// Loads all transformers defined in each phase of [phases]. |
| - /// |
| - /// If any library hasn't yet been loaded via [load], it will be ignored. |
| - Future<List<Set<Transformer>>> transformersForPhases( |
| - Iterable<Set<TransformerConfig>> phases) { |
| - return Future.wait(phases.map((phase) { |
| - return waitAndPrintErrors(phase.map(transformersFor)).then(unionAll); |
| - })).then((phases) { |
| - // Return a growable list so that callers can add phases. |
| - return phases.toList(); |
| - }); |
| - } |
| -} |