| 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 |