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 EventSink, Future; | 7 import 'dart:async' show EventSink, Future; |
8 | 8 |
9 import '../compiler_new.dart' as api; | 9 import '../compiler_new.dart' as api; |
10 import 'cache_strategy.dart' show CacheStrategy; | 10 import 'cache_strategy.dart' show CacheStrategy; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 Compiler compiler, CompilerOptions options); | 86 Compiler compiler, CompilerOptions options); |
87 | 87 |
88 abstract class Compiler implements LibraryLoaderListener { | 88 abstract class Compiler implements LibraryLoaderListener { |
89 Measurer get measurer; | 89 Measurer get measurer; |
90 | 90 |
91 final IdGenerator idGenerator = new IdGenerator(); | 91 final IdGenerator idGenerator = new IdGenerator(); |
92 WorldImpl get _world => resolverWorld.openWorld; | 92 WorldImpl get _world => resolverWorld.openWorld; |
93 Types types; | 93 Types types; |
94 _CompilerCoreTypes _coreTypes; | 94 _CompilerCoreTypes _coreTypes; |
95 CompilerDiagnosticReporter _reporter; | 95 CompilerDiagnosticReporter _reporter; |
96 _CompilerResolution _resolution; | 96 CompilerResolution _resolution; |
97 ParsingContext _parsingContext; | 97 ParsingContext _parsingContext; |
98 | 98 |
99 final CacheStrategy cacheStrategy; | 99 final CacheStrategy cacheStrategy; |
100 | 100 |
101 ImpactStrategy impactStrategy = const ImpactStrategy(); | 101 ImpactStrategy impactStrategy = const ImpactStrategy(); |
102 | 102 |
103 /** | 103 /** |
104 * Map from token to the first preceding comment token. | 104 * Map from token to the first preceding comment token. |
105 */ | 105 */ |
106 final TokenMap commentMap = new TokenMap(); | 106 final TokenMap commentMap = new TokenMap(); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 : this.options = options, | 208 : this.options = options, |
209 this.cacheStrategy = new CacheStrategy(options.hasIncrementalSupport), | 209 this.cacheStrategy = new CacheStrategy(options.hasIncrementalSupport), |
210 this.userOutputProvider = outputProvider == null | 210 this.userOutputProvider = outputProvider == null |
211 ? const NullCompilerOutput() | 211 ? const NullCompilerOutput() |
212 : outputProvider { | 212 : outputProvider { |
213 if (makeReporter != null) { | 213 if (makeReporter != null) { |
214 _reporter = makeReporter(this, options); | 214 _reporter = makeReporter(this, options); |
215 } else { | 215 } else { |
216 _reporter = new CompilerDiagnosticReporter(this, options); | 216 _reporter = new CompilerDiagnosticReporter(this, options); |
217 } | 217 } |
218 _resolution = new _CompilerResolution(this); | 218 _resolution = createResolution(); |
219 // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and | 219 // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and |
220 // make its field final. | 220 // make its field final. |
221 _coreTypes = new _CompilerCoreTypes(_resolution, reporter); | 221 _coreTypes = new _CompilerCoreTypes(_resolution, reporter); |
222 types = new Types(_resolution); | 222 types = new Types(_resolution); |
223 tracer = new Tracer(this, this.outputProvider); | 223 tracer = new Tracer(this, this.outputProvider); |
224 | 224 |
225 if (options.verbose) { | 225 if (options.verbose) { |
226 progress = new Stopwatch()..start(); | 226 progress = new Stopwatch()..start(); |
227 } | 227 } |
228 | 228 |
229 // TODO(johnniwinther): Separate the dependency tracking from the enqueuing | 229 // TODO(johnniwinther): Separate the dependency tracking from the enqueuing |
230 // for global dependencies. | 230 // for global dependencies. |
231 globalDependencies = new GlobalDependencyRegistry(); | 231 globalDependencies = new GlobalDependencyRegistry(); |
232 | 232 |
233 if (makeBackend != null) { | 233 if (makeBackend != null) { |
234 backend = makeBackend(this); | 234 backend = makeBackend(this); |
235 } else { | 235 } else { |
236 js_backend.JavaScriptBackend jsBackend = new js_backend.JavaScriptBackend( | 236 backend = createBackend(); |
237 this, | |
238 generateSourceMap: options.generateSourceMap, | |
239 useStartupEmitter: options.useStartupEmitter, | |
240 useNewSourceInfo: options.useNewSourceInfo, | |
241 useKernel: options.useKernel); | |
242 backend = jsBackend; | |
243 } | 237 } |
244 enqueuer = backend.makeEnqueuer(); | 238 enqueuer = backend.makeEnqueuer(); |
245 | 239 |
246 if (options.dumpInfo && options.useStartupEmitter) { | 240 if (options.dumpInfo && options.useStartupEmitter) { |
247 throw new ArgumentError( | 241 throw new ArgumentError( |
248 '--dump-info is not supported with the fast startup emitter'); | 242 '--dump-info is not supported with the fast startup emitter'); |
249 } | 243 } |
250 | 244 |
251 tasks = [ | 245 tasks = [ |
252 dietParser = new DietParserTask(idGenerator, backend, reporter, measurer), | 246 dietParser = new DietParserTask(idGenerator, backend, reporter, measurer), |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 /// The closed world after resolution but currently refined by inference. | 289 /// The closed world after resolution but currently refined by inference. |
296 ClosedWorldRefiner get inferenceWorld => _world; | 290 ClosedWorldRefiner get inferenceWorld => _world; |
297 | 291 |
298 /// The closed world after resolution and inference. | 292 /// The closed world after resolution and inference. |
299 ClosedWorld get closedWorld { | 293 ClosedWorld get closedWorld { |
300 assert(invariant(CURRENT_ELEMENT_SPANNABLE, _world.isClosed, | 294 assert(invariant(CURRENT_ELEMENT_SPANNABLE, _world.isClosed, |
301 message: "Closed world not computed yet.")); | 295 message: "Closed world not computed yet.")); |
302 return _world; | 296 return _world; |
303 } | 297 } |
304 | 298 |
299 /// Creates the backend. | |
300 /// | |
301 /// Override this to mock the backend for testing. | |
302 Backend createBackend() { | |
303 return new js_backend.JavaScriptBackend(this, | |
304 generateSourceMap: options.generateSourceMap, | |
305 useStartupEmitter: options.useStartupEmitter, | |
306 useNewSourceInfo: options.useNewSourceInfo, | |
307 useKernel: options.useKernel); | |
308 } | |
309 | |
305 /// Creates the scanner task. | 310 /// Creates the scanner task. |
306 /// | 311 /// |
307 /// Override this to mock the scanner for testing. | 312 /// Override this to mock the scanner for testing. |
308 ScannerTask createScannerTask() => | 313 ScannerTask createScannerTask() => |
309 new ScannerTask(dietParser, reporter, measurer, | 314 new ScannerTask(dietParser, reporter, measurer, |
310 preserveComments: options.preserveComments, commentMap: commentMap); | 315 preserveComments: options.preserveComments, commentMap: commentMap); |
311 | 316 |
317 /// Creates the resolution object. | |
318 /// | |
319 /// Override this to mock resolution for testing. | |
320 Resolution createResolution() => new CompilerResolution(this); | |
321 | |
312 /// Creates the resolver task. | 322 /// Creates the resolver task. |
313 /// | 323 /// |
314 /// Override this to mock the resolver for testing. | 324 /// Override this to mock the resolver for testing. |
315 ResolverTask createResolverTask() { | 325 ResolverTask createResolverTask() { |
316 return new ResolverTask( | 326 return new ResolverTask( |
317 resolution, backend.constantCompilerTask, openWorld, measurer); | 327 resolution, backend.constantCompilerTask, openWorld, measurer); |
318 } | 328 } |
319 | 329 |
320 // TODO(johnniwinther): Rename these appropriately when unification of worlds/ | 330 // TODO(johnniwinther): Rename these appropriately when unification of worlds/ |
321 // universes is complete. | 331 // universes is complete. |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 /// when the '--analyze-main' option is used. | 628 /// when the '--analyze-main' option is used. |
619 Future<LibraryElement> analyzeUri(Uri libraryUri, | 629 Future<LibraryElement> analyzeUri(Uri libraryUri, |
620 {bool skipLibraryWithPartOfTag: true}) { | 630 {bool skipLibraryWithPartOfTag: true}) { |
621 assert(options.analyzeMain); | 631 assert(options.analyzeMain); |
622 reporter.log('Analyzing $libraryUri (${options.buildId})'); | 632 reporter.log('Analyzing $libraryUri (${options.buildId})'); |
623 return libraryLoader | 633 return libraryLoader |
624 .loadLibrary(libraryUri, skipFileWithPartOfTag: true) | 634 .loadLibrary(libraryUri, skipFileWithPartOfTag: true) |
625 .then((LibraryElement library) { | 635 .then((LibraryElement library) { |
626 if (library == null) return null; | 636 if (library == null) return null; |
627 enqueuer.resolution.applyImpact(computeImpactForLibrary(library)); | 637 enqueuer.resolution.applyImpact(computeImpactForLibrary(library)); |
628 emptyQueue(enqueuer.resolution); | 638 emptyQueue(enqueuer.resolution, onProgress: showResolutionProgress); |
629 enqueuer.resolution.logSummary(reporter.log); | 639 enqueuer.resolution.logSummary(reporter.log); |
630 return library; | 640 return library; |
631 }); | 641 }); |
632 } | 642 } |
633 | 643 |
634 /// Performs the compilation when all libraries have been loaded. | 644 /// Performs the compilation when all libraries have been loaded. |
635 void compileLoadedLibraries() => | 645 void compileLoadedLibraries() => |
636 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { | 646 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { |
637 WorldImpact mainImpact = computeMain(); | 647 WorldImpact mainImpact = computeMain(); |
638 | 648 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
679 } | 689 } |
680 // Elements required by enqueueHelpers are global dependencies | 690 // Elements required by enqueueHelpers are global dependencies |
681 // that are not pulled in by a particular element. | 691 // that are not pulled in by a particular element. |
682 enqueuer.resolution.applyImpact(backend.computeHelpersImpact()); | 692 enqueuer.resolution.applyImpact(backend.computeHelpersImpact()); |
683 resolveLibraryMetadata(); | 693 resolveLibraryMetadata(); |
684 reporter.log('Resolving...'); | 694 reporter.log('Resolving...'); |
685 if (mainFunction != null && !mainFunction.isMalformed) { | 695 if (mainFunction != null && !mainFunction.isMalformed) { |
686 mainFunction.computeType(resolution); | 696 mainFunction.computeType(resolution); |
687 } | 697 } |
688 | 698 |
689 processQueue(enqueuer.resolution, mainFunction); | 699 processQueue(enqueuer.resolution, mainFunction, |
700 onProgress: showResolutionProgress); | |
690 enqueuer.resolution.logSummary(reporter.log); | 701 enqueuer.resolution.logSummary(reporter.log); |
691 | 702 |
692 _reporter.reportSuppressedMessagesSummary(); | 703 _reporter.reportSuppressedMessagesSummary(); |
693 | 704 |
694 if (compilationFailed) { | 705 if (compilationFailed) { |
695 if (!options.generateCodeWithCompileTimeErrors) return; | 706 if (!options.generateCodeWithCompileTimeErrors) return; |
696 if (!backend | 707 if (!backend |
697 .enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) { | 708 .enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) { |
698 return; | 709 return; |
699 } | 710 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 backend.onCodegenStart(); | 747 backend.onCodegenStart(); |
737 if (hasIsolateSupport) { | 748 if (hasIsolateSupport) { |
738 enqueuer.codegen | 749 enqueuer.codegen |
739 .applyImpact(backend.enableIsolateSupport(forResolution: false)); | 750 .applyImpact(backend.enableIsolateSupport(forResolution: false)); |
740 } | 751 } |
741 if (compileAll) { | 752 if (compileAll) { |
742 libraryLoader.libraries.forEach((LibraryElement library) { | 753 libraryLoader.libraries.forEach((LibraryElement library) { |
743 enqueuer.codegen.applyImpact(computeImpactForLibrary(library)); | 754 enqueuer.codegen.applyImpact(computeImpactForLibrary(library)); |
744 }); | 755 }); |
745 } | 756 } |
746 processQueue(enqueuer.codegen, mainFunction); | 757 processQueue(enqueuer.codegen, mainFunction, |
758 onProgress: showCodegenProgress); | |
747 enqueuer.codegen.logSummary(reporter.log); | 759 enqueuer.codegen.logSummary(reporter.log); |
748 | 760 |
749 int programSize = backend.assembleProgram(); | 761 int programSize = backend.assembleProgram(); |
750 | 762 |
751 if (options.dumpInfo) { | 763 if (options.dumpInfo) { |
752 dumpInfoTask.reportSize(programSize); | 764 dumpInfoTask.reportSize(programSize); |
753 dumpInfoTask.dumpInfo(); | 765 dumpInfoTask.dumpInfo(); |
754 } | 766 } |
755 | 767 |
756 backend.sourceInformationStrategy.onComplete(); | 768 backend.sourceInformationStrategy.onComplete(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
834 for (MetadataAnnotation metadata in library.metadata) { | 846 for (MetadataAnnotation metadata in library.metadata) { |
835 metadata.ensureResolved(resolution); | 847 metadata.ensureResolved(resolution); |
836 } | 848 } |
837 } | 849 } |
838 } | 850 } |
839 } | 851 } |
840 | 852 |
841 /** | 853 /** |
842 * Empty the [enqueuer] queue. | 854 * Empty the [enqueuer] queue. |
843 */ | 855 */ |
844 void emptyQueue(Enqueuer enqueuer) { | 856 void emptyQueue(Enqueuer enqueuer, {void onProgress()}) { |
845 selfTask.measureSubtask("Compiler.emptyQueue", () { | 857 selfTask.measureSubtask("Compiler.emptyQueue", () { |
846 enqueuer.forEach((WorkItem work) { | 858 enqueuer.forEach((WorkItem work) { |
859 if (onProgress != null) { | |
860 onProgress(); | |
861 } | |
847 reporter.withCurrentElement( | 862 reporter.withCurrentElement( |
848 work.element, | 863 work.element, |
849 () => selfTask.measureSubtask("world.applyImpact", () { | 864 () => selfTask.measureSubtask("world.applyImpact", () { |
850 enqueuer.applyImpact( | 865 enqueuer.applyImpact( |
851 selfTask.measureSubtask( | 866 selfTask.measureSubtask("work.run", () => work.run()), |
852 "work.run", () => work.run(this, enqueuer)), | |
853 impactSource: work.element); | 867 impactSource: work.element); |
854 })); | 868 })); |
855 }); | 869 }); |
856 }); | 870 }); |
857 } | 871 } |
858 | 872 |
859 void processQueue(Enqueuer enqueuer, MethodElement mainMethod) { | 873 void processQueue(Enqueuer enqueuer, MethodElement mainMethod, |
874 {void onProgress()}) { | |
860 selfTask.measureSubtask("Compiler.processQueue", () { | 875 selfTask.measureSubtask("Compiler.processQueue", () { |
861 enqueuer.open(impactStrategy); | 876 enqueuer.open(impactStrategy); |
862 enqueuer.applyImpact(enqueuer.nativeEnqueuer | 877 enqueuer.applyImpact(enqueuer.nativeEnqueuer |
863 .processNativeClasses(libraryLoader.libraries)); | 878 .processNativeClasses(libraryLoader.libraries)); |
864 if (mainMethod != null && !mainMethod.isMalformed) { | 879 if (mainMethod != null && !mainMethod.isMalformed) { |
865 enqueuer.applyImpact(backend.computeMainImpact(mainMethod, | 880 enqueuer.applyImpact(backend.computeMainImpact(mainMethod, |
866 forResolution: enqueuer.isResolutionQueue)); | 881 forResolution: enqueuer.isResolutionQueue)); |
867 } | 882 } |
868 if (options.verbose) { | 883 if (options.verbose) { |
869 progress.reset(); | 884 progress.reset(); |
870 } | 885 } |
871 emptyQueue(enqueuer); | 886 emptyQueue(enqueuer, onProgress: onProgress); |
872 enqueuer.queueIsClosed = true; | 887 enqueuer.queueIsClosed = true; |
873 enqueuer.close(); | 888 enqueuer.close(); |
874 // Notify the impact strategy impacts are no longer needed for this | 889 // Notify the impact strategy impacts are no longer needed for this |
875 // enqueuer. | 890 // enqueuer. |
876 impactStrategy.onImpactUsed(enqueuer.impactUse); | 891 impactStrategy.onImpactUsed(enqueuer.impactUse); |
877 backend.onQueueClosed(); | 892 backend.onQueueClosed(); |
878 assert(compilationFailed || | 893 assert(compilationFailed || |
879 enqueuer.checkNoEnqueuedInvokedInstanceMethods()); | 894 enqueuer.checkNoEnqueuedInvokedInstanceMethods()); |
880 }); | 895 }); |
881 } | 896 } |
(...skipping 30 matching lines...) Expand all Loading... | |
912 resolved.remove(e); | 927 resolved.remove(e); |
913 } | 928 } |
914 } | 929 } |
915 reporter.log('Excess resolution work: ${resolved.length}.'); | 930 reporter.log('Excess resolution work: ${resolved.length}.'); |
916 for (Element e in resolved) { | 931 for (Element e in resolved) { |
917 reporter.reportWarningMessage(e, MessageKind.GENERIC, | 932 reporter.reportWarningMessage(e, MessageKind.GENERIC, |
918 {'text': 'Warning: $e resolved but not compiled.'}); | 933 {'text': 'Warning: $e resolved but not compiled.'}); |
919 } | 934 } |
920 } | 935 } |
921 | 936 |
922 WorldImpact analyzeElement(Element element) => | 937 /* |
Harry Terkelsen
2016/11/28 19:24:29
delete commented code
Johnni Winther
2016/11/29 08:43:38
Done.
| |
923 selfTask.measureSubtask("Compiler.analyzeElement", () { | 938 WorldImpact analyze(ResolutionWorkItem work) => |
924 assert(invariant( | 939 selfTask.measureSubtask("Compiler.analyze", () { |
925 element, | 940 assert(invariant(work.element, !work.isAnalyzed, |
926 element.impliesType || | 941 message: 'Element ${work.element} has already been analyzed')); |
927 element.isField || | 942 AstElement element = work.element; |
928 element.isFunction || | |
929 element.isConstructor || | |
930 element.isGetter || | |
931 element.isSetter, | |
932 message: 'Unexpected element kind: ${element.kind}')); | |
933 assert(invariant(element, element is AnalyzableElement, | |
934 message: 'Element $element is not analyzable.')); | |
935 assert(invariant(element, element.isDeclaration)); | |
936 return resolution.computeWorldImpact(element); | 943 return resolution.computeWorldImpact(element); |
937 }); | 944 }); |
938 | 945 */ |
939 WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) => | 946 void showResolutionProgress() { |
940 selfTask.measureSubtask("Compiler.analyze", () { | |
941 assert(invariant(work.element, identical(world, enqueuer.resolution))); | |
942 assert(invariant(work.element, !work.isAnalyzed, | |
943 message: 'Element ${work.element} has already been analyzed')); | |
944 if (shouldPrintProgress) { | |
945 // TODO(ahe): Add structured diagnostics to the compiler API and | |
946 // use it to separate this from the --verbose option. | |
947 if (phase == PHASE_RESOLVING) { | |
948 reporter | |
949 .log('Resolved ${enqueuer.resolution.processedElements.length} ' | |
950 'elements.'); | |
951 progress.reset(); | |
952 } | |
953 } | |
954 AstElement element = work.element; | |
955 if (world.hasBeenProcessed(element)) { | |
956 return const WorldImpact(); | |
957 } | |
958 WorldImpact worldImpact = analyzeElement(element); | |
959 world.registerProcessedElement(element); | |
960 return worldImpact; | |
961 }); | |
962 | |
963 WorldImpact codegen(CodegenWorkItem work, Enqueuer world) { | |
964 assert(invariant(work.element, identical(world, enqueuer.codegen))); | |
965 if (shouldPrintProgress) { | 947 if (shouldPrintProgress) { |
966 // TODO(ahe): Add structured diagnostics to the compiler API and | 948 // TODO(ahe): Add structured diagnostics to the compiler API and |
967 // use it to separate this from the --verbose option. | 949 // use it to separate this from the --verbose option. |
950 assert(phase == PHASE_RESOLVING); | |
951 reporter.log('Resolved ${enqueuer.resolution.processedElements.length} ' | |
952 'elements.'); | |
953 progress.reset(); | |
954 } | |
955 } | |
956 | |
957 void showCodegenProgress() { | |
958 if (shouldPrintProgress) { | |
959 // TODO(ahe): Add structured diagnostics to the compiler API and | |
960 // use it to separate this from the --verbose option. | |
968 reporter.log( | 961 reporter.log( |
969 'Compiled ${enqueuer.codegen.processedEntities.length} methods.'); | 962 'Compiled ${enqueuer.codegen.processedEntities.length} methods.'); |
970 progress.reset(); | 963 progress.reset(); |
971 } | 964 } |
972 return backend.codegen(work); | |
973 } | 965 } |
974 | 966 |
975 void reportDiagnostic(DiagnosticMessage message, | 967 void reportDiagnostic(DiagnosticMessage message, |
976 List<DiagnosticMessage> infos, api.Diagnostic kind); | 968 List<DiagnosticMessage> infos, api.Diagnostic kind); |
977 | 969 |
978 void reportCrashInUserCode(String message, exception, stackTrace) { | 970 void reportCrashInUserCode(String message, exception, stackTrace) { |
979 reporter.onCrashInUserCode(message, exception, stackTrace); | 971 reporter.onCrashInUserCode(message, exception, stackTrace); |
980 } | 972 } |
981 | 973 |
982 /// Messages for which compile-time errors are reported but compilation | 974 /// Messages for which compile-time errors are reported but compilation |
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1938 {'warnings': info.warnings, 'hints': info.hints, 'uri': uri}, | 1930 {'warnings': info.warnings, 'hints': info.hints, 'uri': uri}, |
1939 options.terseDiagnostics); | 1931 options.terseDiagnostics); |
1940 reportDiagnostic(new DiagnosticMessage(null, null, message), | 1932 reportDiagnostic(new DiagnosticMessage(null, null, message), |
1941 const <DiagnosticMessage>[], api.Diagnostic.HINT); | 1933 const <DiagnosticMessage>[], api.Diagnostic.HINT); |
1942 }); | 1934 }); |
1943 } | 1935 } |
1944 } | 1936 } |
1945 } | 1937 } |
1946 | 1938 |
1947 // TODO(johnniwinther): Move [ResolverTask] here. | 1939 // TODO(johnniwinther): Move [ResolverTask] here. |
1948 class _CompilerResolution implements Resolution { | 1940 class CompilerResolution implements Resolution { |
1949 final Compiler compiler; | 1941 final Compiler _compiler; |
1950 final Map<Element, ResolutionImpact> _resolutionImpactCache = | 1942 final Map<Element, ResolutionImpact> _resolutionImpactCache = |
1951 <Element, ResolutionImpact>{}; | 1943 <Element, ResolutionImpact>{}; |
1952 final Map<Element, WorldImpact> _worldImpactCache = <Element, WorldImpact>{}; | 1944 final Map<Element, WorldImpact> _worldImpactCache = <Element, WorldImpact>{}; |
1953 bool retainCachesForTesting = false; | 1945 bool retainCachesForTesting = false; |
1954 | 1946 |
1955 _CompilerResolution(this.compiler); | 1947 CompilerResolution(this._compiler); |
1956 | 1948 |
1957 @override | 1949 @override |
1958 DiagnosticReporter get reporter => compiler.reporter; | 1950 DiagnosticReporter get reporter => _compiler.reporter; |
1959 | 1951 |
1960 @override | 1952 @override |
1961 ParsingContext get parsingContext => compiler.parsingContext; | 1953 ParsingContext get parsingContext => _compiler.parsingContext; |
1962 | 1954 |
1963 @override | 1955 @override |
1964 CoreClasses get coreClasses => compiler.coreClasses; | 1956 CoreClasses get coreClasses => _compiler.coreClasses; |
1965 | 1957 |
1966 @override | 1958 @override |
1967 CoreTypes get coreTypes => compiler.coreTypes; | 1959 CoreTypes get coreTypes => _compiler.coreTypes; |
1968 | 1960 |
1969 @override | 1961 @override |
1970 CommonElements get commonElements => compiler.commonElements; | 1962 CommonElements get commonElements => _compiler.commonElements; |
1971 | 1963 |
1972 @override | 1964 @override |
1973 Types get types => compiler.types; | 1965 Types get types => _compiler.types; |
1974 | 1966 |
1975 @override | 1967 @override |
1976 Target get target => compiler.backend; | 1968 Target get target => _compiler.backend; |
1977 | 1969 |
1978 @override | 1970 @override |
1979 ResolverTask get resolver => compiler.resolver; | 1971 ResolverTask get resolver => _compiler.resolver; |
1980 | 1972 |
1981 @override | 1973 @override |
1982 ResolutionEnqueuer get enqueuer => compiler.enqueuer.resolution; | 1974 ResolutionEnqueuer get enqueuer => _compiler.enqueuer.resolution; |
1983 | 1975 |
1984 @override | 1976 @override |
1985 CompilerOptions get options => compiler.options; | 1977 CompilerOptions get options => _compiler.options; |
1986 | 1978 |
1987 @override | 1979 @override |
1988 IdGenerator get idGenerator => compiler.idGenerator; | 1980 IdGenerator get idGenerator => _compiler.idGenerator; |
1989 | 1981 |
1990 @override | 1982 @override |
1991 ConstantEnvironment get constants => compiler.constants; | 1983 ConstantEnvironment get constants => _compiler.constants; |
1992 | 1984 |
1993 @override | 1985 @override |
1994 MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask => | 1986 MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask => |
1995 compiler.mirrorUsageAnalyzerTask; | 1987 _compiler.mirrorUsageAnalyzerTask; |
1996 | 1988 |
1997 @override | 1989 @override |
1998 LibraryElement get coreLibrary => compiler._coreTypes.coreLibrary; | 1990 LibraryElement get coreLibrary => _compiler._coreTypes.coreLibrary; |
1999 | 1991 |
2000 @override | 1992 @override |
2001 bool get wasProxyConstantComputedTestingOnly => _proxyConstant != null; | 1993 bool get wasProxyConstantComputedTestingOnly => _proxyConstant != null; |
2002 | 1994 |
2003 @override | 1995 @override |
2004 void registerClass(ClassElement cls) { | 1996 void registerClass(ClassElement cls) { |
2005 compiler.openWorld.registerClass(cls); | 1997 _compiler.openWorld.registerClass(cls); |
2006 } | 1998 } |
2007 | 1999 |
2008 @override | 2000 @override |
2009 void resolveClass(ClassElement cls) { | 2001 void resolveClass(ClassElement cls) { |
2010 compiler.resolver.resolveClass(cls); | 2002 _compiler.resolver.resolveClass(cls); |
2011 } | 2003 } |
2012 | 2004 |
2013 @override | 2005 @override |
2014 void resolveTypedef(TypedefElement typdef) { | 2006 void resolveTypedef(TypedefElement typdef) { |
2015 compiler.resolver.resolve(typdef); | 2007 _compiler.resolver.resolve(typdef); |
2016 } | 2008 } |
2017 | 2009 |
2018 @override | 2010 @override |
2019 void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation) { | 2011 void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation) { |
2020 compiler.resolver.resolveMetadataAnnotation(metadataAnnotation); | 2012 _compiler.resolver.resolveMetadataAnnotation(metadataAnnotation); |
2021 } | 2013 } |
2022 | 2014 |
2023 @override | 2015 @override |
2024 FunctionSignature resolveSignature(FunctionElement function) { | 2016 FunctionSignature resolveSignature(FunctionElement function) { |
2025 return compiler.resolver.resolveSignature(function); | 2017 return _compiler.resolver.resolveSignature(function); |
2026 } | 2018 } |
2027 | 2019 |
2028 @override | 2020 @override |
2029 DartType resolveTypeAnnotation(Element element, TypeAnnotation node) { | 2021 DartType resolveTypeAnnotation(Element element, TypeAnnotation node) { |
2030 return compiler.resolver.resolveTypeAnnotation(element, node); | 2022 return _compiler.resolver.resolveTypeAnnotation(element, node); |
2031 } | 2023 } |
2032 | 2024 |
2033 @override | 2025 @override |
2034 void ensureResolved(Element element) { | 2026 void ensureResolved(Element element) { |
2035 if (compiler.serialization.isDeserialized(element)) { | 2027 if (_compiler.serialization.isDeserialized(element)) { |
2036 return; | 2028 return; |
2037 } | 2029 } |
2038 computeWorldImpact(element); | 2030 computeWorldImpact(element); |
2039 } | 2031 } |
2040 | 2032 |
2041 @override | 2033 @override |
2042 void ensureClassMembers(ClassElement element) { | 2034 void ensureClassMembers(ClassElement element) { |
2043 if (!compiler.serialization.isDeserialized(element)) { | 2035 if (!_compiler.serialization.isDeserialized(element)) { |
2044 compiler.resolver.checkClass(element); | 2036 _compiler.resolver.checkClass(element); |
2045 } | 2037 } |
2046 } | 2038 } |
2047 | 2039 |
2048 @override | 2040 @override |
2049 void registerCompileTimeError(Element element, DiagnosticMessage message) => | 2041 void registerCompileTimeError(Element element, DiagnosticMessage message) => |
2050 compiler.registerCompileTimeError(element, message); | 2042 _compiler.registerCompileTimeError(element, message); |
2051 | 2043 |
2052 @override | 2044 @override |
2053 bool hasResolvedAst(ExecutableElement element) { | 2045 bool hasResolvedAst(ExecutableElement element) { |
2054 assert(invariant(element, element.isDeclaration, | 2046 assert(invariant(element, element.isDeclaration, |
2055 message: "Element $element must be the declaration.")); | 2047 message: "Element $element must be the declaration.")); |
2056 if (compiler.serialization.isDeserialized(element)) { | 2048 if (_compiler.serialization.isDeserialized(element)) { |
2057 return compiler.serialization.hasResolvedAst(element); | 2049 return _compiler.serialization.hasResolvedAst(element); |
2058 } | 2050 } |
2059 return hasBeenResolved(element.memberContext.declaration) && | 2051 return hasBeenResolved(element.memberContext.declaration) && |
2060 element.hasResolvedAst; | 2052 element.hasResolvedAst; |
2061 } | 2053 } |
2062 | 2054 |
2063 @override | 2055 @override |
2064 ResolvedAst getResolvedAst(ExecutableElement element) { | 2056 ResolvedAst getResolvedAst(ExecutableElement element) { |
2065 assert(invariant(element, element.isDeclaration, | 2057 assert(invariant(element, element.isDeclaration, |
2066 message: "Element $element must be the declaration.")); | 2058 message: "Element $element must be the declaration.")); |
2067 assert(invariant(element, hasResolvedAst(element), | 2059 assert(invariant(element, hasResolvedAst(element), |
2068 message: "ResolvedAst not available for $element.")); | 2060 message: "ResolvedAst not available for $element.")); |
2069 if (compiler.serialization.isDeserialized(element)) { | 2061 if (_compiler.serialization.isDeserialized(element)) { |
2070 return compiler.serialization.getResolvedAst(element); | 2062 return _compiler.serialization.getResolvedAst(element); |
2071 } | 2063 } |
2072 return element.resolvedAst; | 2064 return element.resolvedAst; |
2073 } | 2065 } |
2074 | 2066 |
2075 @override | 2067 @override |
2076 ResolvedAst computeResolvedAst(Element element) { | 2068 ResolvedAst computeResolvedAst(Element element) { |
2077 ensureResolved(element); | 2069 ensureResolved(element); |
2078 return getResolvedAst(element); | 2070 return getResolvedAst(element); |
2079 } | 2071 } |
2080 | 2072 |
2081 @override | 2073 @override |
2082 bool hasResolutionImpact(Element element) { | 2074 bool hasResolutionImpact(Element element) { |
2083 assert(invariant(element, element.isDeclaration, | 2075 assert(invariant(element, element.isDeclaration, |
2084 message: "Element $element must be the declaration.")); | 2076 message: "Element $element must be the declaration.")); |
2085 if (compiler.serialization.isDeserialized(element)) { | 2077 if (_compiler.serialization.isDeserialized(element)) { |
2086 return compiler.serialization.hasResolutionImpact(element); | 2078 return _compiler.serialization.hasResolutionImpact(element); |
2087 } | 2079 } |
2088 return _resolutionImpactCache.containsKey(element); | 2080 return _resolutionImpactCache.containsKey(element); |
2089 } | 2081 } |
2090 | 2082 |
2091 @override | 2083 @override |
2092 ResolutionImpact getResolutionImpact(Element element) { | 2084 ResolutionImpact getResolutionImpact(Element element) { |
2093 assert(invariant(element, element.isDeclaration, | 2085 assert(invariant(element, element.isDeclaration, |
2094 message: "Element $element must be the declaration.")); | 2086 message: "Element $element must be the declaration.")); |
2095 ResolutionImpact resolutionImpact; | 2087 ResolutionImpact resolutionImpact; |
2096 if (compiler.serialization.isDeserialized(element)) { | 2088 if (_compiler.serialization.isDeserialized(element)) { |
2097 resolutionImpact = compiler.serialization.getResolutionImpact(element); | 2089 resolutionImpact = _compiler.serialization.getResolutionImpact(element); |
2098 } else { | 2090 } else { |
2099 resolutionImpact = _resolutionImpactCache[element]; | 2091 resolutionImpact = _resolutionImpactCache[element]; |
2100 } | 2092 } |
2101 assert(invariant(element, resolutionImpact != null, | 2093 assert(invariant(element, resolutionImpact != null, |
2102 message: "ResolutionImpact not available for $element.")); | 2094 message: "ResolutionImpact not available for $element.")); |
2103 return resolutionImpact; | 2095 return resolutionImpact; |
2104 } | 2096 } |
2105 | 2097 |
2106 @override | 2098 @override |
2107 WorldImpact getWorldImpact(Element element) { | 2099 WorldImpact getWorldImpact(Element element) { |
2108 assert(invariant(element, element.isDeclaration, | 2100 assert(invariant(element, element.isDeclaration, |
2109 message: "Element $element must be the declaration.")); | 2101 message: "Element $element must be the declaration.")); |
2110 WorldImpact worldImpact = _worldImpactCache[element]; | 2102 WorldImpact worldImpact = _worldImpactCache[element]; |
2111 assert(invariant(element, worldImpact != null, | 2103 assert(invariant(element, worldImpact != null, |
2112 message: "WorldImpact not computed for $element.")); | 2104 message: "WorldImpact not computed for $element.")); |
2113 return worldImpact; | 2105 return worldImpact; |
2114 } | 2106 } |
2115 | 2107 |
2116 @override | 2108 @override |
2117 WorldImpact computeWorldImpact(Element element) { | 2109 WorldImpact computeWorldImpact(Element element) { |
2118 assert(invariant(element, element.isDeclaration, | 2110 return _compiler.selfTask.measureSubtask("Resolution.computeWorldImpact", |
2119 message: "Element $element must be the declaration.")); | 2111 () { |
2120 return _worldImpactCache.putIfAbsent(element, () { | 2112 assert(invariant( |
2121 assert(compiler.parser != null); | 2113 element, |
2122 Node tree = compiler.parser.parse(element); | 2114 element.impliesType || |
2123 assert(invariant(element, !element.isSynthesized || tree == null)); | 2115 element.isField || |
2124 ResolutionImpact resolutionImpact = compiler.resolver.resolve(element); | 2116 element.isFunction || |
2117 element.isConstructor || | |
2118 element.isGetter || | |
2119 element.isSetter, | |
2120 message: 'Unexpected element kind: ${element.kind}')); | |
2121 assert(invariant(element, element is AnalyzableElement, | |
2122 message: 'Element $element is not analyzable.')); | |
2123 assert(invariant(element, element.isDeclaration)); | |
Harry Terkelsen
2016/11/28 19:24:29
you have the same invariant twice
Johnni Winther
2016/11/29 08:43:38
One removed!
| |
2124 assert(invariant(element, element.isDeclaration, | |
2125 message: "Element $element must be the declaration.")); | |
2126 return _worldImpactCache.putIfAbsent(element, () { | |
2127 assert(_compiler.parser != null); | |
2128 Node tree = _compiler.parser.parse(element); | |
2129 assert(invariant(element, !element.isSynthesized || tree == null)); | |
2130 ResolutionImpact resolutionImpact = _compiler.resolver.resolve(element); | |
2125 | 2131 |
2126 if (compiler.serialization.supportSerialization || | 2132 if (_compiler.serialization.supportSerialization || |
2127 retainCachesForTesting) { | 2133 retainCachesForTesting) { |
2128 // [ResolutionImpact] is currently only used by serialization. The | 2134 // [ResolutionImpact] is currently only used by serialization. The |
2129 // enqueuer uses the [WorldImpact] which is always cached. | 2135 // enqueuer uses the [WorldImpact] which is always cached. |
2130 // TODO(johnniwinther): Align these use cases better; maybe only | 2136 // TODO(johnniwinther): Align these use cases better; maybe only |
2131 // cache [ResolutionImpact] and let the enqueuer transform it into | 2137 // cache [ResolutionImpact] and let the enqueuer transform it into |
2132 // a [WorldImpact]. | 2138 // a [WorldImpact]. |
2133 _resolutionImpactCache[element] = resolutionImpact; | 2139 _resolutionImpactCache[element] = resolutionImpact; |
2134 } | 2140 } |
2135 if (tree != null && !compiler.options.analyzeSignaturesOnly) { | 2141 if (tree != null && !_compiler.options.analyzeSignaturesOnly) { |
2136 // TODO(het): don't do this if suppressWarnings is on, currently we have | 2142 // TODO(het): don't do this if suppressWarnings is on, currently we |
2137 // to do it because the typechecker also sets types | 2143 // have to do it because the typechecker also sets types |
2138 // Only analyze nodes with a corresponding [TreeElements]. | 2144 // Only analyze nodes with a corresponding [TreeElements]. |
2139 compiler.checker.check(element); | 2145 _compiler.checker.check(element); |
2140 } | 2146 } |
2141 return transformResolutionImpact(element, resolutionImpact); | 2147 return transformResolutionImpact(element, resolutionImpact); |
2148 }); | |
2142 }); | 2149 }); |
2143 } | 2150 } |
2144 | 2151 |
2145 @override | 2152 @override |
2146 WorldImpact transformResolutionImpact( | 2153 WorldImpact transformResolutionImpact( |
2147 Element element, ResolutionImpact resolutionImpact) { | 2154 Element element, ResolutionImpact resolutionImpact) { |
2148 WorldImpact worldImpact = compiler.backend.impactTransformer | 2155 WorldImpact worldImpact = _compiler.backend.impactTransformer |
2149 .transformResolutionImpact( | 2156 .transformResolutionImpact( |
2150 compiler.enqueuer.resolution, resolutionImpact); | 2157 _compiler.enqueuer.resolution, resolutionImpact); |
2151 _worldImpactCache[element] = worldImpact; | 2158 _worldImpactCache[element] = worldImpact; |
2152 return worldImpact; | 2159 return worldImpact; |
2153 } | 2160 } |
2154 | 2161 |
2155 @override | 2162 @override |
2156 void uncacheWorldImpact(Element element) { | 2163 void uncacheWorldImpact(Element element) { |
2157 assert(invariant(element, element.isDeclaration, | 2164 assert(invariant(element, element.isDeclaration, |
2158 message: "Element $element must be the declaration.")); | 2165 message: "Element $element must be the declaration.")); |
2159 if (retainCachesForTesting) return; | 2166 if (retainCachesForTesting) return; |
2160 if (compiler.serialization.isDeserialized(element)) return; | 2167 if (_compiler.serialization.isDeserialized(element)) return; |
2161 assert(invariant(element, _worldImpactCache[element] != null, | 2168 assert(invariant(element, _worldImpactCache[element] != null, |
2162 message: "WorldImpact not computed for $element.")); | 2169 message: "WorldImpact not computed for $element.")); |
2163 _worldImpactCache[element] = const WorldImpact(); | 2170 _worldImpactCache[element] = const WorldImpact(); |
2164 _resolutionImpactCache.remove(element); | 2171 _resolutionImpactCache.remove(element); |
2165 } | 2172 } |
2166 | 2173 |
2167 @override | 2174 @override |
2168 void emptyCache() { | 2175 void emptyCache() { |
2169 if (retainCachesForTesting) return; | 2176 if (retainCachesForTesting) return; |
2170 for (Element element in _worldImpactCache.keys) { | 2177 for (Element element in _worldImpactCache.keys) { |
2171 _worldImpactCache[element] = const WorldImpact(); | 2178 _worldImpactCache[element] = const WorldImpact(); |
2172 } | 2179 } |
2173 _resolutionImpactCache.clear(); | 2180 _resolutionImpactCache.clear(); |
2174 } | 2181 } |
2175 | 2182 |
2176 @override | 2183 @override |
2177 bool hasBeenResolved(Element element) { | 2184 bool hasBeenResolved(Element element) { |
2178 return _worldImpactCache.containsKey(element); | 2185 return _worldImpactCache.containsKey(element); |
2179 } | 2186 } |
2180 | 2187 |
2181 @override | 2188 @override |
2182 ResolutionWorkItem createWorkItem(Element element) { | 2189 ResolutionWorkItem createWorkItem(Element element) { |
2183 if (compiler.serialization.isDeserialized(element)) { | 2190 if (_compiler.serialization.isDeserialized(element)) { |
2184 return compiler.serialization.createResolutionWorkItem(element); | 2191 return _compiler.serialization.createResolutionWorkItem(element); |
2185 } else { | 2192 } else { |
2186 return new ResolutionWorkItem(element); | 2193 return new ResolutionWorkItem(this, element); |
2187 } | 2194 } |
2188 } | 2195 } |
2189 | 2196 |
2190 @override | 2197 @override |
2191 void forgetElement(Element element) { | 2198 void forgetElement(Element element) { |
2192 _worldImpactCache.remove(element); | 2199 _worldImpactCache.remove(element); |
2193 _resolutionImpactCache.remove(element); | 2200 _resolutionImpactCache.remove(element); |
2194 } | 2201 } |
2195 | 2202 |
2196 ConstantValue _proxyConstant; | 2203 ConstantValue _proxyConstant; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2253 _ElementScanner(this.scanner); | 2260 _ElementScanner(this.scanner); |
2254 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); | 2261 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); |
2255 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); | 2262 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); |
2256 } | 2263 } |
2257 | 2264 |
2258 class _EmptyEnvironment implements Environment { | 2265 class _EmptyEnvironment implements Environment { |
2259 const _EmptyEnvironment(); | 2266 const _EmptyEnvironment(); |
2260 | 2267 |
2261 String valueOf(String key) => null; | 2268 String valueOf(String key) => null; |
2262 } | 2269 } |
OLD | NEW |