Chromium Code Reviews| 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 |