OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 leg_apiimpl; | 5 library leg_apiimpl; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | |
8 | 9 |
9 import '../compiler.dart' as api; | 10 import '../compiler.dart' as api; |
10 import 'dart2jslib.dart' as leg; | 11 import 'dart2jslib.dart' as leg; |
11 import 'tree/tree.dart' as tree; | 12 import 'tree/tree.dart' as tree; |
12 import 'elements/elements.dart' as elements; | 13 import 'elements/elements.dart' as elements; |
13 import 'package:_internal/libraries.dart' hide LIBRARIES; | 14 import 'package:_internal/libraries.dart' hide LIBRARIES; |
14 import 'package:_internal/libraries.dart' as library_info show LIBRARIES; | 15 import 'package:_internal/libraries.dart' as library_info show LIBRARIES; |
15 import 'io/source_file.dart'; | 16 import 'io/source_file.dart'; |
17 import 'package:package_config/packages.dart'; | |
18 import 'package:package_config/packages_file.dart' as pkgs; | |
19 import 'package:package_config/src/packages_impl.dart' | |
20 show NonFilePackagesDirectoryPackages, MapPackages; | |
16 | 21 |
17 const bool forceIncrementalSupport = | 22 const bool forceIncrementalSupport = |
18 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); | 23 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); |
19 | 24 |
20 class Compiler extends leg.Compiler { | 25 class Compiler extends leg.Compiler { |
21 api.CompilerInputProvider provider; | 26 api.CompilerInputProvider provider; |
22 api.DiagnosticHandler handler; | 27 api.DiagnosticHandler handler; |
23 final Uri libraryRoot; | 28 final Uri libraryRoot; |
29 final Uri packageConfig; | |
24 final Uri packageRoot; | 30 final Uri packageRoot; |
31 final api.PackagesDiscoveryProvider packagesDiscoveryProvider; | |
32 Packages packages; | |
25 List<String> options; | 33 List<String> options; |
26 Map<String, dynamic> environment; | 34 Map<String, dynamic> environment; |
27 bool mockableLibraryUsed = false; | 35 bool mockableLibraryUsed = false; |
28 final Set<String> allowedLibraryCategories; | 36 final Set<String> allowedLibraryCategories; |
29 | 37 |
30 leg.GenericTask userHandlerTask; | 38 leg.GenericTask userHandlerTask; |
31 leg.GenericTask userProviderTask; | 39 leg.GenericTask userProviderTask; |
40 leg.GenericTask userPackagesDiscoveryTask; | |
32 | 41 |
33 Compiler(this.provider, | 42 Compiler(this.provider, |
34 api.CompilerOutputProvider outputProvider, | 43 api.CompilerOutputProvider outputProvider, |
35 this.handler, | 44 this.handler, |
36 this.libraryRoot, | 45 this.libraryRoot, |
37 this.packageRoot, | 46 this.packageRoot, |
38 List<String> options, | 47 List<String> options, |
39 this.environment) | 48 this.environment, |
49 [this.packageConfig, | |
50 this.packagesDiscoveryProvider]) | |
40 : this.options = options, | 51 : this.options = options, |
41 this.allowedLibraryCategories = getAllowedLibraryCategories(options), | 52 this.allowedLibraryCategories = getAllowedLibraryCategories(options), |
42 super( | 53 super( |
43 outputProvider: outputProvider, | 54 outputProvider: outputProvider, |
44 enableTypeAssertions: hasOption(options, '--enable-checked-mode'), | 55 enableTypeAssertions: hasOption(options, '--enable-checked-mode'), |
45 enableUserAssertions: hasOption(options, '--enable-checked-mode'), | 56 enableUserAssertions: hasOption(options, '--enable-checked-mode'), |
46 trustTypeAnnotations: | 57 trustTypeAnnotations: |
47 hasOption(options, '--trust-type-annotations'), | 58 hasOption(options, '--trust-type-annotations'), |
48 trustPrimitives: | 59 trustPrimitives: |
49 hasOption(options, '--trust-primitives'), | 60 hasOption(options, '--trust-primitives'), |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 hasOption(options, '--enable-experimental-mirrors'), | 99 hasOption(options, '--enable-experimental-mirrors'), |
89 generateCodeWithCompileTimeErrors: | 100 generateCodeWithCompileTimeErrors: |
90 hasOption(options, '--generate-code-with-compile-time-errors'), | 101 hasOption(options, '--generate-code-with-compile-time-errors'), |
91 allowNativeExtensions: | 102 allowNativeExtensions: |
92 hasOption(options, '--allow-native-extensions'), | 103 hasOption(options, '--allow-native-extensions'), |
93 enableNullAwareOperators: | 104 enableNullAwareOperators: |
94 hasOption(options, '--enable-null-aware-operators')) { | 105 hasOption(options, '--enable-null-aware-operators')) { |
95 tasks.addAll([ | 106 tasks.addAll([ |
96 userHandlerTask = new leg.GenericTask('Diagnostic handler', this), | 107 userHandlerTask = new leg.GenericTask('Diagnostic handler', this), |
97 userProviderTask = new leg.GenericTask('Input provider', this), | 108 userProviderTask = new leg.GenericTask('Input provider', this), |
109 userPackagesDiscoveryTask = | |
110 new leg.GenericTask('Package discovery', this), | |
98 ]); | 111 ]); |
99 if (libraryRoot == null) { | 112 if (libraryRoot == null) { |
100 throw new ArgumentError("[libraryRoot] is null."); | 113 throw new ArgumentError("[libraryRoot] is null."); |
101 } | 114 } |
102 if (!libraryRoot.path.endsWith("/")) { | 115 if (!libraryRoot.path.endsWith("/")) { |
103 throw new ArgumentError("[libraryRoot] must end with a /."); | 116 throw new ArgumentError("[libraryRoot] must end with a /."); |
104 } | 117 } |
105 if (packageRoot == null) { | 118 if (packageRoot != null && packageConfig != null) { |
106 throw new ArgumentError("[packageRoot] is null."); | 119 throw new ArgumentError("Only one of [packageRoot] or [packageConfig] " |
120 "may be given."); | |
107 } | 121 } |
108 if (!packageRoot.path.endsWith("/")) { | 122 if (packageRoot != null && !packageRoot.path.endsWith("/")) { |
109 throw new ArgumentError("[packageRoot] must end with a /."); | 123 throw new ArgumentError("[packageRoot] must end with a /."); |
110 } | 124 } |
111 if (!analyzeOnly) { | 125 if (!analyzeOnly) { |
112 if (allowNativeExtensions) { | 126 if (allowNativeExtensions) { |
113 throw new ArgumentError( | 127 throw new ArgumentError( |
114 "--allow-native-extensions is only supported in combination with " | 128 "--allow-native-extensions is only supported in combination with " |
115 "--analyze-only"); | 129 "--analyze-only"); |
116 } | 130 } |
117 } | 131 } |
118 } | 132 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
152 result.add('Internal'); | 166 result.add('Internal'); |
153 return new Set<String>.from(result); | 167 return new Set<String>.from(result); |
154 } | 168 } |
155 | 169 |
156 static bool hasOption(List<String> options, String option) { | 170 static bool hasOption(List<String> options, String option) { |
157 return options.indexOf(option) >= 0; | 171 return options.indexOf(option) >= 0; |
158 } | 172 } |
159 | 173 |
160 // TODO(johnniwinther): Merge better with [translateDartUri] when | 174 // TODO(johnniwinther): Merge better with [translateDartUri] when |
161 // [scanBuiltinLibrary] is removed. | 175 // [scanBuiltinLibrary] is removed. |
162 String lookupLibraryPath(String dartLibraryName) { | 176 String lookupLibraryPath(LibraryInfo info) { |
163 LibraryInfo info = lookupLibraryInfo(dartLibraryName); | |
164 if (info == null) return null; | 177 if (info == null) return null; |
165 if (!info.isDart2jsLibrary) return null; | 178 if (!info.isDart2jsLibrary) return null; |
166 if (!allowedLibraryCategories.contains(info.category)) return null; | 179 if (!allowedLibraryCategories.contains(info.category)) return null; |
167 String path = info.dart2jsPath; | 180 String path = info.dart2jsPath; |
168 if (path == null) { | 181 if (path == null) { |
169 path = info.path; | 182 path = info.path; |
170 } | 183 } |
171 return "lib/$path"; | 184 return "lib/$path"; |
172 } | 185 } |
173 | 186 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 Uri translateUri(leg.Spannable node, Uri readableUri) { | 290 Uri translateUri(leg.Spannable node, Uri readableUri) { |
278 switch (readableUri.scheme) { | 291 switch (readableUri.scheme) { |
279 case 'package': return translatePackageUri(node, readableUri); | 292 case 'package': return translatePackageUri(node, readableUri); |
280 default: return readableUri; | 293 default: return readableUri; |
281 } | 294 } |
282 } | 295 } |
283 | 296 |
284 Uri translateDartUri(elements.LibraryElement importingLibrary, | 297 Uri translateDartUri(elements.LibraryElement importingLibrary, |
285 Uri resolvedUri, tree.Node node) { | 298 Uri resolvedUri, tree.Node node) { |
286 LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path); | 299 LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path); |
287 String path = lookupLibraryPath(resolvedUri.path); | 300 String path = lookupLibraryPath(libraryInfo); |
288 if (libraryInfo != null && | 301 if (libraryInfo != null && |
289 libraryInfo.category == "Internal") { | 302 libraryInfo.category == "Internal") { |
290 bool allowInternalLibraryAccess = false; | 303 bool allowInternalLibraryAccess = false; |
291 if (importingLibrary != null) { | 304 if (importingLibrary != null) { |
292 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { | 305 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { |
293 allowInternalLibraryAccess = true; | 306 allowInternalLibraryAccess = true; |
294 } else if (importingLibrary.canonicalUri.path.contains( | 307 } else if (importingLibrary.canonicalUri.path.contains( |
295 'sdk/tests/compiler/dart2js_native')) { | 308 'sdk/tests/compiler/dart2js_native')) { |
296 allowInternalLibraryAccess = true; | 309 allowInternalLibraryAccess = true; |
297 } | 310 } |
(...skipping 27 matching lines...) Expand all Loading... | |
325 return libraryRoot.resolve(path); | 338 return libraryRoot.resolve(path); |
326 } | 339 } |
327 | 340 |
328 Uri resolvePatchUri(String dartLibraryPath) { | 341 Uri resolvePatchUri(String dartLibraryPath) { |
329 String patchPath = lookupPatchPath(dartLibraryPath); | 342 String patchPath = lookupPatchPath(dartLibraryPath); |
330 if (patchPath == null) return null; | 343 if (patchPath == null) return null; |
331 return libraryRoot.resolve(patchPath); | 344 return libraryRoot.resolve(patchPath); |
332 } | 345 } |
333 | 346 |
334 Uri translatePackageUri(leg.Spannable node, Uri uri) { | 347 Uri translatePackageUri(leg.Spannable node, Uri uri) { |
335 return packageRoot.resolve(uri.path); | 348 return packages.resolve(uri); |
336 } | 349 } |
337 | 350 |
338 Future<bool> run(Uri uri) { | 351 Future setPackages(Uri uri) async { |
Johnni Winther
2015/06/03 11:36:39
Rename to 'setupPackages'.
Harry Terkelsen
2015/06/04 22:05:30
Done.
| |
352 if (packageRoot != null) { | |
353 // Use "non-file" packages because the file version requires a [Directory] | |
354 // and we can't depend on 'dart:io' classes. | |
355 packages = new NonFilePackagesDirectoryPackages(packageRoot); | |
356 } else if (packageConfig != null) { | |
357 var packageConfigContents = await provider(packageConfig); | |
358 if (packageConfigContents is String) { | |
359 packageConfigContents = UTF8.encode(packageConfigContents); | |
360 } | |
361 packages = | |
362 new MapPackages(pkgs.parse(packageConfigContents, packageConfig)); | |
Johnni Winther
2015/06/03 11:36:39
Indent by 4.
Harry Terkelsen
2015/06/04 22:05:30
Done.
| |
363 } else { | |
364 if (packagesDiscoveryProvider == null) { | |
365 packages = Packages.noPackages; | |
366 } else { | |
367 packages = await callUserPackagesDiscovery(uri); | |
368 } | |
369 } | |
370 } | |
371 | |
372 Future<bool> run(Uri uri) async { | |
339 log('Allowed library categories: $allowedLibraryCategories'); | 373 log('Allowed library categories: $allowedLibraryCategories'); |
340 return super.run(uri).then((bool success) { | 374 |
341 int cumulated = 0; | 375 await setPackages(uri); |
342 for (final task in tasks) { | 376 assert(packages != null); |
343 int elapsed = task.timing; | 377 |
344 if (elapsed != 0) { | 378 bool success = await super.run(uri); |
345 cumulated += elapsed; | 379 int cumulated = 0; |
346 log('${task.name} took ${elapsed}msec'); | 380 for (final task in tasks) { |
347 } | 381 int elapsed = task.timing; |
382 if (elapsed != 0) { | |
383 cumulated += elapsed; | |
384 log('${task.name} took ${elapsed}msec'); | |
348 } | 385 } |
349 int total = totalCompileTime.elapsedMilliseconds; | 386 } |
350 log('Total compile-time ${total}msec;' | 387 int total = totalCompileTime.elapsedMilliseconds; |
351 ' unaccounted ${total - cumulated}msec'); | 388 log('Total compile-time ${total}msec;' |
352 return success; | 389 ' unaccounted ${total - cumulated}msec'); |
353 }); | 390 return success; |
354 } | 391 } |
355 | 392 |
356 void reportDiagnostic(leg.Spannable node, | 393 void reportDiagnostic(leg.Spannable node, |
357 leg.Message message, | 394 leg.Message message, |
358 api.Diagnostic kind) { | 395 api.Diagnostic kind) { |
359 leg.SourceSpan span = spanFromSpannable(node); | 396 leg.SourceSpan span = spanFromSpannable(node); |
360 if (identical(kind, api.Diagnostic.ERROR) | 397 if (identical(kind, api.Diagnostic.ERROR) |
361 || identical(kind, api.Diagnostic.CRASH) | 398 || identical(kind, api.Diagnostic.CRASH) |
362 || (fatalWarnings && identical(kind, api.Diagnostic.WARNING))) { | 399 || (fatalWarnings && identical(kind, api.Diagnostic.WARNING))) { |
363 compilationFailed = true; | 400 compilationFailed = true; |
(...skipping 28 matching lines...) Expand all Loading... | |
392 | 429 |
393 Future callUserProvider(Uri uri) { | 430 Future callUserProvider(Uri uri) { |
394 try { | 431 try { |
395 return userProviderTask.measure(() => provider(uri)); | 432 return userProviderTask.measure(() => provider(uri)); |
396 } catch (ex, s) { | 433 } catch (ex, s) { |
397 diagnoseCrashInUserCode('Uncaught exception in input provider', ex, s); | 434 diagnoseCrashInUserCode('Uncaught exception in input provider', ex, s); |
398 rethrow; | 435 rethrow; |
399 } | 436 } |
400 } | 437 } |
401 | 438 |
439 Future<Packages> callUserPackagesDiscovery(Uri uri) { | |
440 try { | |
441 return userPackagesDiscoveryTask.measure( | |
442 () => packagesDiscoveryProvider(uri)); | |
443 } catch (ex, s) { | |
444 diagnoseCrashInUserCode('Uncaught exception in package discovery', ex, s); | |
445 rethrow; | |
446 } | |
447 } | |
448 | |
402 void diagnoseCrashInUserCode(String message, exception, stackTrace) { | 449 void diagnoseCrashInUserCode(String message, exception, stackTrace) { |
403 hasCrashed = true; | 450 hasCrashed = true; |
404 print('$message: ${tryToString(exception)}'); | 451 print('$message: ${tryToString(exception)}'); |
405 print(tryToString(stackTrace)); | 452 print(tryToString(stackTrace)); |
406 } | 453 } |
407 | 454 |
408 fromEnvironment(String name) => environment[name]; | 455 fromEnvironment(String name) => environment[name]; |
409 | 456 |
410 LibraryInfo lookupLibraryInfo(String libraryName) { | 457 LibraryInfo lookupLibraryInfo(String libraryName) { |
411 return library_info.LIBRARIES[libraryName]; | 458 return library_info.LIBRARIES[libraryName]; |
412 } | 459 } |
413 } | 460 } |
OLD | NEW |