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 part of dart2js; | 5 part of dart2js; |
6 | 6 |
7 /** | 7 /** |
8 * If true, print a warning for each method that was resolved, but not | 8 * If true, print a warning for each method that was resolved, but not |
9 * compiled. | 9 * compiled. |
10 */ | 10 */ |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 if (dynamicClass != null) { | 636 if (dynamicClass != null) { |
637 // When loading the built-in libraries, dynamicClass is null. We | 637 // When loading the built-in libraries, dynamicClass is null. We |
638 // take advantage of this as core imports js_helper and sees [dynamic] | 638 // take advantage of this as core imports js_helper and sees [dynamic] |
639 // this way. | 639 // this way. |
640 withCurrentElement(dynamicClass, () { | 640 withCurrentElement(dynamicClass, () { |
641 library.addToScope(dynamicClass, this); | 641 library.addToScope(dynamicClass, this); |
642 }); | 642 }); |
643 } | 643 } |
644 if (uri == Uri.parse('dart:mirrors')) { | 644 if (uri == Uri.parse('dart:mirrors')) { |
645 mirrorSystemClass = library.find(const SourceString('MirrorSystem')); | 645 mirrorSystemClass = library.find(const SourceString('MirrorSystem')); |
| 646 metadataHandler = constantHandler; |
646 } else if (uri == Uri.parse('dart:_collection-dev')) { | 647 } else if (uri == Uri.parse('dart:_collection-dev')) { |
647 symbolImplementationClass = library.find(const SourceString('Symbol')); | 648 symbolImplementationClass = library.find(const SourceString('Symbol')); |
648 } | 649 } |
649 } | 650 } |
650 | 651 |
651 void onClassResolved(ClassElement cls) { | 652 void onClassResolved(ClassElement cls) { |
652 if (mirrorSystemClass == cls) { | 653 if (mirrorSystemClass == cls) { |
653 mirrorSystemGetNameFunction = | 654 mirrorSystemGetNameFunction = |
654 cls.lookupLocalMember(const SourceString('getName')); | 655 cls.lookupLocalMember(const SourceString('getName')); |
655 } else if (symbolClass == cls) { | 656 } else if (symbolClass == cls) { |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 } | 816 } |
816 | 817 |
817 log('Resolving...'); | 818 log('Resolving...'); |
818 phase = PHASE_RESOLVING; | 819 phase = PHASE_RESOLVING; |
819 if (analyzeAll) { | 820 if (analyzeAll) { |
820 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib)); | 821 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib)); |
821 } | 822 } |
822 // Elements required by enqueueHelpers are global dependencies | 823 // Elements required by enqueueHelpers are global dependencies |
823 // that are not pulled in by a particular element. | 824 // that are not pulled in by a particular element. |
824 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); | 825 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); |
| 826 resolveReflectiveDataIfNeeded(); |
825 processQueue(enqueuer.resolution, main); | 827 processQueue(enqueuer.resolution, main); |
826 enqueuer.resolution.logSummary(log); | 828 enqueuer.resolution.logSummary(log); |
827 | 829 |
828 if (compilationFailed) return; | 830 if (compilationFailed) return; |
829 if (analyzeOnly) return; | 831 if (analyzeOnly) return; |
830 assert(main != null); | 832 assert(main != null); |
831 phase = PHASE_DONE_RESOLVING; | 833 phase = PHASE_DONE_RESOLVING; |
832 | 834 |
833 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution | 835 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution |
834 // should know this. | 836 // should know this. |
(...skipping 22 matching lines...) Expand all Loading... |
857 processQueue(enqueuer.codegen, main); | 859 processQueue(enqueuer.codegen, main); |
858 enqueuer.codegen.logSummary(log); | 860 enqueuer.codegen.logSummary(log); |
859 | 861 |
860 if (compilationFailed) return; | 862 if (compilationFailed) return; |
861 | 863 |
862 backend.assembleProgram(); | 864 backend.assembleProgram(); |
863 | 865 |
864 checkQueues(); | 866 checkQueues(); |
865 } | 867 } |
866 | 868 |
| 869 void resolveReflectiveDataIfNeeded() { |
| 870 // Only need reflective data when dart:mirrors is loaded. |
| 871 if (mirrorSystemClass == null) return; |
| 872 |
| 873 for (LibraryElement library in libraries.values) { |
| 874 for (Link link = library.metadata; !link.isEmpty; link = link.tail) { |
| 875 link.head.ensureResolved(this); |
| 876 } |
| 877 } |
| 878 } |
| 879 |
867 void fullyEnqueueLibrary(LibraryElement library) { | 880 void fullyEnqueueLibrary(LibraryElement library) { |
868 library.forEachLocalMember(fullyEnqueueTopLevelElement); | 881 library.forEachLocalMember(fullyEnqueueTopLevelElement); |
869 } | 882 } |
870 | 883 |
871 void fullyEnqueueTopLevelElement(Element element) { | 884 void fullyEnqueueTopLevelElement(Element element) { |
872 if (element.isClass()) { | 885 if (element.isClass()) { |
873 ClassElement cls = element; | 886 ClassElement cls = element; |
874 cls.ensureResolved(this); | 887 cls.ensureResolved(this); |
875 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); | 888 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); |
876 enqueuer.resolution.registerInstantiatedClass( | 889 enqueuer.resolution.registerInstantiatedClass( |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 for (Element e in resolved) { | 954 for (Element e in resolved) { |
942 SourceSpan span = spanFromElement(e); | 955 SourceSpan span = spanFromElement(e); |
943 reportDiagnostic(span, 'Warning: $e resolved but not compiled.', | 956 reportDiagnostic(span, 'Warning: $e resolved but not compiled.', |
944 api.Diagnostic.WARNING); | 957 api.Diagnostic.WARNING); |
945 } | 958 } |
946 } | 959 } |
947 | 960 |
948 TreeElements analyzeElement(Element element) { | 961 TreeElements analyzeElement(Element element) { |
949 assert(invariant(element, element.isDeclaration)); | 962 assert(invariant(element, element.isDeclaration)); |
950 assert(!element.isForwardingConstructor); | 963 assert(!element.isForwardingConstructor); |
951 TreeElements elements = enqueuer.resolution.getCachedElements(element); | 964 ResolutionEnqueuer world = enqueuer.resolution; |
| 965 TreeElements elements = world.getCachedElements(element); |
952 if (elements != null) return elements; | 966 if (elements != null) return elements; |
953 assert(parser != null); | 967 assert(parser != null); |
954 Node tree = parser.parse(element); | 968 Node tree = parser.parse(element); |
955 validator.validate(tree); | 969 validator.validate(tree); |
956 elements = resolver.resolve(element); | 970 elements = resolver.resolve(element); |
957 if (elements != null && !analyzeSignaturesOnly) { | 971 if (elements != null && !analyzeSignaturesOnly) { |
958 // Only analyze nodes with a corresponding [TreeElements]. | 972 // Only analyze nodes with a corresponding [TreeElements]. |
959 checker.check(tree, elements); | 973 checker.check(tree, elements); |
960 } | 974 } |
| 975 world.resolvedElements[element] = elements; |
961 return elements; | 976 return elements; |
962 } | 977 } |
963 | 978 |
964 TreeElements analyze(ResolutionWorkItem work, ResolutionEnqueuer world) { | 979 TreeElements analyze(ResolutionWorkItem work, ResolutionEnqueuer world) { |
965 assert(invariant(work.element, identical(world, enqueuer.resolution))); | 980 assert(invariant(work.element, identical(world, enqueuer.resolution))); |
966 assert(invariant(work.element, !work.isAnalyzed(), | 981 assert(invariant(work.element, !work.isAnalyzed(), |
967 message: 'Element ${work.element} has already been analyzed')); | 982 message: 'Element ${work.element} has already been analyzed')); |
968 if (progress.elapsedMilliseconds > 500) { | 983 if (progress.elapsedMilliseconds > 500) { |
969 // TODO(ahe): Add structured diagnostics to the compiler API and | 984 // TODO(ahe): Add structured diagnostics to the compiler API and |
970 // use it to separate this from the --verbose option. | 985 // use it to separate this from the --verbose option. |
971 if (phase == PHASE_RESOLVING) { | 986 if (phase == PHASE_RESOLVING) { |
972 log('Resolved ${enqueuer.resolution.resolvedElements.length} ' | 987 log('Resolved ${enqueuer.resolution.resolvedElements.length} ' |
973 'elements.'); | 988 'elements.'); |
974 progress.reset(); | 989 progress.reset(); |
975 } | 990 } |
976 } | 991 } |
977 Element element = work.element; | 992 Element element = work.element; |
978 TreeElements result = world.getCachedElements(element); | 993 TreeElements result = world.getCachedElements(element); |
979 if (result != null) return result; | 994 if (result != null) return result; |
980 result = analyzeElement(element); | 995 result = analyzeElement(element); |
981 assert(invariant(element, element.isDeclaration)); | |
982 world.resolvedElements[element] = result; | |
983 return result; | 996 return result; |
984 } | 997 } |
985 | 998 |
986 void codegen(CodegenWorkItem work, CodegenEnqueuer world) { | 999 void codegen(CodegenWorkItem work, CodegenEnqueuer world) { |
987 assert(invariant(work.element, identical(world, enqueuer.codegen))); | 1000 assert(invariant(work.element, identical(world, enqueuer.codegen))); |
988 if (progress.elapsedMilliseconds > 500) { | 1001 if (progress.elapsedMilliseconds > 500) { |
989 // TODO(ahe): Add structured diagnostics to the compiler API and | 1002 // TODO(ahe): Add structured diagnostics to the compiler API and |
990 // use it to separate this from the --verbose option. | 1003 // use it to separate this from the --verbose option. |
991 log('Compiled ${enqueuer.codegen.generatedCode.length} methods.'); | 1004 log('Compiled ${enqueuer.codegen.generatedCode.length} methods.'); |
992 progress.reset(); | 1005 progress.reset(); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 | 1345 |
1333 void close() {} | 1346 void close() {} |
1334 | 1347 |
1335 toString() => name; | 1348 toString() => name; |
1336 | 1349 |
1337 /// Convenience method for getting an [api.CompilerOutputProvider]. | 1350 /// Convenience method for getting an [api.CompilerOutputProvider]. |
1338 static NullSink outputProvider(String name, String extension) { | 1351 static NullSink outputProvider(String name, String extension) { |
1339 return new NullSink('$name.$extension'); | 1352 return new NullSink('$name.$extension'); |
1340 } | 1353 } |
1341 } | 1354 } |
OLD | NEW |