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 |