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 |