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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 | 396 |
397 void unimplemented(Spannable spannable, String methodName) { | 397 void unimplemented(Spannable spannable, String methodName) { |
398 reporter.internalError(spannable, "$methodName not implemented."); | 398 reporter.internalError(spannable, "$methodName not implemented."); |
399 } | 399 } |
400 | 400 |
401 // Compiles the dart script at [uri]. | 401 // Compiles the dart script at [uri]. |
402 // | 402 // |
403 // The resulting future will complete with true if the compilation | 403 // The resulting future will complete with true if the compilation |
404 // succeeded. | 404 // succeeded. |
405 Future<bool> run(Uri uri) => selfTask.measureSubtask("Compiler.run", () { | 405 Future<bool> run(Uri uri) => selfTask.measureSubtask("Compiler.run", () { |
406 measurer.startWallClock(); | 406 measurer.startWallClock(); |
407 | 407 |
408 return new Future.sync(() => runInternal(uri)) | 408 return new Future.sync(() => runInternal(uri)) |
409 .catchError((error) => _reporter.onError(uri, error)) | 409 .catchError((error) => _reporter.onError(uri, error)) |
410 .whenComplete(() { | 410 .whenComplete(() { |
411 tracer.close(); | 411 tracer.close(); |
412 measurer.stopWallClock(); | 412 measurer.stopWallClock(); |
413 }).then((_) { | 413 }).then((_) { |
414 return !compilationFailed; | 414 return !compilationFailed; |
415 }); | 415 }); |
416 }); | 416 }); |
417 | 417 |
418 /// This method is called immediately after the [LibraryElement] [library] has | 418 /// This method is called immediately after the [LibraryElement] [library] has |
419 /// been created. | 419 /// been created. |
420 /// | 420 /// |
421 /// Use this callback method to store references to specific libraries. | 421 /// Use this callback method to store references to specific libraries. |
422 /// Note that [library] has not been scanned yet, nor has its imports/exports | 422 /// Note that [library] has not been scanned yet, nor has its imports/exports |
423 /// been resolved. | 423 /// been resolved. |
424 void onLibraryCreated(LibraryElement library) { | 424 void onLibraryCreated(LibraryElement library) { |
425 Uri uri = library.canonicalUri; | 425 Uri uri = library.canonicalUri; |
426 if (uri == Uris.dart_core) { | 426 if (uri == Uris.dart_core) { |
(...skipping 15 matching lines...) Expand all Loading... |
442 /// | 442 /// |
443 /// Use [loader] to register the creation and scanning of a patch library | 443 /// Use [loader] to register the creation and scanning of a patch library |
444 /// for [library]. | 444 /// for [library]. |
445 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { | 445 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
446 Uri uri = library.canonicalUri; | 446 Uri uri = library.canonicalUri; |
447 // If the script of the library is synthesized, the library does not exist | 447 // If the script of the library is synthesized, the library does not exist |
448 // and we do not try to load the helpers. | 448 // and we do not try to load the helpers. |
449 // | 449 // |
450 // This could for example happen if dart:async is disabled, then loading it | 450 // This could for example happen if dart:async is disabled, then loading it |
451 // should not try to find the given element. | 451 // should not try to find the given element. |
452 // TODO(johnniwinther): This should just be library.isSynthesized, but that | 452 if (!library.isSynthesized) { |
453 // does not work yet for deserialized elements. | |
454 if (!library.compilationUnit.script.isSynthesized) { | |
455 if (uri == Uris.dart_core) { | 453 if (uri == Uris.dart_core) { |
456 initializeCoreClasses(); | 454 initializeCoreClasses(); |
457 identicalFunction = coreLibrary.find('identical'); | 455 identicalFunction = coreLibrary.find('identical'); |
458 } else if (uri == Uris.dart_mirrors) { | 456 } else if (uri == Uris.dart_mirrors) { |
459 mirrorSystemClass = findRequiredElement(library, 'MirrorSystem'); | 457 mirrorSystemClass = findRequiredElement(library, 'MirrorSystem'); |
460 mirrorsUsedClass = findRequiredElement(library, 'MirrorsUsed'); | 458 mirrorsUsedClass = findRequiredElement(library, 'MirrorsUsed'); |
461 } else if (uri == Uris.dart_async) { | 459 } else if (uri == Uris.dart_async) { |
462 asyncLibrary = library; | 460 asyncLibrary = library; |
463 deferredLibraryClass = findRequiredElement(library, 'DeferredLibrary'); | 461 deferredLibraryClass = findRequiredElement(library, 'DeferredLibrary'); |
464 _coreTypes.futureClass = findRequiredElement(library, 'Future'); | 462 _coreTypes.futureClass = findRequiredElement(library, 'Future'); |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 .then((LibraryElement library) { | 800 .then((LibraryElement library) { |
803 if (library == null) return null; | 801 if (library == null) return null; |
804 fullyEnqueueLibrary(library, enqueuer.resolution); | 802 fullyEnqueueLibrary(library, enqueuer.resolution); |
805 emptyQueue(enqueuer.resolution); | 803 emptyQueue(enqueuer.resolution); |
806 enqueuer.resolution.logSummary(reporter.log); | 804 enqueuer.resolution.logSummary(reporter.log); |
807 return library; | 805 return library; |
808 }); | 806 }); |
809 } | 807 } |
810 | 808 |
811 /// Performs the compilation when all libraries have been loaded. | 809 /// Performs the compilation when all libraries have been loaded. |
812 void compileLoadedLibraries() | 810 void compileLoadedLibraries() => |
813 => selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { | 811 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { |
| 812 computeMain(); |
814 | 813 |
815 computeMain(); | 814 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); |
816 | 815 |
817 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | 816 // In order to see if a library is deferred, we must compute the |
| 817 // compile-time constants that are metadata. This means adding |
| 818 // something to the resolution queue. So we cannot wait with |
| 819 // this until after the resolution queue is processed. |
| 820 deferredLoadTask.beforeResolution(this); |
| 821 impactStrategy = backend.createImpactStrategy( |
| 822 supportDeferredLoad: deferredLoadTask.isProgramSplit, |
| 823 supportDumpInfo: options.dumpInfo, |
| 824 supportSerialization: serialization.supportSerialization); |
818 | 825 |
819 // In order to see if a library is deferred, we must compute the | 826 phase = PHASE_RESOLVING; |
820 // compile-time constants that are metadata. This means adding | 827 if (analyzeAll) { |
821 // something to the resolution queue. So we cannot wait with | 828 libraryLoader.libraries.forEach((LibraryElement library) { |
822 // this until after the resolution queue is processed. | 829 reporter.log('Enqueuing ${library.canonicalUri}'); |
823 deferredLoadTask.beforeResolution(this); | 830 fullyEnqueueLibrary(library, enqueuer.resolution); |
824 impactStrategy = backend.createImpactStrategy( | 831 }); |
825 supportDeferredLoad: deferredLoadTask.isProgramSplit, | 832 } else if (options.analyzeMain) { |
826 supportDumpInfo: options.dumpInfo, | 833 if (mainApp != null) { |
827 supportSerialization: serialization.supportSerialization); | 834 fullyEnqueueLibrary(mainApp, enqueuer.resolution); |
| 835 } |
| 836 if (librariesToAnalyzeWhenRun != null) { |
| 837 for (Uri libraryUri in librariesToAnalyzeWhenRun) { |
| 838 fullyEnqueueLibrary( |
| 839 libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution); |
| 840 } |
| 841 } |
| 842 } |
| 843 // Elements required by enqueueHelpers are global dependencies |
| 844 // that are not pulled in by a particular element. |
| 845 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); |
| 846 resolveLibraryMetadata(); |
| 847 reporter.log('Resolving...'); |
| 848 processQueue(enqueuer.resolution, mainFunction); |
| 849 enqueuer.resolution.logSummary(reporter.log); |
828 | 850 |
829 phase = PHASE_RESOLVING; | 851 _reporter.reportSuppressedMessagesSummary(); |
830 if (analyzeAll) { | 852 |
831 libraryLoader.libraries.forEach((LibraryElement library) { | 853 if (compilationFailed) { |
832 reporter.log('Enqueuing ${library.canonicalUri}'); | 854 if (!options.generateCodeWithCompileTimeErrors) return; |
833 fullyEnqueueLibrary(library, enqueuer.resolution); | 855 if (!backend |
| 856 .enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) { |
| 857 return; |
| 858 } |
| 859 } |
| 860 |
| 861 if (options.analyzeOnly) { |
| 862 if (!analyzeAll && !compilationFailed) { |
| 863 // No point in reporting unused code when [analyzeAll] is true: all |
| 864 // code is artificially used. |
| 865 // If compilation failed, it is possible that the error prevents the |
| 866 // compiler from analyzing all the code. |
| 867 // TODO(johnniwinther): Reenable this when the reporting is more |
| 868 // precise. |
| 869 //reportUnusedCode(); |
| 870 } |
| 871 return; |
| 872 } |
| 873 assert(mainFunction != null); |
| 874 phase = PHASE_DONE_RESOLVING; |
| 875 |
| 876 world.populate(); |
| 877 // Compute whole-program-knowledge that the backend needs. (This might |
| 878 // require the information computed in [world.populate].) |
| 879 backend.onResolutionComplete(); |
| 880 |
| 881 deferredLoadTask.onResolutionComplete(mainFunction); |
| 882 |
| 883 reporter.log('Inferring types...'); |
| 884 typesTask.onResolutionComplete(mainFunction); |
| 885 |
| 886 if (stopAfterTypeInference) return; |
| 887 |
| 888 backend.onTypeInferenceComplete(); |
| 889 |
| 890 reporter.log('Compiling...'); |
| 891 phase = PHASE_COMPILING; |
| 892 backend.onCodegenStart(); |
| 893 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. |
| 894 if (hasIsolateSupport) { |
| 895 backend.enableIsolateSupport(enqueuer.codegen); |
| 896 } |
| 897 if (compileAll) { |
| 898 libraryLoader.libraries.forEach((LibraryElement library) { |
| 899 fullyEnqueueLibrary(library, enqueuer.codegen); |
| 900 }); |
| 901 } |
| 902 processQueue(enqueuer.codegen, mainFunction); |
| 903 enqueuer.codegen.logSummary(reporter.log); |
| 904 |
| 905 int programSize = backend.assembleProgram(); |
| 906 |
| 907 if (options.dumpInfo) { |
| 908 dumpInfoTask.reportSize(programSize); |
| 909 dumpInfoTask.dumpInfo(); |
| 910 } |
| 911 |
| 912 backend.sourceInformationStrategy.onComplete(); |
| 913 |
| 914 checkQueues(); |
834 }); | 915 }); |
835 } else if (options.analyzeMain) { | |
836 if (mainApp != null) { | |
837 fullyEnqueueLibrary(mainApp, enqueuer.resolution); | |
838 } | |
839 if (librariesToAnalyzeWhenRun != null) { | |
840 for (Uri libraryUri in librariesToAnalyzeWhenRun) { | |
841 fullyEnqueueLibrary( | |
842 libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution); | |
843 } | |
844 } | |
845 } | |
846 // Elements required by enqueueHelpers are global dependencies | |
847 // that are not pulled in by a particular element. | |
848 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); | |
849 resolveLibraryMetadata(); | |
850 reporter.log('Resolving...'); | |
851 processQueue(enqueuer.resolution, mainFunction); | |
852 enqueuer.resolution.logSummary(reporter.log); | |
853 | |
854 _reporter.reportSuppressedMessagesSummary(); | |
855 | |
856 if (compilationFailed) { | |
857 if (!options.generateCodeWithCompileTimeErrors) return; | |
858 if (!backend.enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) { | |
859 return; | |
860 } | |
861 } | |
862 | |
863 if (options.analyzeOnly) { | |
864 if (!analyzeAll && !compilationFailed) { | |
865 // No point in reporting unused code when [analyzeAll] is true: all | |
866 // code is artificially used. | |
867 // If compilation failed, it is possible that the error prevents the | |
868 // compiler from analyzing all the code. | |
869 // TODO(johnniwinther): Reenable this when the reporting is more | |
870 // precise. | |
871 //reportUnusedCode(); | |
872 } | |
873 return; | |
874 } | |
875 assert(mainFunction != null); | |
876 phase = PHASE_DONE_RESOLVING; | |
877 | |
878 world.populate(); | |
879 // Compute whole-program-knowledge that the backend needs. (This might | |
880 // require the information computed in [world.populate].) | |
881 backend.onResolutionComplete(); | |
882 | |
883 deferredLoadTask.onResolutionComplete(mainFunction); | |
884 | |
885 reporter.log('Inferring types...'); | |
886 typesTask.onResolutionComplete(mainFunction); | |
887 | |
888 if (stopAfterTypeInference) return; | |
889 | |
890 backend.onTypeInferenceComplete(); | |
891 | |
892 reporter.log('Compiling...'); | |
893 phase = PHASE_COMPILING; | |
894 backend.onCodegenStart(); | |
895 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. | |
896 if (hasIsolateSupport) { | |
897 backend.enableIsolateSupport(enqueuer.codegen); | |
898 } | |
899 if (compileAll) { | |
900 libraryLoader.libraries.forEach((LibraryElement library) { | |
901 fullyEnqueueLibrary(library, enqueuer.codegen); | |
902 }); | |
903 } | |
904 processQueue(enqueuer.codegen, mainFunction); | |
905 enqueuer.codegen.logSummary(reporter.log); | |
906 | |
907 int programSize = backend.assembleProgram(); | |
908 | |
909 if (options.dumpInfo) { | |
910 dumpInfoTask.reportSize(programSize); | |
911 dumpInfoTask.dumpInfo(); | |
912 } | |
913 | |
914 backend.sourceInformationStrategy.onComplete(); | |
915 | |
916 checkQueues(); | |
917 }); | |
918 | 916 |
919 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { | 917 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { |
920 void enqueueAll(Element element) { | 918 void enqueueAll(Element element) { |
921 fullyEnqueueTopLevelElement(element, world); | 919 fullyEnqueueTopLevelElement(element, world); |
922 } | 920 } |
923 library.implementation.forEachLocalMember(enqueueAll); | 921 library.implementation.forEachLocalMember(enqueueAll); |
924 } | 922 } |
925 | 923 |
926 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { | 924 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { |
927 if (element.isClass) { | 925 if (element.isClass) { |
(...skipping 15 matching lines...) Expand all Loading... |
943 for (MetadataAnnotation metadata in library.metadata) { | 941 for (MetadataAnnotation metadata in library.metadata) { |
944 metadata.ensureResolved(resolution); | 942 metadata.ensureResolved(resolution); |
945 } | 943 } |
946 } | 944 } |
947 } | 945 } |
948 } | 946 } |
949 | 947 |
950 /** | 948 /** |
951 * Empty the [world] queue. | 949 * Empty the [world] queue. |
952 */ | 950 */ |
953 void emptyQueue(Enqueuer world) | 951 void emptyQueue(Enqueuer world) => |
954 => selfTask.measureSubtask("Compiler.emptyQueue", () { | 952 selfTask.measureSubtask("Compiler.emptyQueue", () { |
955 world.forEach((WorkItem work) { | 953 world.forEach((WorkItem work) { |
956 reporter.withCurrentElement( | 954 reporter.withCurrentElement( |
957 work.element, () => selfTask.measureSubtask("world.applyImpact", () { | 955 work.element, |
958 world.applyImpact( | 956 () => selfTask.measureSubtask("world.applyImpact", () { |
959 work.element, | 957 world.applyImpact( |
960 selfTask.measureSubtask("work.run", () => work.run(this, world))); | 958 work.element, |
961 })); | 959 selfTask.measureSubtask( |
962 }); | 960 "work.run", () => work.run(this, world))); |
963 }); | 961 })); |
| 962 }); |
| 963 }); |
964 | 964 |
965 void processQueue(Enqueuer world, Element main) | 965 void processQueue(Enqueuer world, Element main) => |
966 => selfTask.measureSubtask("Compiler.processQueue", () { | 966 selfTask.measureSubtask("Compiler.processQueue", () { |
967 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); | 967 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); |
968 if (main != null && !main.isMalformed) { | 968 if (main != null && !main.isMalformed) { |
969 FunctionElement mainMethod = main; | 969 FunctionElement mainMethod = main; |
970 mainMethod.computeType(resolution); | 970 mainMethod.computeType(resolution); |
971 if (mainMethod.functionSignature.parameterCount != 0) { | 971 if (mainMethod.functionSignature.parameterCount != 0) { |
972 // The first argument could be a list of strings. | 972 // The first argument could be a list of strings. |
973 backend.listImplementation.ensureResolved(resolution); | 973 backend.listImplementation.ensureResolved(resolution); |
974 backend.registerInstantiatedType( | 974 backend.registerInstantiatedType( |
975 backend.listImplementation.rawType, world, globalDependencies); | 975 backend.listImplementation.rawType, world, globalDependencies); |
976 backend.stringImplementation.ensureResolved(resolution); | 976 backend.stringImplementation.ensureResolved(resolution); |
977 backend.registerInstantiatedType( | 977 backend.registerInstantiatedType( |
978 backend.stringImplementation.rawType, world, globalDependencies); | 978 backend.stringImplementation.rawType, |
| 979 world, |
| 980 globalDependencies); |
979 | 981 |
980 backend.registerMainHasArguments(world); | 982 backend.registerMainHasArguments(world); |
981 } | 983 } |
982 world.addToWorkList(main); | 984 world.addToWorkList(main); |
983 } | 985 } |
984 if (options.verbose) { | 986 if (options.verbose) { |
985 progress.reset(); | 987 progress.reset(); |
986 } | 988 } |
987 emptyQueue(world); | 989 emptyQueue(world); |
988 world.queueIsClosed = true; | 990 world.queueIsClosed = true; |
989 // Notify the impact strategy impacts are no longer needed for this | 991 // Notify the impact strategy impacts are no longer needed for this |
990 // enqueuer. | 992 // enqueuer. |
991 impactStrategy.onImpactUsed(world.impactUse); | 993 impactStrategy.onImpactUsed(world.impactUse); |
992 backend.onQueueClosed(); | 994 backend.onQueueClosed(); |
993 assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods()); | 995 assert( |
994 }); | 996 compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods()); |
| 997 }); |
995 | 998 |
996 /** | 999 /** |
997 * Perform various checks of the queues. This includes checking that | 1000 * Perform various checks of the queues. This includes checking that |
998 * the queues are empty (nothing was added after we stopped | 1001 * the queues are empty (nothing was added after we stopped |
999 * processing the queues). Also compute the number of methods that | 1002 * processing the queues). Also compute the number of methods that |
1000 * were resolved, but not compiled (aka excess resolution). | 1003 * were resolved, but not compiled (aka excess resolution). |
1001 */ | 1004 */ |
1002 checkQueues() { | 1005 checkQueues() { |
1003 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { | 1006 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
1004 world.forEach((WorkItem work) { | 1007 world.forEach((WorkItem work) { |
(...skipping 20 matching lines...) Expand all Loading... |
1025 resolved.remove(e); | 1028 resolved.remove(e); |
1026 } | 1029 } |
1027 } | 1030 } |
1028 reporter.log('Excess resolution work: ${resolved.length}.'); | 1031 reporter.log('Excess resolution work: ${resolved.length}.'); |
1029 for (Element e in resolved) { | 1032 for (Element e in resolved) { |
1030 reporter.reportWarningMessage(e, MessageKind.GENERIC, | 1033 reporter.reportWarningMessage(e, MessageKind.GENERIC, |
1031 {'text': 'Warning: $e resolved but not compiled.'}); | 1034 {'text': 'Warning: $e resolved but not compiled.'}); |
1032 } | 1035 } |
1033 } | 1036 } |
1034 | 1037 |
1035 WorldImpact analyzeElement(Element element) | 1038 WorldImpact analyzeElement(Element element) => |
1036 => selfTask.measureSubtask("Compiler.analyzeElement", () { | 1039 selfTask.measureSubtask("Compiler.analyzeElement", () { |
1037 assert(invariant( | 1040 assert(invariant( |
1038 element, | 1041 element, |
1039 element.impliesType || | 1042 element.impliesType || |
1040 element.isField || | 1043 element.isField || |
1041 element.isFunction || | 1044 element.isFunction || |
1042 element.isConstructor || | 1045 element.isConstructor || |
1043 element.isGetter || | 1046 element.isGetter || |
1044 element.isSetter, | 1047 element.isSetter, |
1045 message: 'Unexpected element kind: ${element.kind}')); | 1048 message: 'Unexpected element kind: ${element.kind}')); |
1046 assert(invariant(element, element is AnalyzableElement, | 1049 assert(invariant(element, element is AnalyzableElement, |
1047 message: 'Element $element is not analyzable.')); | 1050 message: 'Element $element is not analyzable.')); |
1048 assert(invariant(element, element.isDeclaration)); | 1051 assert(invariant(element, element.isDeclaration)); |
1049 return resolution.computeWorldImpact(element); | 1052 return resolution.computeWorldImpact(element); |
1050 }); | 1053 }); |
1051 | 1054 |
1052 WorldImpact analyze(ResolutionWorkItem work, | 1055 WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) => |
1053 ResolutionEnqueuer world) | 1056 selfTask.measureSubtask("Compiler.analyze", () { |
1054 => selfTask.measureSubtask("Compiler.analyze", () { | 1057 assert(invariant(work.element, identical(world, enqueuer.resolution))); |
1055 assert(invariant(work.element, identical(world, enqueuer.resolution))); | 1058 assert(invariant(work.element, !work.isAnalyzed, |
1056 assert(invariant(work.element, !work.isAnalyzed, | 1059 message: 'Element ${work.element} has already been analyzed')); |
1057 message: 'Element ${work.element} has already been analyzed')); | 1060 if (shouldPrintProgress) { |
1058 if (shouldPrintProgress) { | 1061 // TODO(ahe): Add structured diagnostics to the compiler API and |
1059 // TODO(ahe): Add structured diagnostics to the compiler API and | 1062 // use it to separate this from the --verbose option. |
1060 // use it to separate this from the --verbose option. | 1063 if (phase == PHASE_RESOLVING) { |
1061 if (phase == PHASE_RESOLVING) { | 1064 reporter |
1062 reporter.log('Resolved ${enqueuer.resolution.processedElements.length} ' | 1065 .log('Resolved ${enqueuer.resolution.processedElements.length} ' |
1063 'elements.'); | 1066 'elements.'); |
1064 progress.reset(); | 1067 progress.reset(); |
1065 } | 1068 } |
1066 } | 1069 } |
1067 AstElement element = work.element; | 1070 AstElement element = work.element; |
1068 if (world.hasBeenProcessed(element)) { | 1071 if (world.hasBeenProcessed(element)) { |
1069 return const WorldImpact(); | 1072 return const WorldImpact(); |
1070 } | 1073 } |
1071 WorldImpact worldImpact = analyzeElement(element); | 1074 WorldImpact worldImpact = analyzeElement(element); |
1072 backend.onElementResolved(element); | 1075 backend.onElementResolved(element); |
1073 world.registerProcessedElement(element); | 1076 world.registerProcessedElement(element); |
1074 return worldImpact; | 1077 return worldImpact; |
1075 }); | 1078 }); |
1076 | 1079 |
1077 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) { | 1080 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) { |
1078 assert(invariant(work.element, identical(world, enqueuer.codegen))); | 1081 assert(invariant(work.element, identical(world, enqueuer.codegen))); |
1079 if (shouldPrintProgress) { | 1082 if (shouldPrintProgress) { |
1080 // TODO(ahe): Add structured diagnostics to the compiler API and | 1083 // TODO(ahe): Add structured diagnostics to the compiler API and |
1081 // use it to separate this from the --verbose option. | 1084 // use it to separate this from the --verbose option. |
1082 reporter | 1085 reporter |
1083 .log('Compiled ${enqueuer.codegen.generatedCode.length} methods.'); | 1086 .log('Compiled ${enqueuer.codegen.generatedCode.length} methods.'); |
1084 progress.reset(); | 1087 progress.reset(); |
1085 } | 1088 } |
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2095 _ElementScanner(this.scanner); | 2098 _ElementScanner(this.scanner); |
2096 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); | 2099 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); |
2097 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); | 2100 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); |
2098 } | 2101 } |
2099 | 2102 |
2100 class _EmptyEnvironment implements Environment { | 2103 class _EmptyEnvironment implements Environment { |
2101 const _EmptyEnvironment(); | 2104 const _EmptyEnvironment(); |
2102 | 2105 |
2103 String valueOf(String key) => null; | 2106 String valueOf(String key) => null; |
2104 } | 2107 } |
OLD | NEW |