Chromium Code Reviews| 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 |