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 18 matching lines...) Expand all Loading... |
29 * | 29 * |
30 * Invariant: [element] must be a declaration element. | 30 * Invariant: [element] must be a declaration element. |
31 */ | 31 */ |
32 final Element element; | 32 final Element element; |
33 TreeElements resolutionTree; | 33 TreeElements resolutionTree; |
34 | 34 |
35 WorkItem(this.element, this.compilationContext) { | 35 WorkItem(this.element, this.compilationContext) { |
36 assert(invariant(element, element.isDeclaration)); | 36 assert(invariant(element, element.isDeclaration)); |
37 } | 37 } |
38 | 38 |
39 | |
40 void run(Compiler compiler, Enqueuer world); | 39 void run(Compiler compiler, Enqueuer world); |
41 } | 40 } |
42 | 41 |
43 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. | 42 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. |
44 class ResolutionWorkItem extends WorkItem { | 43 class ResolutionWorkItem extends WorkItem { |
45 ResolutionWorkItem(Element element, | 44 ResolutionWorkItem(Element element, |
46 ItemCompilationContext compilationContext) | 45 ItemCompilationContext compilationContext) |
47 : super(element, compilationContext); | 46 : super(element, compilationContext); |
48 | 47 |
49 void run(Compiler compiler, ResolutionEnqueuer world) { | 48 void run(Compiler compiler, ResolutionEnqueuer world) { |
(...skipping 24 matching lines...) Expand all Loading... |
74 | 73 |
75 typedef void PostProcessAction(); | 74 typedef void PostProcessAction(); |
76 | 75 |
77 class PostProcessTask { | 76 class PostProcessTask { |
78 final Element element; | 77 final Element element; |
79 final PostProcessAction action; | 78 final PostProcessAction action; |
80 | 79 |
81 PostProcessTask(this.element, this.action); | 80 PostProcessTask(this.element, this.action); |
82 } | 81 } |
83 | 82 |
84 class ReadingFilesTask extends CompilerTask { | |
85 ReadingFilesTask(Compiler compiler) : super(compiler); | |
86 String get name => 'Reading input files'; | |
87 } | |
88 | |
89 abstract class Backend { | 83 abstract class Backend { |
90 final Compiler compiler; | 84 final Compiler compiler; |
91 final ConstantSystem constantSystem; | 85 final ConstantSystem constantSystem; |
92 | 86 |
93 Backend(this.compiler, | 87 Backend(this.compiler, |
94 [ConstantSystem constantSystem = DART_CONSTANT_SYSTEM]) | 88 [ConstantSystem constantSystem = DART_CONSTANT_SYSTEM]) |
95 : this.constantSystem = constantSystem; | 89 : this.constantSystem = constantSystem; |
96 | 90 |
97 void initializeHelperClasses() {} | 91 void initializeHelperClasses() {} |
98 | 92 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass; | 240 ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass; |
247 | 241 |
248 bool isDefaultNoSuchMethodImplementation(Element element) { | 242 bool isDefaultNoSuchMethodImplementation(Element element) { |
249 assert(element.name == Compiler.NO_SUCH_METHOD); | 243 assert(element.name == Compiler.NO_SUCH_METHOD); |
250 ClassElement classElement = element.getEnclosingClass(); | 244 ClassElement classElement = element.getEnclosingClass(); |
251 return classElement == compiler.objectClass; | 245 return classElement == compiler.objectClass; |
252 } | 246 } |
253 | 247 |
254 void registerStaticUse(Element element, Enqueuer enqueuer) {} | 248 void registerStaticUse(Element element, Enqueuer enqueuer) {} |
255 | 249 |
256 void onLibraryLoaded(LibraryElement library, Uri uri) {} | 250 Future onLibraryLoaded(LibraryElement library, Uri uri) { |
| 251 return new Future.value(); |
| 252 } |
257 | 253 |
258 void registerMetadataInstantiatedType(DartType type, TreeElements elements) {} | 254 void registerMetadataInstantiatedType(DartType type, TreeElements elements) {} |
259 void registerMetadataStaticUse(Element element) {} | 255 void registerMetadataStaticUse(Element element) {} |
260 void registerMetadataGetOfStaticFunction(FunctionElement element) {} | 256 void registerMetadataGetOfStaticFunction(FunctionElement element) {} |
261 | 257 |
262 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed | 258 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed |
263 /// annotations. The arguments corresponds to the unions of the corresponding | 259 /// annotations. The arguments corresponds to the unions of the corresponding |
264 /// fields of the annotations. | 260 /// fields of the annotations. |
265 void registerMirrorUsage(Set<String> symbols, | 261 void registerMirrorUsage(Set<String> symbols, |
266 Set<Element> targets, | 262 Set<Element> targets, |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 LibraryLoader libraryLoader; | 501 LibraryLoader libraryLoader; |
506 TreeValidatorTask validator; | 502 TreeValidatorTask validator; |
507 ResolverTask resolver; | 503 ResolverTask resolver; |
508 closureMapping.ClosureTask closureToClassMapper; | 504 closureMapping.ClosureTask closureToClassMapper; |
509 TypeCheckerTask checker; | 505 TypeCheckerTask checker; |
510 ti.TypesTask typesTask; | 506 ti.TypesTask typesTask; |
511 Backend backend; | 507 Backend backend; |
512 ConstantHandler constantHandler; | 508 ConstantHandler constantHandler; |
513 ConstantHandler metadataHandler; | 509 ConstantHandler metadataHandler; |
514 EnqueueTask enqueuer; | 510 EnqueueTask enqueuer; |
515 CompilerTask fileReadingTask; | |
516 DeferredLoadTask deferredLoadTask; | 511 DeferredLoadTask deferredLoadTask; |
517 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; | 512 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; |
518 ContainerTracer containerTracer; | 513 ContainerTracer containerTracer; |
519 String buildId; | 514 String buildId; |
520 | 515 |
521 static const SourceString MAIN = const SourceString('main'); | 516 static const SourceString MAIN = const SourceString('main'); |
522 static const SourceString CALL_OPERATOR_NAME = const SourceString('call'); | 517 static const SourceString CALL_OPERATOR_NAME = const SourceString('call'); |
523 static const SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod'); | 518 static const SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod'); |
524 static const int NO_SUCH_METHOD_ARG_COUNT = 1; | 519 static const int NO_SUCH_METHOD_ARG_COUNT = 1; |
525 static const SourceString CREATE_INVOCATION_MIRROR = | 520 static const SourceString CREATE_INVOCATION_MIRROR = |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 backend = jsBackend; | 602 backend = jsBackend; |
608 } else { | 603 } else { |
609 closureNamer = new closureMapping.ClosureNamer(); | 604 closureNamer = new closureMapping.ClosureNamer(); |
610 backend = new dart_backend.DartBackend(this, strips); | 605 backend = new dart_backend.DartBackend(this, strips); |
611 } | 606 } |
612 | 607 |
613 // No-op in production mode. | 608 // No-op in production mode. |
614 validator = new TreeValidatorTask(this); | 609 validator = new TreeValidatorTask(this); |
615 | 610 |
616 tasks = [ | 611 tasks = [ |
617 fileReadingTask = new ReadingFilesTask(this), | |
618 libraryLoader = new LibraryLoaderTask(this), | 612 libraryLoader = new LibraryLoaderTask(this), |
619 scanner = new ScannerTask(this), | 613 scanner = new ScannerTask(this), |
620 dietParser = new DietParserTask(this), | 614 dietParser = new DietParserTask(this), |
621 parser = new ParserTask(this), | 615 parser = new ParserTask(this), |
622 patchParser = new PatchParserTask(this), | 616 patchParser = new PatchParserTask(this), |
623 resolver = new ResolverTask(this), | 617 resolver = new ResolverTask(this), |
624 closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer), | 618 closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer), |
625 checker = new TypeCheckerTask(this), | 619 checker = new TypeCheckerTask(this), |
626 typesTask = new ti.TypesTask(this), | 620 typesTask = new ti.TypesTask(this), |
627 containerTracer = new ContainerTracer(this), | 621 containerTracer = new ContainerTracer(this), |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 return spanFromTokens(annotation.beginToken, annotation.endToken, uri); | 718 return spanFromTokens(annotation.beginToken, annotation.endToken, uri); |
725 } else { | 719 } else { |
726 throw 'No error location.'; | 720 throw 'No error location.'; |
727 } | 721 } |
728 } | 722 } |
729 | 723 |
730 void log(message) { | 724 void log(message) { |
731 reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO); | 725 reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO); |
732 } | 726 } |
733 | 727 |
734 bool run(Uri uri) { | 728 Future<bool> run(Uri uri) { |
735 totalCompileTime.start(); | 729 totalCompileTime.start(); |
736 try { | 730 |
737 runCompiler(uri); | 731 return new Future.sync(() => runCompiler(uri)).catchError((error) { |
738 } on CompilerCancelledException catch (exception) { | 732 if (error is CompilerCancelledException) { |
739 log('Error: $exception'); | 733 log('Error: $error'); |
740 return false; | 734 return false; |
741 } catch (exception) { | 735 } |
| 736 |
742 try { | 737 try { |
743 if (!hasCrashed) { | 738 if (!hasCrashed) { |
744 hasCrashed = true; | 739 hasCrashed = true; |
745 reportDiagnostic(new SourceSpan(uri, 0, 0), | 740 reportDiagnostic(new SourceSpan(uri, 0, 0), |
746 MessageKind.COMPILER_CRASHED.error().toString(), | 741 MessageKind.COMPILER_CRASHED.error().toString(), |
747 api.Diagnostic.CRASH); | 742 api.Diagnostic.CRASH); |
748 pleaseReportCrash(); | 743 pleaseReportCrash(); |
749 } | 744 } |
750 } catch (doubleFault) { | 745 } catch (doubleFault) { |
751 // Ignoring exceptions in exception handling. | 746 // Ignoring exceptions in exception handling. |
752 } | 747 } |
753 rethrow; | 748 throw error; |
754 } finally { | 749 }).whenComplete(() { |
755 tracer.close(); | 750 tracer.close(); |
756 totalCompileTime.stop(); | 751 totalCompileTime.stop(); |
757 } | 752 }).then((_) { |
758 return !compilationFailed; | 753 return !compilationFailed; |
| 754 }); |
759 } | 755 } |
760 | 756 |
761 bool hasIsolateSupport() => isolateLibrary != null; | 757 bool hasIsolateSupport() => isolateLibrary != null; |
762 | 758 |
763 /** | 759 /** |
764 * This method is called before [library] import and export scopes have been | 760 * This method is called before [library] import and export scopes have been |
765 * set up. | 761 * set up. |
766 */ | 762 */ |
767 void onLibraryLoaded(LibraryElement library, Uri uri) { | 763 Future onLibraryLoaded(LibraryElement library, Uri uri) { |
768 if (dynamicClass != null) { | 764 if (dynamicClass != null) { |
769 // When loading the built-in libraries, dynamicClass is null. We | 765 // When loading the built-in libraries, dynamicClass is null. We |
770 // take advantage of this as core imports js_helper and sees [dynamic] | 766 // take advantage of this as core imports js_helper and sees [dynamic] |
771 // this way. | 767 // this way. |
772 withCurrentElement(dynamicClass, () { | 768 withCurrentElement(dynamicClass, () { |
773 library.addToScope(dynamicClass, this); | 769 library.addToScope(dynamicClass, this); |
774 }); | 770 }); |
775 } | 771 } |
776 if (uri == new Uri(scheme: 'dart', path: 'mirrors')) { | 772 if (uri == new Uri(scheme: 'dart', path: 'mirrors')) { |
777 mirrorsLibrary = library; | 773 mirrorsLibrary = library; |
778 mirrorSystemClass = | 774 mirrorSystemClass = |
779 findRequiredElement(library, const SourceString('MirrorSystem')); | 775 findRequiredElement(library, const SourceString('MirrorSystem')); |
780 mirrorsUsedClass = | 776 mirrorsUsedClass = |
781 findRequiredElement(library, const SourceString('MirrorsUsed')); | 777 findRequiredElement(library, const SourceString('MirrorsUsed')); |
782 } else if (uri == new Uri(scheme: 'dart', path: 'typed_data')) { | 778 } else if (uri == new Uri(scheme: 'dart', path: 'typed_data')) { |
783 typedDataLibrary = library; | 779 typedDataLibrary = library; |
784 typedDataClass = | 780 typedDataClass = |
785 findRequiredElement(library, const SourceString('TypedData')); | 781 findRequiredElement(library, const SourceString('TypedData')); |
786 } else if (uri == new Uri(scheme: 'dart', path: '_collection-dev')) { | 782 } else if (uri == new Uri(scheme: 'dart', path: '_collection-dev')) { |
787 symbolImplementationClass = | 783 symbolImplementationClass = |
788 findRequiredElement(library, const SourceString('Symbol')); | 784 findRequiredElement(library, const SourceString('Symbol')); |
789 } else if (uri == new Uri(scheme: 'dart', path: 'async')) { | 785 } else if (uri == new Uri(scheme: 'dart', path: 'async')) { |
790 deferredLibraryClass = | 786 deferredLibraryClass = |
791 findRequiredElement(library, const SourceString('DeferredLibrary')); | 787 findRequiredElement(library, const SourceString('DeferredLibrary')); |
792 } else if (isolateHelperLibrary == null | 788 } else if (isolateHelperLibrary == null |
793 && (uri == new Uri(scheme: 'dart', path: '_isolate_helper'))) { | 789 && (uri == new Uri(scheme: 'dart', path: '_isolate_helper'))) { |
794 isolateHelperLibrary = scanBuiltinLibrary('_isolate_helper'); | 790 isolateHelperLibrary = library; |
795 } else if (foreignLibrary == null | 791 } else if (foreignLibrary == null |
796 && (uri == new Uri(scheme: 'dart', path: '_foreign_helper'))) { | 792 && (uri == new Uri(scheme: 'dart', path: '_foreign_helper'))) { |
797 foreignLibrary = scanBuiltinLibrary('_foreign_helper'); | 793 foreignLibrary = library; |
798 } | 794 } |
799 backend.onLibraryLoaded(library, uri); | 795 return backend.onLibraryLoaded(library, uri); |
800 } | 796 } |
801 | 797 |
802 Element findRequiredElement(LibraryElement library, SourceString name) { | 798 Element findRequiredElement(LibraryElement library, SourceString name) { |
803 var element = library.find(name); | 799 var element = library.find(name); |
804 if (element == null) { | 800 if (element == null) { |
805 internalErrorOnElement( | 801 internalErrorOnElement( |
806 library, | 802 library, |
807 'The library "${library.canonicalUri}" does not contain required ' | 803 'The library "${library.canonicalUri}" does not contain required ' |
808 'element: ${name.slowToString()}'); | 804 'element: ${name.slowToString()}'); |
809 } | 805 } |
810 return element; | 806 return element; |
811 } | 807 } |
812 | 808 |
813 void onClassResolved(ClassElement cls) { | 809 void onClassResolved(ClassElement cls) { |
814 if (mirrorSystemClass == cls) { | 810 if (mirrorSystemClass == cls) { |
815 mirrorSystemGetNameFunction = | 811 mirrorSystemGetNameFunction = |
816 cls.lookupLocalMember(const SourceString('getName')); | 812 cls.lookupLocalMember(const SourceString('getName')); |
817 } else if (symbolClass == cls) { | 813 } else if (symbolClass == cls) { |
818 symbolConstructor = cls.constructors.head; | 814 symbolConstructor = cls.constructors.head; |
819 } else if (symbolImplementationClass == cls) { | 815 } else if (symbolImplementationClass == cls) { |
820 symbolValidatedConstructor = symbolImplementationClass.lookupConstructor( | 816 symbolValidatedConstructor = symbolImplementationClass.lookupConstructor( |
821 symbolValidatedConstructorSelector); | 817 symbolValidatedConstructorSelector); |
822 } else if (mirrorsUsedClass == cls) { | 818 } else if (mirrorsUsedClass == cls) { |
823 mirrorsUsedConstructor = cls.constructors.head; | 819 mirrorsUsedConstructor = cls.constructors.head; |
824 } | 820 } |
825 } | 821 } |
826 | 822 |
827 LibraryElement scanBuiltinLibrary(String filename); | 823 Future<LibraryElement> scanBuiltinLibrary(String filename); |
828 | 824 |
829 void initializeSpecialClasses() { | 825 void initializeSpecialClasses() { |
830 final List missingCoreClasses = []; | 826 final List missingCoreClasses = []; |
831 ClassElement lookupCoreClass(String name) { | 827 ClassElement lookupCoreClass(String name) { |
832 ClassElement result = coreLibrary.find(new SourceString(name)); | 828 ClassElement result = coreLibrary.find(new SourceString(name)); |
833 if (result == null) { | 829 if (result == null) { |
834 missingCoreClasses.add(name); | 830 missingCoreClasses.add(name); |
835 } | 831 } |
836 return result; | 832 return result; |
837 } | 833 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 | 891 |
896 Element _filledListConstructor; | 892 Element _filledListConstructor; |
897 Element get filledListConstructor { | 893 Element get filledListConstructor { |
898 if (_filledListConstructor != null) return _filledListConstructor; | 894 if (_filledListConstructor != null) return _filledListConstructor; |
899 Selector callConstructor = new Selector.callConstructor( | 895 Selector callConstructor = new Selector.callConstructor( |
900 const SourceString("filled"), listClass.getLibrary()); | 896 const SourceString("filled"), listClass.getLibrary()); |
901 return _filledListConstructor = | 897 return _filledListConstructor = |
902 listClass.lookupConstructor(callConstructor); | 898 listClass.lookupConstructor(callConstructor); |
903 } | 899 } |
904 | 900 |
905 void scanBuiltinLibraries() { | 901 Future scanBuiltinLibraries() { |
906 jsHelperLibrary = scanBuiltinLibrary('_js_helper'); | 902 return scanBuiltinLibrary('_js_helper').then((LibraryElement library) { |
907 interceptorsLibrary = scanBuiltinLibrary('_interceptors'); | 903 jsHelperLibrary = library; |
908 assertMethod = jsHelperLibrary.find(const SourceString('assertHelper')); | 904 return scanBuiltinLibrary('_interceptors'); |
909 identicalFunction = coreLibrary.find(const SourceString('identical')); | 905 }).then((LibraryElement library) { |
| 906 interceptorsLibrary = library; |
910 | 907 |
911 initializeSpecialClasses(); | 908 assertMethod = jsHelperLibrary.find(const SourceString('assertHelper')); |
| 909 identicalFunction = coreLibrary.find(const SourceString('identical')); |
912 | 910 |
913 functionClass.ensureResolved(this); | 911 initializeSpecialClasses(); |
914 functionApplyMethod = | |
915 functionClass.lookupLocalMember(const SourceString('apply')); | |
916 jsInvocationMirrorClass.ensureResolved(this); | |
917 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); | |
918 | 912 |
919 if (preserveComments) { | 913 functionClass.ensureResolved(this); |
920 var uri = new Uri(scheme: 'dart', path: 'mirrors'); | 914 functionApplyMethod = |
921 LibraryElement libraryElement = | 915 functionClass.lookupLocalMember(const SourceString('apply')); |
922 libraryLoader.loadLibrary(uri, null, uri); | 916 jsInvocationMirrorClass.ensureResolved(this); |
923 documentClass = libraryElement.find(const SourceString('Comment')); | 917 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); |
924 } | 918 |
| 919 if (preserveComments) { |
| 920 var uri = new Uri(scheme: 'dart', path: 'mirrors'); |
| 921 return libraryLoader.loadLibrary(uri, null, uri).then( |
| 922 (LibraryElement libraryElement) { |
| 923 documentClass = libraryElement.find(const SourceString('Comment')); |
| 924 }); |
| 925 } |
| 926 }); |
925 } | 927 } |
926 | 928 |
927 void importHelperLibrary(LibraryElement library) { | 929 void importHelperLibrary(LibraryElement library) { |
928 if (jsHelperLibrary != null) { | 930 if (jsHelperLibrary != null) { |
929 libraryLoader.importLibrary(library, jsHelperLibrary, null); | 931 libraryLoader.importLibrary(library, jsHelperLibrary, null); |
930 } | 932 } |
931 } | 933 } |
932 | 934 |
933 /** | 935 /** |
934 * Get an [Uri] pointing to a patch for the dart: library with | 936 * Get an [Uri] pointing to a patch for the dart: library with |
935 * the given path. Returns null if there is no patch. | 937 * the given path. Returns null if there is no patch. |
936 */ | 938 */ |
937 Uri resolvePatchUri(String dartLibraryPath); | 939 Uri resolvePatchUri(String dartLibraryPath); |
938 | 940 |
939 void runCompiler(Uri uri) { | 941 Future runCompiler(Uri uri) { |
940 // TODO(ahe): This prevents memory leaks when invoking the compiler | 942 // TODO(ahe): This prevents memory leaks when invoking the compiler |
941 // multiple times. Implement a better mechanism where StringWrapper | 943 // multiple times. Implement a better mechanism where StringWrapper |
942 // instances are shared on a per library basis. | 944 // instances are shared on a per library basis. |
943 SourceString.canonicalizedValues.clear(); | 945 SourceString.canonicalizedValues.clear(); |
944 | 946 |
945 assert(uri != null || analyzeOnly); | 947 assert(uri != null || analyzeOnly); |
946 scanBuiltinLibraries(); | 948 return scanBuiltinLibraries().then((_) { |
947 if (librariesToAnalyzeWhenRun != null) { | 949 if (librariesToAnalyzeWhenRun != null) { |
948 for (Uri libraryUri in librariesToAnalyzeWhenRun) { | 950 return Future.forEach(librariesToAnalyzeWhenRun, (libraryUri) { |
949 log('analyzing $libraryUri ($buildId)'); | 951 log('analyzing $libraryUri ($buildId)'); |
950 libraryLoader.loadLibrary(libraryUri, null, libraryUri); | 952 return libraryLoader.loadLibrary(libraryUri, null, libraryUri); |
| 953 }); |
951 } | 954 } |
952 } | 955 }).then((_) { |
953 if (uri != null) { | 956 if (uri != null) { |
954 if (analyzeOnly) { | 957 if (analyzeOnly) { |
955 log('analyzing $uri ($buildId)'); | 958 log('analyzing $uri ($buildId)'); |
956 } else { | 959 } else { |
957 log('compiling $uri ($buildId)'); | 960 log('compiling $uri ($buildId)'); |
| 961 } |
| 962 return libraryLoader.loadLibrary(uri, null, uri) |
| 963 .then((LibraryElement library) { |
| 964 mainApp = library; |
| 965 }); |
958 } | 966 } |
959 mainApp = libraryLoader.loadLibrary(uri, null, uri); | 967 }).then((_) { |
960 } | 968 compileLoadedLibraries(); |
| 969 }); |
| 970 } |
| 971 |
| 972 /// Performs the compilation when all libraries have been loaded. |
| 973 void compileLoadedLibraries() { |
961 Element main = null; | 974 Element main = null; |
962 if (mainApp != null) { | 975 if (mainApp != null) { |
963 main = mainApp.find(MAIN); | 976 main = mainApp.find(MAIN); |
964 if (main == null) { | 977 if (main == null) { |
965 if (!analyzeOnly) { | 978 if (!analyzeOnly) { |
966 // Allow analyze only of libraries with no main. | 979 // Allow analyze only of libraries with no main. |
967 reportFatalError( | 980 reportFatalError( |
968 mainApp, | 981 mainApp, |
969 MessageKind.GENERIC, | 982 MessageKind.GENERIC, |
970 {'text': 'Error: Could not find "${MAIN.slowToString()}".'}); | 983 {'text': 'Error: Could not find "${MAIN.slowToString()}".'}); |
971 } else if (!analyzeAll) { | 984 } else if (!analyzeAll) { |
972 reportFatalError( | 985 reportFatalError( |
973 mainApp, | 986 mainApp, |
974 MessageKind.GENERIC, | 987 MessageKind.GENERIC, |
975 {'text': 'Error: Could not find "${MAIN.slowToString()}". ' | 988 {'text': 'Error: Could not find "${MAIN.slowToString()}". ' |
976 'No source will be analyzed. ' | 989 'No source will be analyzed. ' |
977 'Use "--analyze-all" to analyze all code in the library.'}); | 990 'Use "--analyze-all" to analyze all code in the library.'}); |
978 } | 991 } |
979 } else { | 992 } else { |
980 if (!main.isFunction()) { | 993 if (!main.isFunction()) { |
981 reportFatalError( | 994 reportFatalError( |
982 main, | 995 main, |
983 MessageKind.GENERIC, | 996 MessageKind.GENERIC, |
984 {'text': 'Error: "${MAIN.slowToString()}" is not a function.'}); | 997 {'text': 'Error: "${MAIN.slowToString()}" is not a function.'}); |
985 } | 998 } |
986 FunctionElement mainMethod = main; | 999 FunctionElement mainMethod = main; |
987 FunctionSignature parameters = mainMethod.computeSignature(this); | 1000 FunctionSignature parameters = mainMethod.computeSignature(this); |
988 parameters.forEachParameter((Element parameter) { | 1001 parameters.forEachParameter((Element parameter) { |
989 reportError( | 1002 reportError( |
990 parameter, | 1003 parameter, |
991 MessageKind.GENERIC, | 1004 MessageKind.GENERIC, |
992 {'text': | 1005 {'text': |
993 'Error: "${MAIN.slowToString()}" cannot have parameters.'}); | 1006 'Error: "${MAIN.slowToString()}" cannot have parameters.'}); |
994 }); | 1007 }); |
995 } | 1008 } |
996 | 1009 |
997 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | 1010 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); |
998 | 1011 |
999 // In order to see if a library is deferred, we must compute the | 1012 // In order to see if a library is deferred, we must compute the |
1000 // compile-time constants that are metadata. This means adding | 1013 // compile-time constants that are metadata. This means adding |
1001 // something to the resolution queue. So we cannot wait with | 1014 // something to the resolution queue. So we cannot wait with |
1002 // this until after the resolution queue is processed. | 1015 // this until after the resolution queue is processed. |
1003 // TODO(ahe): Clean this up, for example, by not enqueueing | 1016 // TODO(ahe): Clean this up, for example, by not enqueueing |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. | 1052 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. |
1040 if (hasIsolateSupport()) { | 1053 if (hasIsolateSupport()) { |
1041 enqueuer.codegen.addToWorkList( | 1054 enqueuer.codegen.addToWorkList( |
1042 isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE)); | 1055 isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE)); |
1043 enqueuer.codegen.registerGetOfStaticFunction(mainApp.find(MAIN)); | 1056 enqueuer.codegen.registerGetOfStaticFunction(mainApp.find(MAIN)); |
1044 } | 1057 } |
1045 if (enabledNoSuchMethod) { | 1058 if (enabledNoSuchMethod) { |
1046 backend.enableNoSuchMethod(enqueuer.codegen); | 1059 backend.enableNoSuchMethod(enqueuer.codegen); |
1047 } | 1060 } |
1048 if (compileAll) { | 1061 if (compileAll) { |
1049 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, enqueuer.codegen)); | 1062 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, |
| 1063 enqueuer.codegen)); |
1050 } | 1064 } |
1051 processQueue(enqueuer.codegen, main); | 1065 processQueue(enqueuer.codegen, main); |
1052 enqueuer.codegen.logSummary(log); | 1066 enqueuer.codegen.logSummary(log); |
1053 | 1067 |
1054 if (compilationFailed) return; | 1068 if (compilationFailed) return; |
1055 | 1069 |
1056 backend.assembleProgram(); | 1070 backend.assembleProgram(); |
1057 | 1071 |
1058 checkQueues(); | 1072 checkQueues(); |
1059 | 1073 |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 Uri translateResolvedUri(LibraryElement importingLibrary, | 1380 Uri translateResolvedUri(LibraryElement importingLibrary, |
1367 Uri resolvedUri, Node node) { | 1381 Uri resolvedUri, Node node) { |
1368 unimplemented('Compiler.translateResolvedUri'); | 1382 unimplemented('Compiler.translateResolvedUri'); |
1369 } | 1383 } |
1370 | 1384 |
1371 /** | 1385 /** |
1372 * Reads the script specified by the [readableUri]. | 1386 * Reads the script specified by the [readableUri]. |
1373 * | 1387 * |
1374 * See [LibraryLoader] for terminology on URIs. | 1388 * See [LibraryLoader] for terminology on URIs. |
1375 */ | 1389 */ |
1376 Script readScript(Uri readableUri, [Node node]) { | 1390 Future<Script> readScript(Uri readableUri, [Element element, Node node]) { |
1377 unimplemented('Compiler.readScript'); | 1391 unimplemented('Compiler.readScript'); |
1378 } | 1392 } |
1379 | 1393 |
1380 String get legDirectory { | 1394 String get legDirectory { |
1381 unimplemented('Compiler.legDirectory'); | 1395 unimplemented('Compiler.legDirectory'); |
1382 } | 1396 } |
1383 | 1397 |
1384 // TODO(karlklose): split into findHelperFunction and findHelperClass and | 1398 // TODO(karlklose): split into findHelperFunction and findHelperClass and |
1385 // add a check that the element has the expected kind. | 1399 // add a check that the element has the expected kind. |
1386 Element findHelper(SourceString name) | 1400 Element findHelper(SourceString name) |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1510 * [invariant] as the argument to an [:assert:] statement: | 1524 * [invariant] as the argument to an [:assert:] statement: |
1511 * | 1525 * |
1512 * assert(invariant(position, isValid)); | 1526 * assert(invariant(position, isValid)); |
1513 * | 1527 * |
1514 * [spannable] must be non-null and will be used to provide positional | 1528 * [spannable] must be non-null and will be used to provide positional |
1515 * information in the generated error message. | 1529 * information in the generated error message. |
1516 */ | 1530 */ |
1517 bool invariant(Spannable spannable, var condition, {var message: null}) { | 1531 bool invariant(Spannable spannable, var condition, {var message: null}) { |
1518 // TODO(johnniwinther): Use [spannable] and [message] to provide better | 1532 // TODO(johnniwinther): Use [spannable] and [message] to provide better |
1519 // information on assertion errors. | 1533 // information on assertion errors. |
| 1534 if (spannable == null) { |
| 1535 throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE, |
| 1536 "Spannable was null for invariant. Use CURRENT_ELEMENT_SPANNABLE."); |
| 1537 } |
1520 if (condition is Function){ | 1538 if (condition is Function){ |
1521 condition = condition(); | 1539 condition = condition(); |
1522 } | 1540 } |
1523 if (spannable == null || !condition) { | 1541 if (!condition) { |
1524 if (message is Function) { | 1542 if (message is Function) { |
1525 message = message(); | 1543 message = message(); |
1526 } | 1544 } |
1527 throw new SpannableAssertionFailure(spannable, message); | 1545 throw new SpannableAssertionFailure(spannable, message); |
1528 } | 1546 } |
1529 return true; | 1547 return true; |
1530 } | 1548 } |
1531 | 1549 |
1532 /// A sink that drains into /dev/null. | 1550 /// A sink that drains into /dev/null. |
1533 class NullSink implements EventSink<String> { | 1551 class NullSink implements EventSink<String> { |
1534 final String name; | 1552 final String name; |
1535 | 1553 |
1536 NullSink(this.name); | 1554 NullSink(this.name); |
1537 | 1555 |
1538 add(String value) {} | 1556 add(String value) {} |
1539 | 1557 |
1540 void addError(Object error) {} | 1558 void addError(Object error) {} |
1541 | 1559 |
1542 void close() {} | 1560 void close() {} |
1543 | 1561 |
1544 toString() => name; | 1562 toString() => name; |
1545 | 1563 |
1546 /// Convenience method for getting an [api.CompilerOutputProvider]. | 1564 /// Convenience method for getting an [api.CompilerOutputProvider]. |
1547 static NullSink outputProvider(String name, String extension) { | 1565 static NullSink outputProvider(String name, String extension) { |
1548 return new NullSink('$name.$extension'); | 1566 return new NullSink('$name.$extension'); |
1549 } | 1567 } |
1550 } | 1568 } |
OLD | NEW |