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

Side by Side Diff: sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart

Issue 141113011: Support directories other than "web" in pub build. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revise. Created 6 years, 10 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 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library pub.dart2js_transformer; 5 library pub.dart2js_transformer;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:convert'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 10
11 import 'package:analyzer/analyzer.dart'; 11 import 'package:analyzer/analyzer.dart';
12 import 'package:barback/barback.dart'; 12 import 'package:barback/barback.dart';
13 import 'package:path/path.dart' as path; 13 import 'package:path/path.dart' as path;
14 import 'package:stack_trace/stack_trace.dart'; 14 import 'package:stack_trace/stack_trace.dart';
15 15
16 import '../../../../compiler/compiler.dart' as compiler; 16 import '../../../../compiler/compiler.dart' as compiler;
17 import '../../../../compiler/implementation/dart2js.dart' 17 import '../../../../compiler/implementation/dart2js.dart'
18 show AbortLeg; 18 show AbortLeg;
19 import '../../../../compiler/implementation/source_file.dart'; 19 import '../../../../compiler/implementation/source_file.dart';
20 import '../barback.dart'; 20 import '../barback.dart';
21 import '../dart.dart' as dart; 21 import '../dart.dart' as dart;
22 import '../io.dart'; 22 import '../io.dart';
23 import '../package.dart'; 23 import '../package.dart';
24 import '../package_graph.dart'; 24 import '../package_graph.dart';
25 import '../utils.dart'; 25 import '../utils.dart';
26 import 'build_environment.dart';
26 27
27 /// The set of all valid configuration options for this transformer. 28 /// The set of all valid configuration options for this transformer.
28 final _validOptions = new Set<String>.from([ 29 final _validOptions = new Set<String>.from([
29 'commandLineOptions', 'checked', 'minify', 'verbose', 'environment', 30 'commandLineOptions', 'checked', 'minify', 'verbose', 'environment',
30 'analyzeAll', 'suppressWarnings', 'suppressHints', 'terse' 31 'analyzeAll', 'suppressWarnings', 'suppressHints', 'terse'
31 ]); 32 ]);
32 33
33 /// A [Transformer] that uses dart2js's library API to transform Dart 34 /// A [Transformer] that uses dart2js's library API to transform Dart
34 /// entrypoints in "web" to JavaScript. 35 /// entrypoints in "web" to JavaScript.
35 class Dart2JSTransformer extends Transformer { 36 class Dart2JSTransformer extends Transformer {
36 final PackageGraph _graph; 37 final BuildEnvironment _environment;
37 final BarbackSettings _settings; 38 final BarbackSettings _settings;
38 39
39 /// The [AssetId]s the transformer has discovered so far. Used by pub build
40 /// to determine where to copy the JS bootstrap files.
41 // TODO(rnystrom): Do something cleaner for this, or eliminate those files.
42 final entrypoints = new Set<AssetId>();
43
44 /// If this is non-null, then the transformer is currently being applied, so 40 /// If this is non-null, then the transformer is currently being applied, so
45 /// subsequent calls to [apply] will wait for this to finish before 41 /// subsequent calls to [apply] will wait for this to finish before
46 /// proceeding. 42 /// proceeding.
47 /// 43 ///
48 /// Dart2js uses lots of memory, so if we try to actually run compiles in 44 /// Dart2js uses lots of memory, so if we try to actually run compiles in
49 /// parallel, it takes down the VM. Instead, the transformer will force 45 /// parallel, it takes down the VM. Instead, the transformer will force
50 /// all applies to be sequential. The tracking bug to do something better 46 /// all applies to be sequential. The tracking bug to do something better
51 /// is here: https://code.google.com/p/dart/issues/detail?id=14730. 47 /// is here: https://code.google.com/p/dart/issues/detail?id=14730.
52 Future _running; 48 Future _running;
53 49
54 Dart2JSTransformer.withSettings(this._graph, this._settings) { 50 Dart2JSTransformer.withSettings(this._environment, this._settings) {
55 var invalidOptions = _settings.configuration.keys.toSet() 51 var invalidOptions = _settings.configuration.keys.toSet()
56 .difference(_validOptions); 52 .difference(_validOptions);
57 if (invalidOptions.isEmpty) return; 53 if (invalidOptions.isEmpty) return;
58 54
59 throw new FormatException("Unrecognized dart2js " 55 throw new FormatException("Unrecognized dart2js "
60 "${pluralize('option', invalidOptions.length)} " 56 "${pluralize('option', invalidOptions.length)} "
61 "${toSentence(invalidOptions.map((option) => '"$option"'))}."); 57 "${toSentence(invalidOptions.map((option) => '"$option"'))}.");
62 } 58 }
63 59
64 Dart2JSTransformer(PackageGraph graph, BarbackMode mode) 60 Dart2JSTransformer(BuildEnvironment environment, BarbackMode mode)
65 : this.withSettings(graph, new BarbackSettings({}, mode)); 61 : this.withSettings(environment, new BarbackSettings({}, mode));
66 62
67 /// Only ".dart" files within "web/" are processed. 63 /// Only ".dart" files within a buildable directory are processed.
68 Future<bool> isPrimary(Asset asset) { 64 Future<bool> isPrimary(Asset asset) {
69 return new Future.value( 65 if (asset.id.extension != ".dart") return new Future.value(false);
70 asset.id.extension == ".dart" && 66
71 asset.id.path.startsWith("web/")); 67 for (var dir in ["benchmark", "example", "test", "web"]) {
68 if (asset.id.path.startsWith("$dir/")) return new Future.value(true);
69 }
70
71 return new Future.value(false);
72 } 72 }
73 73
74 Future apply(Transform transform) { 74 Future apply(Transform transform) {
75 // Wait for any ongoing apply to finish first. 75 // Wait for any ongoing apply to finish first.
76 // TODO(rnystrom): If there are multiple simultaneous compiles, this will 76 // TODO(rnystrom): If there are multiple simultaneous compiles, this will
77 // resume and pause them repeatedly. It still serializes them correctly, 77 // resume and pause them repeatedly. It still serializes them correctly,
78 // but it might be cleaner to use a real queue. 78 // but it might be cleaner to use a real queue.
79 // TODO(rnystrom): Add a test that this is functionality is helpful. 79 // TODO(rnystrom): Add a test that this is functionality is helpful.
80 if (_running != null) { 80 if (_running != null) {
81 return _running.then((_) => apply(transform)); 81 return _running.then((_) => apply(transform));
82 } 82 }
83 83
84 var completer = new Completer(); 84 var completer = new Completer();
85 _running = completer.future; 85 _running = completer.future;
86 86
87 var stopwatch = new Stopwatch(); 87 var stopwatch = new Stopwatch();
88 stopwatch.start(); 88 stopwatch.start();
89 89
90 return transform.primaryInput.readAsString().then((code) { 90 return transform.primaryInput.readAsString().then((code) {
91 try { 91 try {
92 var id = transform.primaryInput.id; 92 var id = transform.primaryInput.id;
93 var name = id.path; 93 var name = id.path;
94 if (id.package != _graph.entrypoint.root.name) { 94 if (id.package != _environment.rootPackage.name) {
95 name += " in ${id.package}"; 95 name += " in ${id.package}";
96 } 96 }
97 97
98 var parsed = parseCompilationUnit(code, name: name); 98 var parsed = parseCompilationUnit(code, name: name);
99 if (!dart.isEntrypoint(parsed)) return null; 99 if (!dart.isEntrypoint(parsed)) return null;
100 } on AnalyzerErrorGroup catch (e) { 100 } on AnalyzerErrorGroup catch (e) {
101 transform.logger.error(e.message); 101 transform.logger.error(e.message);
102 return null; 102 return null;
103 } 103 }
104 104
105 var provider = new _BarbackCompilerProvider(_graph, transform); 105 var provider = new _BarbackCompilerProvider(_environment, transform);
106 106
107 // Create a "path" to the entrypoint script. The entrypoint may not 107 // Create a "path" to the entrypoint script. The entrypoint may not
108 // actually be on disk, but this gives dart2js a root to resolve 108 // actually be on disk, but this gives dart2js a root to resolve
109 // relative paths against. 109 // relative paths against.
110 var id = transform.primaryInput.id; 110 var id = transform.primaryInput.id;
111 111
112 entrypoints.add(id); 112 var entrypoint = path.join(_environment.graph.packages[id.package].dir,
113 113 id.path);
114 var entrypoint = path.join(_graph.packages[id.package].dir, id.path);
115 114
116 // TODO(rnystrom): Should have more sophisticated error-handling here. 115 // TODO(rnystrom): Should have more sophisticated error-handling here.
117 // Need to report compile errors to the user in an easily visible way. 116 // Need to report compile errors to the user in an easily visible way.
118 // Need to make sure paths in errors are mapped to the original source 117 // Need to make sure paths in errors are mapped to the original source
119 // path so they can understand them. 118 // path so they can understand them.
120 return Chain.track(dart.compile( 119 return Chain.track(dart.compile(
121 entrypoint, provider, 120 entrypoint, provider,
122 commandLineOptions: _configCommandLineOptions, 121 commandLineOptions: _configCommandLineOptions,
123 checked: _configBool('checked'), 122 checked: _configBool('checked'),
124 minify: _configBool( 123 minify: _configBool(
125 'minify', defaultsTo: _settings.mode == BarbackMode.RELEASE), 124 'minify', defaultsTo: _settings.mode == BarbackMode.RELEASE),
126 verbose: _configBool('verbose'), 125 verbose: _configBool('verbose'),
127 environment: _configEnvironment, 126 environment: _configEnvironment,
128 packageRoot: path.join(_graph.entrypoint.root.dir, "packages"), 127 packageRoot: path.join(_environment.rootPackage.dir,
128 "packages"),
129 analyzeAll: _configBool('analyzeAll'), 129 analyzeAll: _configBool('analyzeAll'),
130 suppressWarnings: _configBool('suppressWarnings'), 130 suppressWarnings: _configBool('suppressWarnings'),
131 suppressHints: _configBool('suppressHints'), 131 suppressHints: _configBool('suppressHints'),
132 terse: _configBool('terse'))).then((_) { 132 terse: _configBool('terse'))).then((_) {
133 stopwatch.stop(); 133 stopwatch.stop();
134 transform.logger.info("Took ${stopwatch.elapsed} to compile $id."); 134 transform.logger.info("Took ${stopwatch.elapsed} to compile $id.");
135 }); 135 });
136 }).whenComplete(() { 136 }).whenComplete(() {
137 completer.complete(); 137 completer.complete();
138 _running = null; 138 _running = null;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 } 180 }
181 } 181 }
182 182
183 /// Defines an interface for dart2js to communicate with barback and pub. 183 /// Defines an interface for dart2js to communicate with barback and pub.
184 /// 184 ///
185 /// Note that most of the implementation of diagnostic handling here was 185 /// Note that most of the implementation of diagnostic handling here was
186 /// copied from [FormattingDiagnosticHandler] in dart2js. The primary 186 /// copied from [FormattingDiagnosticHandler] in dart2js. The primary
187 /// difference is that it uses barback's logging code and, more importantly, it 187 /// difference is that it uses barback's logging code and, more importantly, it
188 /// handles missing source files more gracefully. 188 /// handles missing source files more gracefully.
189 class _BarbackCompilerProvider implements dart.CompilerProvider { 189 class _BarbackCompilerProvider implements dart.CompilerProvider {
190 final PackageGraph _graph; 190 final BuildEnvironment _environment;
191 final Transform _transform; 191 final Transform _transform;
192 192
193 /// The map of previously loaded files. 193 /// The map of previously loaded files.
194 /// 194 ///
195 /// Used to show where an error occurred in a source file. 195 /// Used to show where an error occurred in a source file.
196 final _sourceFiles = new Map<String, SourceFile>(); 196 final _sourceFiles = new Map<String, SourceFile>();
197 197
198 // TODO(rnystrom): Make these configurable. 198 // TODO(rnystrom): Make these configurable.
199 /// Whether or not warnings should be logged. 199 /// Whether or not warnings should be logged.
200 var _showWarnings = true; 200 var _showWarnings = true;
(...skipping 13 matching lines...) Expand all
214 214
215 compiler.Diagnostic _lastKind = null; 215 compiler.Diagnostic _lastKind = null;
216 216
217 static final int _FATAL = 217 static final int _FATAL =
218 compiler.Diagnostic.CRASH.ordinal | 218 compiler.Diagnostic.CRASH.ordinal |
219 compiler.Diagnostic.ERROR.ordinal; 219 compiler.Diagnostic.ERROR.ordinal;
220 static final int _INFO = 220 static final int _INFO =
221 compiler.Diagnostic.INFO.ordinal | 221 compiler.Diagnostic.INFO.ordinal |
222 compiler.Diagnostic.VERBOSE_INFO.ordinal; 222 compiler.Diagnostic.VERBOSE_INFO.ordinal;
223 223
224 _BarbackCompilerProvider(this._graph, this._transform); 224 _BarbackCompilerProvider(this._environment, this._transform);
225 225
226 /// A [CompilerInputProvider] for dart2js. 226 /// A [CompilerInputProvider] for dart2js.
227 Future<String> provideInput(Uri resourceUri) { 227 Future<String> provideInput(Uri resourceUri) {
228 // We only expect to get absolute "file:" URLs from dart2js. 228 // We only expect to get absolute "file:" URLs from dart2js.
229 assert(resourceUri.isAbsolute); 229 assert(resourceUri.isAbsolute);
230 assert(resourceUri.scheme == "file"); 230 assert(resourceUri.scheme == "file");
231 231
232 var sourcePath = path.fromUri(resourceUri); 232 var sourcePath = path.fromUri(resourceUri);
233 return _readResource(resourceUri).then((source) { 233 return _readResource(resourceUri).then((source) {
234 _sourceFiles[resourceUri.toString()] = 234 _sourceFiles[resourceUri.toString()] =
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 } 337 }
338 338
339 AssetId _sourceUrlToId(Uri url) { 339 AssetId _sourceUrlToId(Uri url) {
340 // See if it's a special path with "packages" or "assets" in it. 340 // See if it's a special path with "packages" or "assets" in it.
341 var id = specialUrlToId(url); 341 var id = specialUrlToId(url);
342 if (id != null) return id; 342 if (id != null) return id;
343 343
344 // See if it's a path to a "public" asset within the root package. All 344 // See if it's a path to a "public" asset within the root package. All
345 // other files in the root package are not visible to transformers, so 345 // other files in the root package are not visible to transformers, so
346 // should be loaded directly from disk. 346 // should be loaded directly from disk.
347 var rootDir = _graph.entrypoint.root.dir; 347 var rootDir = _environment.rootPackage.dir;
348 var sourcePath = path.fromUri(url); 348 var sourcePath = path.fromUri(url);
349 if (isBeneath(sourcePath, path.join(rootDir, "lib")) || 349 if (isBeneath(sourcePath, path.join(rootDir, "lib")) ||
350 isBeneath(sourcePath, path.join(rootDir, "asset")) || 350 isBeneath(sourcePath, path.join(rootDir, "asset")) ||
351 isBeneath(sourcePath, path.join(rootDir, "web"))) { 351 isBeneath(sourcePath, path.join(rootDir, "web"))) {
352 var relative = path.relative(sourcePath, from: rootDir); 352 var relative = path.relative(sourcePath, from: rootDir);
353 353
354 return new AssetId(_graph.entrypoint.root.name, relative); 354 return new AssetId(_environment.rootPackage.name, relative);
355 } 355 }
356 356
357 return null; 357 return null;
358 } 358 }
359 } 359 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698