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