Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(538)

Side by Side Diff: sdk/lib/_internal/pub_generated/lib/src/barback/load_all_transformers.dart

Issue 557563002: Store the async-await compiled pub code directly in the repo. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library pub.load_all_transformers; 1 library pub.load_all_transformers;
6
7 import 'dart:async'; 2 import 'dart:async';
8
9 import 'package:barback/barback.dart'; 3 import 'package:barback/barback.dart';
10
11 import '../log.dart' as log; 4 import '../log.dart' as log;
12 import '../package_graph.dart'; 5 import '../package_graph.dart';
13 import '../utils.dart'; 6 import '../utils.dart';
14 import 'asset_environment.dart'; 7 import 'asset_environment.dart';
15 import 'barback_server.dart'; 8 import 'barback_server.dart';
16 import 'dart2js_transformer.dart'; 9 import 'dart2js_transformer.dart';
17 import 'excluding_transformer.dart'; 10 import 'excluding_transformer.dart';
18 import 'rewrite_import_transformer.dart'; 11 import 'rewrite_import_transformer.dart';
19 import 'transformer_config.dart'; 12 import 'transformer_config.dart';
20 import 'transformer_id.dart'; 13 import 'transformer_id.dart';
21 import 'transformer_isolate.dart'; 14 import 'transformer_isolate.dart';
22 import 'transformers_needed_by_transformers.dart'; 15 import 'transformers_needed_by_transformers.dart';
23
24 /// Loads all transformers depended on by packages in [environment].
25 ///
26 /// This uses [environment]'s primary server to serve the Dart files from which
27 /// transformers are loaded, then adds the transformers to
28 /// `environment.barback`.
29 ///
30 /// Any built-in transformers that are provided by the environment will
31 /// automatically be added to the end of the root package's cascade.
32 Future loadAllTransformers(AssetEnvironment environment, 16 Future loadAllTransformers(AssetEnvironment environment,
33 BarbackServer transformerServer) { 17 BarbackServer transformerServer) {
34 var transformersNeededByTransformers = 18 var transformersNeededByTransformers =
35 computeTransformersNeededByTransformers(environment.graph); 19 computeTransformersNeededByTransformers(environment.graph);
36
37 var buffer = new StringBuffer(); 20 var buffer = new StringBuffer();
38 buffer.writeln("Transformer dependencies:"); 21 buffer.writeln("Transformer dependencies:");
39 transformersNeededByTransformers.forEach((id, dependencies) { 22 transformersNeededByTransformers.forEach((id, dependencies) {
40 if (dependencies.isEmpty) { 23 if (dependencies.isEmpty) {
41 buffer.writeln("$id: -"); 24 buffer.writeln("$id: -");
42 } else { 25 } else {
43 buffer.writeln("$id: ${toSentence(dependencies)}"); 26 buffer.writeln("$id: ${toSentence(dependencies)}");
44 } 27 }
45 }); 28 });
46 log.fine(buffer); 29 log.fine(buffer);
47
48 var phasedTransformers = _phaseTransformers(transformersNeededByTransformers); 30 var phasedTransformers = _phaseTransformers(transformersNeededByTransformers);
49
50 var packagesThatUseTransformers = 31 var packagesThatUseTransformers =
51 _packagesThatUseTransformers(environment.graph); 32 _packagesThatUseTransformers(environment.graph);
52
53 var loader = new _TransformerLoader(environment, transformerServer); 33 var loader = new _TransformerLoader(environment, transformerServer);
54
55 // Add a rewrite transformer for each package, so that we can resolve
56 // "package:" imports while loading transformers.
57 var rewrite = new RewriteImportTransformer(); 34 var rewrite = new RewriteImportTransformer();
58 for (var package in environment.packages) { 35 for (var package in environment.packages) {
59 environment.barback.updateTransformers(package, [[rewrite]]); 36 environment.barback.updateTransformers(package, [[rewrite]]);
60 } 37 }
61 environment.barback.updateTransformers(r'$pub', [[rewrite]]); 38 environment.barback.updateTransformers(r'$pub', [[rewrite]]);
62
63 return Future.forEach(phasedTransformers, (phase) { 39 return Future.forEach(phasedTransformers, (phase) {
64 /// Load all the transformers in [phase], then add them to the appropriate
65 /// locations in the transformer graphs of the packages that use them.
66 return loader.load(phase).then((_) { 40 return loader.load(phase).then((_) {
67 // Only update packages that use transformers in [phase]. 41 var packagesToUpdate =
68 var packagesToUpdate = unionAll(phase.map((id) => 42 unionAll(phase.map((id) => packagesThatUseTransformers[id]));
69 packagesThatUseTransformers[id]));
70 return Future.wait(packagesToUpdate.map((packageName) { 43 return Future.wait(packagesToUpdate.map((packageName) {
71 var package = environment.graph.packages[packageName]; 44 var package = environment.graph.packages[packageName];
72 return loader.transformersForPhases(package.pubspec.transformers) 45 return loader.transformersForPhases(
73 .then((phases) { 46 package.pubspec.transformers).then((phases) {
74
75 // Make sure [rewrite] is still the first phase so that future
76 // transformers' "package:" imports will work.
77 phases.insert(0, new Set.from([rewrite])); 47 phases.insert(0, new Set.from([rewrite]));
78 environment.barback.updateTransformers(packageName, phases); 48 environment.barback.updateTransformers(packageName, phases);
79 }); 49 });
80 })); 50 }));
81 }); 51 });
82 }).then((_) { 52 }).then((_) {
83 /// Reset the transformers for each package to get rid of [rewrite], which
84 /// is no longer needed.
85 return Future.wait(environment.graph.packages.values.map((package) { 53 return Future.wait(environment.graph.packages.values.map((package) {
86 return loader.transformersForPhases(package.pubspec.transformers) 54 return loader.transformersForPhases(
87 .then((phases) { 55 package.pubspec.transformers).then((phases) {
88 var transformers = environment.getBuiltInTransformers(package); 56 var transformers = environment.getBuiltInTransformers(package);
89 if (transformers != null) phases.add(transformers); 57 if (transformers != null) phases.add(transformers);
90 58 newFuture(
91 // TODO(nweiz): remove the [newFuture] here when issue 17305 is fixed. 59 () => environment.barback.updateTransformers(package.name, phases));
92 // If no transformer in [phases] applies to a source input,
93 // [updateTransformers] may cause a [BuildResult] to be scheduled for
94 // immediate emission. Issue 17305 means that the caller will be unable
95 // to receive this result unless we delay the update to after this
96 // function returns.
97 newFuture(() =>
98 environment.barback.updateTransformers(package.name, phases));
99 }); 60 });
100 })); 61 }));
101 }); 62 });
102 } 63 }
103 64 List<Set<TransformerId>> _phaseTransformers(Map<TransformerId,
104 /// Given [transformerDependencies], a directed acyclic graph, returns a list of 65 Set<TransformerId>> transformerDependencies) {
105 /// "phases" (sets of transformers).
106 ///
107 /// Each phase must be fully loaded and passed to barback before the next phase
108 /// can be safely loaded. However, transformers within a phase can be safely
109 /// loaded in parallel.
110 List<Set<TransformerId>> _phaseTransformers(
111 Map<TransformerId, Set<TransformerId>> transformerDependencies) {
112 // A map from transformer ids to the indices of the phases that those
113 // transformer ids should end up in. Populated by [phaseNumberFor].
114 var phaseNumbers = {}; 66 var phaseNumbers = {};
115 var phases = []; 67 var phases = [];
116
117 phaseNumberFor(id) { 68 phaseNumberFor(id) {
118 if (phaseNumbers.containsKey(id)) return phaseNumbers[id]; 69 if (phaseNumbers.containsKey(id)) return phaseNumbers[id];
119 var dependencies = transformerDependencies[id]; 70 var dependencies = transformerDependencies[id];
120 phaseNumbers[id] = dependencies.isEmpty ? 0 : 71 phaseNumbers[id] =
121 maxAll(dependencies.map(phaseNumberFor)) + 1; 72 dependencies.isEmpty ? 0 : maxAll(dependencies.map(phaseNumberFor)) + 1;
122 return phaseNumbers[id]; 73 return phaseNumbers[id];
123 } 74 }
124
125 for (var id in transformerDependencies.keys) { 75 for (var id in transformerDependencies.keys) {
126 var phaseNumber = phaseNumberFor(id); 76 var phaseNumber = phaseNumberFor(id);
127 if (phases.length <= phaseNumber) phases.length = phaseNumber + 1; 77 if (phases.length <= phaseNumber) phases.length = phaseNumber + 1;
128 if (phases[phaseNumber] == null) phases[phaseNumber] = new Set(); 78 if (phases[phaseNumber] == null) phases[phaseNumber] = new Set();
129 phases[phaseNumber].add(id); 79 phases[phaseNumber].add(id);
130 } 80 }
131
132 return phases; 81 return phases;
133 } 82 }
134 83 Map<TransformerId, Set<String>> _packagesThatUseTransformers(PackageGraph graph)
135 /// Returns a map from transformer ids to all packages in [graph] that use each 84 {
136 /// transformer.
137 Map<TransformerId, Set<String>> _packagesThatUseTransformers(
138 PackageGraph graph) {
139 var results = {}; 85 var results = {};
140 for (var package in graph.packages.values) { 86 for (var package in graph.packages.values) {
141 for (var phase in package.pubspec.transformers) { 87 for (var phase in package.pubspec.transformers) {
142 for (var config in phase) { 88 for (var config in phase) {
143 results.putIfAbsent(config.id, () => new Set()).add(package.name); 89 results.putIfAbsent(config.id, () => new Set()).add(package.name);
144 } 90 }
145 } 91 }
146 } 92 }
147 return results; 93 return results;
148 } 94 }
149
150 /// A class that loads transformers defined in specific files.
151 class _TransformerLoader { 95 class _TransformerLoader {
152 final AssetEnvironment _environment; 96 final AssetEnvironment _environment;
153
154 final BarbackServer _transformerServer; 97 final BarbackServer _transformerServer;
155
156 final _isolates = new Map<TransformerId, TransformerIsolate>(); 98 final _isolates = new Map<TransformerId, TransformerIsolate>();
157
158 final _transformers = new Map<TransformerConfig, Set<Transformer>>(); 99 final _transformers = new Map<TransformerConfig, Set<Transformer>>();
159
160 /// The packages that use each transformer id.
161 ///
162 /// Used for error reporting.
163 final _transformerUsers = new Map<TransformerId, Set<String>>(); 100 final _transformerUsers = new Map<TransformerId, Set<String>>();
164
165 _TransformerLoader(this._environment, this._transformerServer) { 101 _TransformerLoader(this._environment, this._transformerServer) {
166 for (var package in _environment.graph.packages.values) { 102 for (var package in _environment.graph.packages.values) {
167 for (var config in unionAll(package.pubspec.transformers)) { 103 for (var config in unionAll(package.pubspec.transformers)) {
168 _transformerUsers.putIfAbsent(config.id, () => new Set<String>()) 104 _transformerUsers.putIfAbsent(
169 .add(package.name); 105 config.id,
106 () => new Set<String>()).add(package.name);
170 } 107 }
171 } 108 }
172 } 109 }
173
174 /// Loads a transformer plugin isolate that imports the transformer libraries
175 /// indicated by [ids].
176 ///
177 /// Once the returned future completes, transformer instances from this
178 /// isolate can be created using [transformersFor] or [transformersForPhase].
179 ///
180 /// This will skip any ids that have already been loaded.
181 Future load(Iterable<TransformerId> ids) { 110 Future load(Iterable<TransformerId> ids) {
182 ids = ids.where((id) => !_isolates.containsKey(id)).toList(); 111 ids = ids.where((id) => !_isolates.containsKey(id)).toList();
183 if (ids.isEmpty) return new Future.value(); 112 if (ids.isEmpty) return new Future.value();
184
185 return log.progress("Loading ${toSentence(ids)} transformers", () { 113 return log.progress("Loading ${toSentence(ids)} transformers", () {
186 return TransformerIsolate.spawn(_environment, _transformerServer, ids); 114 return TransformerIsolate.spawn(_environment, _transformerServer, ids);
187 }).then((isolate) { 115 }).then((isolate) {
188 for (var id in ids) { 116 for (var id in ids) {
189 _isolates[id] = isolate; 117 _isolates[id] = isolate;
190 } 118 }
191 }); 119 });
192 } 120 }
193
194 /// Instantiates and returns all transformers in the library indicated by
195 /// [config] with the given configuration.
196 ///
197 /// If this is called before the library has been loaded into an isolate via
198 /// [load], it will return an empty set.
199 Future<Set<Transformer>> transformersFor(TransformerConfig config) { 121 Future<Set<Transformer>> transformersFor(TransformerConfig config) {
200 if (_transformers.containsKey(config)) { 122 if (_transformers.containsKey(config)) {
201 return new Future.value(_transformers[config]); 123 return new Future.value(_transformers[config]);
202 } else if (_isolates.containsKey(config.id)) { 124 } else if (_isolates.containsKey(config.id)) {
203 return _isolates[config.id].create(config).then((transformers) { 125 return _isolates[config.id].create(config).then((transformers) {
204 if (transformers.isNotEmpty) { 126 if (transformers.isNotEmpty) {
205 _transformers[config] = transformers; 127 _transformers[config] = transformers;
206 return transformers; 128 return transformers;
207 } 129 }
208
209 var message = "No transformers"; 130 var message = "No transformers";
210 if (config.configuration.isNotEmpty) { 131 if (config.configuration.isNotEmpty) {
211 message += " that accept configuration"; 132 message += " that accept configuration";
212 } 133 }
213
214 var location; 134 var location;
215 if (config.id.path == null) { 135 if (config.id.path == null) {
216 location = 'package:${config.id.package}/transformer.dart or ' 136 location =
217 'package:${config.id.package}/${config.id.package}.dart'; 137 'package:${config.id.package}/transformer.dart or '
138 'package:${config.id.package}/${config.id.package}.dart';
218 } else { 139 } else {
219 location = 'package:$config.dart'; 140 location = 'package:$config.dart';
220 } 141 }
221
222 var users = toSentence(ordered(_transformerUsers[config.id])); 142 var users = toSentence(ordered(_transformerUsers[config.id]));
223 fail("$message were defined in $location,\n" 143 fail("$message were defined in $location,\n" "required by $users.");
224 "required by $users.");
225 }); 144 });
226 } else if (config.id.package != '\$dart2js') { 145 } else if (config.id.package != '\$dart2js') {
227 return new Future.value(new Set()); 146 return new Future.value(new Set());
228 } 147 }
229
230 var transformer; 148 var transformer;
231 try { 149 try {
232 transformer = new Dart2JSTransformer.withSettings(_environment, 150 transformer = new Dart2JSTransformer.withSettings(
151 _environment,
233 new BarbackSettings(config.configuration, _environment.mode)); 152 new BarbackSettings(config.configuration, _environment.mode));
234 } on FormatException catch (error, stackTrace) { 153 } on FormatException catch (error, stackTrace) {
235 fail(error.message, error, stackTrace); 154 fail(error.message, error, stackTrace);
236 } 155 }
237 156 _transformers[config] =
238 // Handle any exclusions. 157 new Set.from([ExcludingTransformer.wrap(transformer, config)]);
239 _transformers[config] = new Set.from(
240 [ExcludingTransformer.wrap(transformer, config)]);
241 return new Future.value(_transformers[config]); 158 return new Future.value(_transformers[config]);
242 } 159 }
243 160 Future<List<Set<Transformer>>>
244 /// Loads all transformers defined in each phase of [phases]. 161 transformersForPhases(Iterable<Set<TransformerConfig>> phases) {
245 ///
246 /// If any library hasn't yet been loaded via [load], it will be ignored.
247 Future<List<Set<Transformer>>> transformersForPhases(
248 Iterable<Set<TransformerConfig>> phases) {
249 return Future.wait(phases.map((phase) { 162 return Future.wait(phases.map((phase) {
250 return waitAndPrintErrors(phase.map(transformersFor)).then(unionAll); 163 return waitAndPrintErrors(phase.map(transformersFor)).then(unionAll);
251 })).then((phases) { 164 })).then((phases) {
252 // Return a growable list so that callers can add phases.
253 return phases.toList(); 165 return phases.toList();
254 }); 166 });
255 } 167 }
256 } 168 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698