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 | 7 import 'dart:async' show |
8 EventSink, | 8 EventSink, |
9 Future; | 9 Future; |
10 | 10 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 import 'tree/tree.dart' show | 126 import 'tree/tree.dart' show |
127 Node; | 127 Node; |
128 import 'typechecker.dart' show | 128 import 'typechecker.dart' show |
129 TypeCheckerTask; | 129 TypeCheckerTask; |
130 import 'types/types.dart' as ti; | 130 import 'types/types.dart' as ti; |
131 import 'universe/universe.dart' show | 131 import 'universe/universe.dart' show |
132 CallStructure, | 132 CallStructure, |
133 Selector, | 133 Selector, |
134 Universe; | 134 Universe; |
135 import 'util/util.dart' show | 135 import 'util/util.dart' show |
136 Link; | 136 Link, |
| 137 Setlet; |
137 import 'world.dart' show | 138 import 'world.dart' show |
138 World; | 139 World; |
139 | 140 |
140 abstract class Compiler implements DiagnosticListener { | 141 abstract class Compiler implements DiagnosticListener { |
141 | 142 |
142 final Stopwatch totalCompileTime = new Stopwatch(); | 143 final Stopwatch totalCompileTime = new Stopwatch(); |
143 int nextFreeClassId = 0; | 144 int nextFreeClassId = 0; |
144 World world; | 145 World world; |
145 Types types; | 146 Types types; |
146 _CompilerCoreTypes _coreTypes; | 147 _CompilerCoreTypes _coreTypes; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 /// Generate output even when there are compile-time errors. | 269 /// Generate output even when there are compile-time errors. |
269 final bool generateCodeWithCompileTimeErrors; | 270 final bool generateCodeWithCompileTimeErrors; |
270 | 271 |
271 /// The compiler is run from the build bot. | 272 /// The compiler is run from the build bot. |
272 final bool testMode; | 273 final bool testMode; |
273 | 274 |
274 bool disableInlining = false; | 275 bool disableInlining = false; |
275 | 276 |
276 List<Uri> librariesToAnalyzeWhenRun; | 277 List<Uri> librariesToAnalyzeWhenRun; |
277 | 278 |
| 279 /// The set of platform libraries reported as unsupported. |
| 280 /// |
| 281 /// For instance when importing 'dart:io' without '--categories=Server'. |
| 282 Set<Uri> disallowedLibraryUris = new Setlet<Uri>(); |
| 283 |
278 Tracer tracer; | 284 Tracer tracer; |
279 | 285 |
280 CompilerTask measuredTask; | 286 CompilerTask measuredTask; |
281 Element _currentElement; | 287 Element _currentElement; |
282 LibraryElement coreLibrary; | 288 LibraryElement coreLibrary; |
283 LibraryElement asyncLibrary; | 289 LibraryElement asyncLibrary; |
284 | 290 |
285 LibraryElement mainApp; | 291 LibraryElement mainApp; |
286 FunctionElement mainFunction; | 292 FunctionElement mainFunction; |
287 | 293 |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 _coreTypes.streamClass = findRequiredElement(library, 'Stream'); | 769 _coreTypes.streamClass = findRequiredElement(library, 'Stream'); |
764 } else if (uri == Uris.dart__native_typed_data) { | 770 } else if (uri == Uris.dart__native_typed_data) { |
765 typedDataClass = findRequiredElement(library, 'NativeTypedData'); | 771 typedDataClass = findRequiredElement(library, 'NativeTypedData'); |
766 } else if (uri == js_backend.JavaScriptBackend.DART_JS_HELPER) { | 772 } else if (uri == js_backend.JavaScriptBackend.DART_JS_HELPER) { |
767 patchAnnotationClass = findRequiredElement(library, '_Patch'); | 773 patchAnnotationClass = findRequiredElement(library, '_Patch'); |
768 nativeAnnotationClass = findRequiredElement(library, 'Native'); | 774 nativeAnnotationClass = findRequiredElement(library, 'Native'); |
769 } | 775 } |
770 return backend.onLibraryScanned(library, loader); | 776 return backend.onLibraryScanned(library, loader); |
771 } | 777 } |
772 | 778 |
| 779 /// Compute the set of distinct import chains to the library at [uri] within |
| 780 /// [loadedLibraries]. |
| 781 /// |
| 782 /// The chains are strings of the form |
| 783 /// |
| 784 /// <main-uri> => <intermediate-uri1> => <intermediate-uri2> => <uri> |
| 785 /// |
| 786 Set<String> computeImportChainsFor(LoadedLibraries loadedLibraries, Uri uri) { |
| 787 // TODO(johnniwinther): Move computation of dependencies to the library |
| 788 // loader. |
| 789 Uri rootUri = loadedLibraries.rootUri; |
| 790 Set<String> importChains = new Set<String>(); |
| 791 // The maximum number of full imports chains to process. |
| 792 final int chainLimit = 10000; |
| 793 // The maximum number of imports chains to show. |
| 794 final int compactChainLimit = verbose ? 20 : 10; |
| 795 int chainCount = 0; |
| 796 loadedLibraries.forEachImportChain(uri, |
| 797 callback: (Link<Uri> importChainReversed) { |
| 798 Link<CodeLocation> compactImportChain = const Link<CodeLocation>(); |
| 799 CodeLocation currentCodeLocation = |
| 800 new UriLocation(importChainReversed.head); |
| 801 compactImportChain = compactImportChain.prepend(currentCodeLocation); |
| 802 for (Link<Uri> link = importChainReversed.tail; |
| 803 !link.isEmpty; |
| 804 link = link.tail) { |
| 805 Uri uri = link.head; |
| 806 if (!currentCodeLocation.inSameLocation(uri)) { |
| 807 currentCodeLocation = |
| 808 verbose ? new UriLocation(uri) : new CodeLocation(uri); |
| 809 compactImportChain = |
| 810 compactImportChain.prepend(currentCodeLocation); |
| 811 } |
| 812 } |
| 813 String importChain = |
| 814 compactImportChain.map((CodeLocation codeLocation) { |
| 815 return codeLocation.relativize(rootUri); |
| 816 }).join(' => '); |
| 817 |
| 818 if (!importChains.contains(importChain)) { |
| 819 if (importChains.length > compactChainLimit) { |
| 820 importChains.add('...'); |
| 821 return false; |
| 822 } else { |
| 823 importChains.add(importChain); |
| 824 } |
| 825 } |
| 826 |
| 827 chainCount++; |
| 828 if (chainCount > chainLimit) { |
| 829 // Assume there are more import chains. |
| 830 importChains.add('...'); |
| 831 return false; |
| 832 } |
| 833 return true; |
| 834 }); |
| 835 return importChains; |
| 836 } |
| 837 |
| 838 /// Register that [uri] was recognized but disallowed as a dependency. |
| 839 /// |
| 840 /// For instance import of 'dart:io' without '--categories=Server'. |
| 841 void registerDisallowedLibraryUse(Uri uri) { |
| 842 disallowedLibraryUris.add(uri); |
| 843 } |
| 844 |
773 /// This method is called when all new libraries loaded through | 845 /// This method is called when all new libraries loaded through |
774 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports | 846 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports |
775 /// have been computed. | 847 /// have been computed. |
776 /// | 848 /// |
777 /// [loadedLibraries] contains the newly loaded libraries. | 849 /// [loadedLibraries] contains the newly loaded libraries. |
778 /// | 850 /// |
779 /// The method returns a [Future] allowing for the loading of additional | 851 /// The method returns a [Future] allowing for the loading of additional |
780 /// libraries. | 852 /// libraries. |
781 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { | 853 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
782 return new Future.sync(() { | 854 return new Future.sync(() { |
| 855 for (Uri uri in disallowedLibraryUris) { |
| 856 if (loadedLibraries.containsLibrary(uri)) { |
| 857 Set<String> importChains = |
| 858 computeImportChainsFor(loadedLibraries, Uri.parse('dart:io')); |
| 859 reportInfo(NO_LOCATION_SPANNABLE, |
| 860 MessageKind.DISALLOWED_LIBRARY_IMPORT, |
| 861 {'uri': uri, |
| 862 'importChain': importChains.join( |
| 863 MessageTemplate.DISALLOWED_LIBRARY_IMPORT_PADDING)}); |
| 864 } |
| 865 } |
| 866 |
783 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { | 867 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { |
784 return null; | 868 return null; |
785 } | 869 } |
| 870 |
786 if (!enableExperimentalMirrors && | 871 if (!enableExperimentalMirrors && |
787 loadedLibraries.containsLibrary(Uris.dart_mirrors)) { | 872 loadedLibraries.containsLibrary(Uris.dart_mirrors)) { |
788 // TODO(johnniwinther): Move computation of dependencies to the library | 873 Set<String> importChains = |
789 // loader. | 874 computeImportChainsFor(loadedLibraries, Uris.dart_mirrors); |
790 Uri rootUri = loadedLibraries.rootUri; | |
791 Set<String> importChains = new Set<String>(); | |
792 // The maximum number of full imports chains to process. | |
793 final int chainLimit = 10000; | |
794 // The maximum number of imports chains to show. | |
795 final int compactChainLimit = verbose ? 20 : 10; | |
796 int chainCount = 0; | |
797 loadedLibraries.forEachImportChain(Uris.dart_mirrors, | |
798 callback: (Link<Uri> importChainReversed) { | |
799 Link<CodeLocation> compactImportChain = const Link<CodeLocation>(); | |
800 CodeLocation currentCodeLocation = | |
801 new UriLocation(importChainReversed.head); | |
802 compactImportChain = compactImportChain.prepend(currentCodeLocation); | |
803 for (Link<Uri> link = importChainReversed.tail; | |
804 !link.isEmpty; | |
805 link = link.tail) { | |
806 Uri uri = link.head; | |
807 if (!currentCodeLocation.inSameLocation(uri)) { | |
808 currentCodeLocation = | |
809 verbose ? new UriLocation(uri) : new CodeLocation(uri); | |
810 compactImportChain = | |
811 compactImportChain.prepend(currentCodeLocation); | |
812 } | |
813 } | |
814 String importChain = | |
815 compactImportChain.map((CodeLocation codeLocation) { | |
816 return codeLocation.relativize(rootUri); | |
817 }).join(' => '); | |
818 | |
819 if (!importChains.contains(importChain)) { | |
820 if (importChains.length > compactChainLimit) { | |
821 importChains.add('...'); | |
822 return false; | |
823 } else { | |
824 importChains.add(importChain); | |
825 } | |
826 } | |
827 | |
828 chainCount++; | |
829 if (chainCount > chainLimit) { | |
830 // Assume there are more import chains. | |
831 importChains.add('...'); | |
832 return false; | |
833 } | |
834 return true; | |
835 }); | |
836 | |
837 if (!backend.supportsReflection) { | 875 if (!backend.supportsReflection) { |
838 reportError(NO_LOCATION_SPANNABLE, | 876 reportError(NO_LOCATION_SPANNABLE, |
839 MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND); | 877 MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND); |
840 } else { | 878 } else { |
841 reportWarning(NO_LOCATION_SPANNABLE, | 879 reportWarning(NO_LOCATION_SPANNABLE, |
842 MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, | 880 MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, |
843 {'importChain': importChains.join( | 881 {'importChain': importChains.join( |
844 MessageTemplate.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}); | 882 MessageTemplate.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}); |
845 } | 883 } |
846 } | 884 } |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1792 | 1830 |
1793 @override | 1831 @override |
1794 InterfaceType streamType([DartType elementType]) { | 1832 InterfaceType streamType([DartType elementType]) { |
1795 InterfaceType type = streamClass.computeType(compiler); | 1833 InterfaceType type = streamClass.computeType(compiler); |
1796 if (elementType == null) { | 1834 if (elementType == null) { |
1797 return streamClass.rawType; | 1835 return streamClass.rawType; |
1798 } | 1836 } |
1799 return type.createInstantiation([elementType]); | 1837 return type.createInstantiation([elementType]); |
1800 } | 1838 } |
1801 } | 1839 } |
OLD | NEW |