| 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 dart2js.compiler_base; | 5 library dart2js.compiler_base; |
| 6 | 6 |
| 7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import '../compiler_new.dart' as api; | 9 import '../compiler_new.dart' as api; |
| 10 import 'backend_strategy.dart'; | 10 import 'backend_strategy.dart'; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 */ | 108 */ |
| 109 bool stopAfterTypeInference = false; | 109 bool stopAfterTypeInference = false; |
| 110 | 110 |
| 111 /// Output provider from user of Compiler API. | 111 /// Output provider from user of Compiler API. |
| 112 api.CompilerOutput userOutputProvider; | 112 api.CompilerOutput userOutputProvider; |
| 113 | 113 |
| 114 List<Uri> librariesToAnalyzeWhenRun; | 114 List<Uri> librariesToAnalyzeWhenRun; |
| 115 | 115 |
| 116 ResolvedUriTranslator get resolvedUriTranslator; | 116 ResolvedUriTranslator get resolvedUriTranslator; |
| 117 | 117 |
| 118 LibraryEntity mainApp; | 118 Uri mainLibraryUri; |
| 119 FunctionEntity mainFunction; | |
| 120 | 119 |
| 121 DiagnosticReporter get reporter => _reporter; | 120 DiagnosticReporter get reporter => _reporter; |
| 122 Resolution get resolution => _resolution; | 121 Resolution get resolution => _resolution; |
| 123 ParsingContext get parsingContext => _parsingContext; | 122 ParsingContext get parsingContext => _parsingContext; |
| 124 | 123 |
| 125 // TODO(zarah): Remove this map and incorporate compile-time errors | 124 // TODO(zarah): Remove this map and incorporate compile-time errors |
| 126 // in the model. | 125 // in the model. |
| 127 /// Tracks elements with compile-time errors. | 126 /// Tracks elements with compile-time errors. |
| 128 final Map<Entity, List<DiagnosticMessage>> elementsWithCompileTimeErrors = | 127 final Map<Entity, List<DiagnosticMessage>> elementsWithCompileTimeErrors = |
| 129 new Map<Entity, List<DiagnosticMessage>>(); | 128 new Map<Entity, List<DiagnosticMessage>>(); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 return loadedLibraries; | 425 return loadedLibraries; |
| 427 } | 426 } |
| 428 | 427 |
| 429 /** | 428 /** |
| 430 * Get an [Uri] pointing to a patch for the dart: library with | 429 * Get an [Uri] pointing to a patch for the dart: library with |
| 431 * the given path. Returns null if there is no patch. | 430 * the given path. Returns null if there is no patch. |
| 432 */ | 431 */ |
| 433 Uri resolvePatchUri(String dartLibraryPath); | 432 Uri resolvePatchUri(String dartLibraryPath); |
| 434 | 433 |
| 435 Future runInternal(Uri uri) async { | 434 Future runInternal(Uri uri) async { |
| 435 mainLibraryUri = uri; |
| 436 // TODO(ahe): This prevents memory leaks when invoking the compiler | 436 // TODO(ahe): This prevents memory leaks when invoking the compiler |
| 437 // multiple times. Implement a better mechanism where we can store | 437 // multiple times. Implement a better mechanism where we can store |
| 438 // such caches in the compiler and get access to them through a | 438 // such caches in the compiler and get access to them through a |
| 439 // suitably maintained static reference to the current compiler. | 439 // suitably maintained static reference to the current compiler. |
| 440 StringToken.canonicalizer.clear(); | 440 StringToken.canonicalizer.clear(); |
| 441 Selector.canonicalizedValues.clear(); | 441 Selector.canonicalizedValues.clear(); |
| 442 | 442 |
| 443 // The selector objects held in static fields must remain canonical. | 443 // The selector objects held in static fields must remain canonical. |
| 444 for (Selector selector in Selectors.ALL) { | 444 for (Selector selector in Selectors.ALL) { |
| 445 Selector.canonicalizedValues | 445 Selector.canonicalizedValues |
| 446 .putIfAbsent(selector.hashCode, () => <Selector>[]) | 446 .putIfAbsent(selector.hashCode, () => <Selector>[]) |
| 447 .add(selector); | 447 .add(selector); |
| 448 } | 448 } |
| 449 | 449 |
| 450 assert(uri != null || options.analyzeOnly); | 450 assert(uri != null || options.analyzeOnly); |
| 451 // As far as I can tell, this branch is only used by test code. | 451 // As far as I can tell, this branch is only used by test code. |
| 452 if (librariesToAnalyzeWhenRun != null) { | 452 if (librariesToAnalyzeWhenRun != null) { |
| 453 await Future.forEach(librariesToAnalyzeWhenRun, (libraryUri) async { | 453 await Future.forEach(librariesToAnalyzeWhenRun, (libraryUri) async { |
| 454 reporter.log('Analyzing $libraryUri (${options.buildId})'); | 454 reporter.log('Analyzing $libraryUri (${options.buildId})'); |
| 455 LoadedLibraries loadedLibraries = | 455 LoadedLibraries loadedLibraries = |
| 456 await libraryLoader.loadLibrary(libraryUri); | 456 await libraryLoader.loadLibrary(libraryUri); |
| 457 processLoadedLibraries(loadedLibraries); | 457 processLoadedLibraries(loadedLibraries); |
| 458 }); | 458 }); |
| 459 } | 459 } |
| 460 LibraryEntity mainApp; |
| 460 if (uri != null) { | 461 if (uri != null) { |
| 461 if (options.analyzeOnly) { | 462 if (options.analyzeOnly) { |
| 462 reporter.log('Analyzing $uri (${options.buildId})'); | 463 reporter.log('Analyzing $uri (${options.buildId})'); |
| 463 } else { | 464 } else { |
| 464 reporter.log('Compiling $uri (${options.buildId})'); | 465 reporter.log('Compiling $uri (${options.buildId})'); |
| 465 } | 466 } |
| 466 LoadedLibraries libraries = await libraryLoader.loadLibrary(uri); | 467 LoadedLibraries libraries = await libraryLoader.loadLibrary(uri); |
| 467 processLoadedLibraries(libraries); | 468 processLoadedLibraries(libraries); |
| 468 mainApp = libraries.rootLibrary; | 469 mainApp = libraries.rootLibrary; |
| 469 } | 470 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 } | 509 } |
| 509 resolutionEnqueuer.addDeferredActions(libraryLoader.pullDeferredActions()); | 510 resolutionEnqueuer.addDeferredActions(libraryLoader.pullDeferredActions()); |
| 510 return resolutionEnqueuer; | 511 return resolutionEnqueuer; |
| 511 } | 512 } |
| 512 | 513 |
| 513 /// Performs the compilation when all libraries have been loaded. | 514 /// Performs the compilation when all libraries have been loaded. |
| 514 void compileLoadedLibraries(LibraryEntity rootLibrary) => | 515 void compileLoadedLibraries(LibraryEntity rootLibrary) => |
| 515 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { | 516 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { |
| 516 ResolutionEnqueuer resolutionEnqueuer = startResolution(); | 517 ResolutionEnqueuer resolutionEnqueuer = startResolution(); |
| 517 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); | 518 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); |
| 518 mainFunction = frontendStrategy.computeMain(rootLibrary, mainImpact); | 519 FunctionEntity mainFunction = |
| 520 frontendStrategy.computeMain(rootLibrary, mainImpact); |
| 519 | 521 |
| 520 if (!options.loadFromDill) { | 522 if (!options.loadFromDill) { |
| 521 // TODO(johnniwinther): Support mirrors usages analysis from dill. | 523 // TODO(johnniwinther): Support mirrors usages analysis from dill. |
| 522 mirrorUsageAnalyzerTask.analyzeUsage(rootLibrary); | 524 mirrorUsageAnalyzerTask.analyzeUsage(rootLibrary); |
| 523 } | 525 } |
| 524 | 526 |
| 525 // In order to see if a library is deferred, we must compute the | 527 // In order to see if a library is deferred, we must compute the |
| 526 // compile-time constants that are metadata. This means adding | 528 // compile-time constants that are metadata. This means adding |
| 527 // something to the resolution queue. So we cannot wait with | 529 // something to the resolution queue. So we cannot wait with |
| 528 // this until after the resolution queue is processed. | 530 // this until after the resolution queue is processed. |
| 529 deferredLoadTask.beforeResolution(this); | 531 deferredLoadTask.beforeResolution(rootLibrary); |
| 530 impactStrategy = backend.createImpactStrategy( | 532 impactStrategy = backend.createImpactStrategy( |
| 531 supportDeferredLoad: deferredLoadTask.isProgramSplit, | 533 supportDeferredLoad: deferredLoadTask.isProgramSplit, |
| 532 supportDumpInfo: options.dumpInfo, | 534 supportDumpInfo: options.dumpInfo, |
| 533 supportSerialization: serialization.supportSerialization); | 535 supportSerialization: serialization.supportSerialization); |
| 534 | 536 |
| 535 phase = PHASE_RESOLVING; | 537 phase = PHASE_RESOLVING; |
| 536 resolutionEnqueuer.applyImpact(mainImpact); | 538 resolutionEnqueuer.applyImpact(mainImpact); |
| 537 if (options.resolveOnly) { | 539 if (options.resolveOnly) { |
| 538 libraryLoader.libraries.where((LibraryEntity library) { | 540 libraryLoader.libraries.where((LibraryEntity library) { |
| 539 return !serialization.isDeserialized(library); | 541 return !serialization.isDeserialized(library); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 serialization.serializeToSink( | 591 serialization.serializeToSink( |
| 590 userOutputProvider.createOutputSink( | 592 userOutputProvider.createOutputSink( |
| 591 '', 'data', api.OutputType.serializationData), | 593 '', 'data', api.OutputType.serializationData), |
| 592 libraryLoader.libraries.where((LibraryEntity library) { | 594 libraryLoader.libraries.where((LibraryEntity library) { |
| 593 return !serialization.isDeserialized(library); | 595 return !serialization.isDeserialized(library); |
| 594 })); | 596 })); |
| 595 } | 597 } |
| 596 if (options.analyzeOnly) return; | 598 if (options.analyzeOnly) return; |
| 597 assert(mainFunction != null); | 599 assert(mainFunction != null); |
| 598 | 600 |
| 599 ClosedWorldRefiner closedWorldRefiner = closeResolution(); | 601 ClosedWorldRefiner closedWorldRefiner = closeResolution(mainFunction); |
| 600 ClosedWorld closedWorld = closedWorldRefiner.closedWorld; | 602 ClosedWorld closedWorld = closedWorldRefiner.closedWorld; |
| 603 mainFunction = closedWorld.elementEnvironment.mainFunction; |
| 601 | 604 |
| 602 reporter.log('Inferring types...'); | 605 reporter.log('Inferring types...'); |
| 603 globalInference.runGlobalTypeInference( | 606 globalInference.runGlobalTypeInference( |
| 604 mainFunction, closedWorld, closedWorldRefiner); | 607 mainFunction, closedWorld, closedWorldRefiner); |
| 605 | 608 |
| 606 if (stopAfterTypeInference) return; | 609 if (stopAfterTypeInference) return; |
| 607 | 610 |
| 608 backend.onTypeInferenceComplete(globalInference.results); | 611 backend.onTypeInferenceComplete(globalInference.results); |
| 609 | 612 |
| 610 reporter.log('Compiling...'); | 613 reporter.log('Compiling...'); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 630 dumpInfoTask.reportSize(programSize); | 633 dumpInfoTask.reportSize(programSize); |
| 631 dumpInfoTask.dumpInfo(closedWorld); | 634 dumpInfoTask.dumpInfo(closedWorld); |
| 632 } | 635 } |
| 633 | 636 |
| 634 backend.onCodegenEnd(); | 637 backend.onCodegenEnd(); |
| 635 | 638 |
| 636 checkQueues(resolutionEnqueuer, codegenEnqueuer); | 639 checkQueues(resolutionEnqueuer, codegenEnqueuer); |
| 637 }); | 640 }); |
| 638 | 641 |
| 639 /// Perform the steps needed to fully end the resolution phase. | 642 /// Perform the steps needed to fully end the resolution phase. |
| 640 ClosedWorldRefiner closeResolution() { | 643 ClosedWorldRefiner closeResolution(FunctionEntity mainFunction) { |
| 641 phase = PHASE_DONE_RESOLVING; | 644 phase = PHASE_DONE_RESOLVING; |
| 642 | 645 |
| 643 ClosedWorld closedWorld = resolutionWorldBuilder.closeWorld(); | 646 ClosedWorld closedWorld = resolutionWorldBuilder.closeWorld(); |
| 644 ClosedWorldRefiner closedWorldRefiner = | 647 ClosedWorldRefiner closedWorldRefiner = |
| 645 backendStrategy.createClosedWorldRefiner(closedWorld); | 648 backendStrategy.createClosedWorldRefiner(closedWorld); |
| 646 // Compute whole-program-knowledge that the backend needs. (This might | 649 // Compute whole-program-knowledge that the backend needs. (This might |
| 647 // require the information computed in [world.closeWorld].) | 650 // require the information computed in [world.closeWorld].) |
| 648 backend.onResolutionClosedWorld(closedWorld, closedWorldRefiner); | 651 backend.onResolutionClosedWorld(closedWorld, closedWorldRefiner); |
| 649 | 652 |
| 650 deferredLoadTask.onResolutionComplete(mainFunction, closedWorld); | 653 deferredLoadTask.onResolutionComplete(mainFunction, closedWorld); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 Iterable<CodeLocation> userCodeLocations = | 906 Iterable<CodeLocation> userCodeLocations = |
| 904 computeUserCodeLocations(assumeInUserCode: assumeInUserCode); | 907 computeUserCodeLocations(assumeInUserCode: assumeInUserCode); |
| 905 Uri libraryUri = element.library.canonicalUri; | 908 Uri libraryUri = element.library.canonicalUri; |
| 906 return userCodeLocations.any( | 909 return userCodeLocations.any( |
| 907 (CodeLocation codeLocation) => codeLocation.inSameLocation(libraryUri)); | 910 (CodeLocation codeLocation) => codeLocation.inSameLocation(libraryUri)); |
| 908 } | 911 } |
| 909 | 912 |
| 910 Iterable<CodeLocation> computeUserCodeLocations( | 913 Iterable<CodeLocation> computeUserCodeLocations( |
| 911 {bool assumeInUserCode: false}) { | 914 {bool assumeInUserCode: false}) { |
| 912 List<CodeLocation> userCodeLocations = <CodeLocation>[]; | 915 List<CodeLocation> userCodeLocations = <CodeLocation>[]; |
| 913 if (mainApp != null) { | 916 if (mainLibraryUri != null) { |
| 914 userCodeLocations.add(new CodeLocation(mainApp.canonicalUri)); | 917 userCodeLocations.add(new CodeLocation(mainLibraryUri)); |
| 915 } | 918 } |
| 916 if (librariesToAnalyzeWhenRun != null) { | 919 if (librariesToAnalyzeWhenRun != null) { |
| 917 userCodeLocations.addAll( | 920 userCodeLocations.addAll( |
| 918 librariesToAnalyzeWhenRun.map((Uri uri) => new CodeLocation(uri))); | 921 librariesToAnalyzeWhenRun.map((Uri uri) => new CodeLocation(uri))); |
| 919 } | 922 } |
| 920 if (userCodeLocations.isEmpty && assumeInUserCode) { | 923 if (userCodeLocations.isEmpty && assumeInUserCode) { |
| 921 // Assume in user code since [mainApp] has not been set yet. | 924 // Assume in user code since [mainApp] has not been set yet. |
| 922 userCodeLocations.add(const AnyLocation()); | 925 userCodeLocations.add(const AnyLocation()); |
| 923 } | 926 } |
| 924 return userCodeLocations; | 927 return userCodeLocations; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 948 } | 951 } |
| 949 | 952 |
| 950 /// Associate [element] with a compile-time error [message]. | 953 /// Associate [element] with a compile-time error [message]. |
| 951 void registerCompileTimeError(Entity element, DiagnosticMessage message) { | 954 void registerCompileTimeError(Entity element, DiagnosticMessage message) { |
| 952 // The information is only needed if [generateCodeWithCompileTimeErrors]. | 955 // The information is only needed if [generateCodeWithCompileTimeErrors]. |
| 953 if (options.generateCodeWithCompileTimeErrors) { | 956 if (options.generateCodeWithCompileTimeErrors) { |
| 954 if (element == null) { | 957 if (element == null) { |
| 955 // Record as global error. | 958 // Record as global error. |
| 956 // TODO(zarah): Extend element model to represent compile-time | 959 // TODO(zarah): Extend element model to represent compile-time |
| 957 // errors instead of using a map. | 960 // errors instead of using a map. |
| 958 element = mainFunction; | 961 element = frontendStrategy.elementEnvironment.mainFunction; |
| 959 } | 962 } |
| 960 elementsWithCompileTimeErrors | 963 elementsWithCompileTimeErrors |
| 961 .putIfAbsent(element, () => <DiagnosticMessage>[]) | 964 .putIfAbsent(element, () => <DiagnosticMessage>[]) |
| 962 .add(message); | 965 .add(message); |
| 963 } | 966 } |
| 964 } | 967 } |
| 965 | 968 |
| 966 api.OutputSink outputProvider( | 969 api.OutputSink outputProvider( |
| 967 String name, String extension, api.OutputType type) { | 970 String name, String extension, api.OutputType type) { |
| 968 if (compilationFailed) { | 971 if (compilationFailed) { |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 _ElementScanner(this.scanner); | 1588 _ElementScanner(this.scanner); |
| 1586 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); | 1589 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); |
| 1587 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); | 1590 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); |
| 1588 } | 1591 } |
| 1589 | 1592 |
| 1590 class _EmptyEnvironment implements Environment { | 1593 class _EmptyEnvironment implements Environment { |
| 1591 const _EmptyEnvironment(); | 1594 const _EmptyEnvironment(); |
| 1592 | 1595 |
| 1593 String valueOf(String key) => null; | 1596 String valueOf(String key) => null; |
| 1594 } | 1597 } |
| OLD | NEW |