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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 checkNativeAnnotation(compiler, element); | 421 checkNativeAnnotation(compiler, element); |
422 } | 422 } |
423 }); | 423 }); |
424 } | 424 } |
425 return new Future.value(); | 425 return new Future.value(); |
426 } | 426 } |
427 | 427 |
428 /// This method is called when all new libraries loaded through | 428 /// This method is called when all new libraries loaded through |
429 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports | 429 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports |
430 /// have been computed. | 430 /// have been computed. |
431 Future onLibrariesLoaded(Map<Uri, LibraryElement> loadedLibraries) { | 431 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
432 return new Future.value(); | 432 return new Future.value(); |
433 } | 433 } |
434 | 434 |
435 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed | 435 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed |
436 /// annotations. The arguments corresponds to the unions of the corresponding | 436 /// annotations. The arguments corresponds to the unions of the corresponding |
437 /// fields of the annotations. | 437 /// fields of the annotations. |
438 void registerMirrorUsage(Set<String> symbols, | 438 void registerMirrorUsage(Set<String> symbols, |
439 Set<Element> targets, | 439 Set<Element> targets, |
440 Set<Element> metaTargets) {} | 440 Set<Element> metaTargets) {} |
441 | 441 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
649 /// When `true` emits URIs in the reflection metadata. | 649 /// When `true` emits URIs in the reflection metadata. |
650 final bool preserveUris; | 650 final bool preserveUris; |
651 | 651 |
652 final bool enableTypeAssertions; | 652 final bool enableTypeAssertions; |
653 final bool enableUserAssertions; | 653 final bool enableUserAssertions; |
654 final bool trustTypeAnnotations; | 654 final bool trustTypeAnnotations; |
655 final bool trustPrimitives; | 655 final bool trustPrimitives; |
656 final bool enableConcreteTypeInference; | 656 final bool enableConcreteTypeInference; |
657 final bool disableTypeInferenceFlag; | 657 final bool disableTypeInferenceFlag; |
658 final bool dumpInfo; | 658 final bool dumpInfo; |
659 final bool useContentSecurityPolicy; | 659 final bool useContentSecurityPolicy; |
floitsch
2014/11/18 15:50:01
Move `final bool enableExperimentalMirrors;` to he
Johnni Winther
2014/11/19 08:52:19
Done.
| |
660 | 660 |
661 /** | 661 /** |
662 * The maximum size of a concrete type before it widens to dynamic during | 662 * The maximum size of a concrete type before it widens to dynamic during |
663 * concrete type inference. | 663 * concrete type inference. |
664 */ | 664 */ |
665 final int maxConcreteTypeSize; | 665 final int maxConcreteTypeSize; |
666 final bool analyzeAllFlag; | 666 final bool analyzeAllFlag; |
667 final bool analyzeOnly; | 667 final bool analyzeOnly; |
668 | 668 |
669 /// If true, disable tree-shaking for the main script. | 669 /// If true, disable tree-shaking for the main script. |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
914 final Selector symbolValidatedConstructorSelector = new Selector.call( | 914 final Selector symbolValidatedConstructorSelector = new Selector.call( |
915 'validated', null, 1); | 915 'validated', null, 1); |
916 final Selector fromEnvironmentSelector = new Selector.callConstructor( | 916 final Selector fromEnvironmentSelector = new Selector.callConstructor( |
917 'fromEnvironment', null, 2); | 917 'fromEnvironment', null, 2); |
918 | 918 |
919 bool enabledNoSuchMethod = false; | 919 bool enabledNoSuchMethod = false; |
920 bool enabledRuntimeType = false; | 920 bool enabledRuntimeType = false; |
921 bool enabledFunctionApply = false; | 921 bool enabledFunctionApply = false; |
922 bool enabledInvokeOn = false; | 922 bool enabledInvokeOn = false; |
923 bool hasIsolateSupport = false; | 923 bool hasIsolateSupport = false; |
924 final bool enableExperimentalMirrors; | |
924 | 925 |
925 Stopwatch progress; | 926 Stopwatch progress; |
926 | 927 |
927 bool get shouldPrintProgress { | 928 bool get shouldPrintProgress { |
928 return verbose && progress.elapsedMilliseconds > 500; | 929 return verbose && progress.elapsedMilliseconds > 500; |
929 } | 930 } |
930 | 931 |
931 static const int PHASE_SCANNING = 0; | 932 static const int PHASE_SCANNING = 0; |
932 static const int PHASE_RESOLVING = 1; | 933 static const int PHASE_RESOLVING = 1; |
933 static const int PHASE_DONE_RESOLVING = 2; | 934 static const int PHASE_DONE_RESOLVING = 2; |
(...skipping 28 matching lines...) Expand all Loading... | |
962 this.verbose: false, | 963 this.verbose: false, |
963 this.sourceMapUri: null, | 964 this.sourceMapUri: null, |
964 this.outputUri: null, | 965 this.outputUri: null, |
965 this.buildId: UNDETERMINED_BUILD_ID, | 966 this.buildId: UNDETERMINED_BUILD_ID, |
966 this.terseDiagnostics: false, | 967 this.terseDiagnostics: false, |
967 this.dumpInfo: false, | 968 this.dumpInfo: false, |
968 this.showPackageWarnings: false, | 969 this.showPackageWarnings: false, |
969 this.useContentSecurityPolicy: false, | 970 this.useContentSecurityPolicy: false, |
970 this.suppressWarnings: false, | 971 this.suppressWarnings: false, |
971 bool hasIncrementalSupport: false, | 972 bool hasIncrementalSupport: false, |
973 this.enableExperimentalMirrors: false, | |
972 this.enableAsyncAwait: false, | 974 this.enableAsyncAwait: false, |
973 this.enableEnums: false, | 975 this.enableEnums: false, |
974 api.CompilerOutputProvider outputProvider, | 976 api.CompilerOutputProvider outputProvider, |
975 List<String> strips: const []}) | 977 List<String> strips: const []}) |
976 : this.disableTypeInferenceFlag = | 978 : this.disableTypeInferenceFlag = |
977 disableTypeInferenceFlag || !emitJavaScript, | 979 disableTypeInferenceFlag || !emitJavaScript, |
978 this.analyzeOnly = | 980 this.analyzeOnly = |
979 analyzeOnly || analyzeSignaturesOnly || analyzeAllFlag, | 981 analyzeOnly || analyzeSignaturesOnly || analyzeAllFlag, |
980 this.analyzeSignaturesOnly = analyzeSignaturesOnly, | 982 this.analyzeSignaturesOnly = analyzeSignaturesOnly, |
981 this.analyzeAllFlag = analyzeAllFlag, | 983 this.analyzeAllFlag = analyzeAllFlag, |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1216 } | 1218 } |
1217 | 1219 |
1218 /// This method is called when all new libraries loaded through | 1220 /// This method is called when all new libraries loaded through |
1219 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports | 1221 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports |
1220 /// have been computed. | 1222 /// have been computed. |
1221 /// | 1223 /// |
1222 /// [loadedLibraries] contains the newly loaded libraries. | 1224 /// [loadedLibraries] contains the newly loaded libraries. |
1223 /// | 1225 /// |
1224 /// The method returns a [Future] allowing for the loading of additional | 1226 /// The method returns a [Future] allowing for the loading of additional |
1225 /// libraries. | 1227 /// libraries. |
1226 Future onLibrariesLoaded(Map<Uri, LibraryElement> loadedLibraries) { | 1228 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
1227 return new Future.sync(() { | 1229 return new Future.sync(() { |
1228 if (!loadedLibraries.containsKey(DART_CORE)) return new Future.value(); | 1230 if (!loadedLibraries.containsLibrary(DART_CORE)) { |
1231 return null; | |
1232 } | |
1233 if (!enableExperimentalMirrors && | |
1234 loadedLibraries.containsLibrary(DART_MIRRORS)) { | |
1235 // TODO(johnniwinther): Move computation of dependencies to the library | |
1236 // loader. | |
1237 Uri rootUri = loadedLibraries.rootUri; | |
1238 Set<String> importChains = new Set<String>(); | |
1239 // The maximum number of full imports chains to process. | |
1240 final int chainLimit = 10000; | |
1241 // The maximum number of imports chains to show. | |
1242 final int compactChainLimit = verbose ? 20 : 10; | |
1243 int chainCount = 0; | |
1244 bool limitExceeded = false; | |
1245 loadedLibraries.forEachImportChain(DART_MIRRORS, | |
1246 callback:(Link<Uri> importChainReversed) { | |
floitsch
2014/11/18 15:50:01
space after ':'.
Johnni Winther
2014/11/19 08:52:19
Done.
| |
1247 Link<CodeLocation> compactImportChain = const Link<CodeLocation>(); | |
1248 CodeLocation currentCodeLocation = | |
1249 new UriLocation(importChainReversed.head); | |
1250 compactImportChain = compactImportChain.prepend(currentCodeLocation); | |
1251 for (Link<Uri> link = importChainReversed.tail; | |
1252 !link.isEmpty; | |
1253 link = link.tail) { | |
1254 Uri uri = link.head; | |
1255 if (!currentCodeLocation.inSameLocation(uri)) { | |
1256 currentCodeLocation = | |
1257 verbose ? new UriLocation(uri) : new CodeLocation(uri); | |
1258 compactImportChain = | |
1259 compactImportChain.prepend(currentCodeLocation); | |
1260 } | |
1261 } | |
1262 String importChain = | |
1263 compactImportChain.map((CodeLocation codeLocation) { | |
1264 return codeLocation.relativize(rootUri); | |
floitsch
2014/11/18 15:50:01
This indentation just doesn't work for me... (even
Johnni Winther
2014/11/19 08:52:19
Done. Didn't like it either.
| |
1265 }).join(' => '); | |
1266 | |
1267 if (!importChains.contains(importChain)) { | |
1268 if (importChains.length > compactChainLimit) { | |
1269 importChains.add('...'); | |
1270 return false; | |
1271 } else { | |
1272 importChains.add(importChain); | |
1273 } | |
1274 } | |
1275 | |
1276 chainCount++; | |
1277 if (chainCount > chainLimit) { | |
1278 // Assume there are more import chains. | |
1279 importChains.add('...'); | |
1280 return false; | |
1281 } | |
1282 return true; | |
1283 }); | |
1284 reportWarning(NO_LOCATION_SPANNABLE, | |
1285 MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, | |
1286 {'importChain': importChains.join( | |
1287 MessageKind.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}); | |
1288 } | |
1229 | 1289 |
1230 functionClass.ensureResolved(this); | 1290 functionClass.ensureResolved(this); |
1231 functionApplyMethod = functionClass.lookupLocalMember('apply'); | 1291 functionApplyMethod = functionClass.lookupLocalMember('apply'); |
1232 | 1292 |
1233 proxyConstant = | 1293 proxyConstant = |
1234 resolver.constantCompiler.compileConstant( | 1294 resolver.constantCompiler.compileConstant( |
1235 coreLibrary.find('proxy')).value; | 1295 coreLibrary.find('proxy')).value; |
1236 | 1296 |
1237 // TODO(johnniwinther): Move this to the JavaScript backend. | 1297 // TODO(johnniwinther): Move this to the JavaScript backend. |
1238 LibraryElement jsHelperLibrary = | 1298 LibraryElement jsHelperLibrary = loadedLibraries.getLibrary( |
1239 loadedLibraries[js_backend.JavaScriptBackend.DART_JS_HELPER]; | 1299 js_backend.JavaScriptBackend.DART_JS_HELPER); |
1240 if (jsHelperLibrary != null) { | 1300 if (jsHelperLibrary != null) { |
1241 patchConstant = resolver.constantCompiler.compileConstant( | 1301 patchConstant = resolver.constantCompiler.compileConstant( |
1242 jsHelperLibrary.find('patch')).value; | 1302 jsHelperLibrary.find('patch')).value; |
1243 } | 1303 } |
1244 | 1304 |
1245 if (preserveComments) { | 1305 if (preserveComments) { |
1246 return libraryLoader.loadLibrary(DART_MIRRORS) | 1306 return libraryLoader.loadLibrary(DART_MIRRORS) |
1247 .then((LibraryElement libraryElement) { | 1307 .then((LibraryElement libraryElement) { |
1248 documentClass = libraryElement.find('Comment'); | 1308 documentClass = libraryElement.find('Comment'); |
1249 }); | 1309 }); |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1956 /// canonical URI starts with 'package:foo/' is in user code. | 2016 /// canonical URI starts with 'package:foo/' is in user code. |
1957 /// | 2017 /// |
1958 /// If an entrypoint URI uses another scheme than 'package' then every library | 2018 /// If an entrypoint URI uses another scheme than 'package' then every library |
1959 /// with that scheme is in user code. For instance, an entry point URI is | 2019 /// with that scheme is in user code. For instance, an entry point URI is |
1960 /// 'file:///foo.dart' then every library whose canonical URI scheme is | 2020 /// 'file:///foo.dart' then every library whose canonical URI scheme is |
1961 /// 'file' is in user code. | 2021 /// 'file' is in user code. |
1962 /// | 2022 /// |
1963 /// If [assumeInUserCode] is `true`, [element] is assumed to be in user code | 2023 /// If [assumeInUserCode] is `true`, [element] is assumed to be in user code |
1964 /// if no entrypoints have been set. | 2024 /// if no entrypoints have been set. |
1965 bool inUserCode(Element element, {bool assumeInUserCode: false}) { | 2025 bool inUserCode(Element element, {bool assumeInUserCode: false}) { |
1966 List<Uri> entrypoints = <Uri>[]; | 2026 if (element == null) return false; |
2027 Iterable<CodeLocation> userCodeLocations = | |
2028 computeUserCodeLocations(assumeInUserCode: assumeInUserCode); | |
2029 Uri libraryUri = element.library.canonicalUri; | |
2030 return userCodeLocations.any( | |
2031 (CodeLocation codeLocation) => codeLocation.inSameLocation(libraryUri)); | |
2032 } | |
2033 | |
2034 Iterable<CodeLocation> computeUserCodeLocations( | |
2035 {bool assumeInUserCode: false}) { | |
2036 List<CodeLocation> userCodeLocations = <CodeLocation>[]; | |
1967 if (mainApp != null) { | 2037 if (mainApp != null) { |
1968 entrypoints.add(mainApp.canonicalUri); | 2038 userCodeLocations.add(new CodeLocation(mainApp.canonicalUri)); |
1969 } | 2039 } |
1970 if (librariesToAnalyzeWhenRun != null) { | 2040 if (librariesToAnalyzeWhenRun != null) { |
1971 entrypoints.addAll(librariesToAnalyzeWhenRun); | 2041 userCodeLocations.addAll(librariesToAnalyzeWhenRun.map( |
2042 (Uri uri) => new CodeLocation(uri))); | |
1972 } | 2043 } |
1973 if (entrypoints.isEmpty && assumeInUserCode) { | 2044 if (userCodeLocations.isEmpty && assumeInUserCode) { |
1974 // Assume in user code since [mainApp] has not been set yet. | 2045 // Assume in user code since [mainApp] has not been set yet. |
1975 return true; | 2046 userCodeLocations.add(const AnyLocation()); |
1976 } | 2047 } |
1977 if (element == null) return false; | 2048 return userCodeLocations; |
1978 Uri libraryUri = element.library.canonicalUri; | |
1979 if (libraryUri.scheme == 'package') { | |
1980 for (Uri uri in entrypoints) { | |
1981 if (uri.scheme != 'package') continue; | |
1982 int slashPos = libraryUri.path.indexOf('/'); | |
1983 if (slashPos != -1) { | |
1984 String packageName = libraryUri.path.substring(0, slashPos + 1); | |
1985 if (uri.path.startsWith(packageName)) { | |
1986 return true; | |
1987 } | |
1988 } else { | |
1989 if (libraryUri.path == uri.path) { | |
1990 return true; | |
1991 } | |
1992 } | |
1993 } | |
1994 } else { | |
1995 for (Uri uri in entrypoints) { | |
1996 if (libraryUri.scheme == uri.scheme) return true; | |
1997 } | |
1998 } | |
1999 return false; | |
2000 } | 2049 } |
2001 | 2050 |
2002 /// Return a canonical URI for the source of [element]. | 2051 /// Return a canonical URI for the source of [element]. |
2003 /// | 2052 /// |
2004 /// For a package library with canonical URI 'package:foo/bar/baz.dart' the | 2053 /// For a package library with canonical URI 'package:foo/bar/baz.dart' the |
2005 /// return URI is 'package:foo'. For non-package libraries the returned URI is | 2054 /// return URI is 'package:foo'. For non-package libraries the returned URI is |
2006 /// the canonical URI of the library itself. | 2055 /// the canonical URI of the library itself. |
2007 Uri getCanonicalUri(Element element) { | 2056 Uri getCanonicalUri(Element element) { |
2008 if (element == null) return null; | 2057 if (element == null) return null; |
2009 Uri libraryUri = element.library.canonicalUri; | 2058 Uri libraryUri = element.library.canonicalUri; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2181 int warnings = 0; | 2230 int warnings = 0; |
2182 int hints = 0; | 2231 int hints = 0; |
2183 } | 2232 } |
2184 | 2233 |
2185 class GenericTask extends CompilerTask { | 2234 class GenericTask extends CompilerTask { |
2186 final String name; | 2235 final String name; |
2187 | 2236 |
2188 GenericTask(this.name, Compiler compiler) | 2237 GenericTask(this.name, Compiler compiler) |
2189 : super(compiler); | 2238 : super(compiler); |
2190 } | 2239 } |
2240 | |
2241 /// [CodeLocation] divides uris into different classes. | |
2242 /// | |
2243 /// These are used to group uris from user code, platform libraries and | |
2244 /// packages. | |
2245 abstract class CodeLocation { | |
2246 /// Returns `true` if [uri] is in this code location. | |
2247 bool inSameLocation(Uri uri); | |
2248 | |
2249 /// Returns the uri of this location relative to [baseUri]. | |
2250 String relativize(Uri baseUri); | |
2251 | |
2252 factory CodeLocation(Uri uri) { | |
2253 if (uri.scheme == 'package') { | |
2254 int slashPos = uri.path.indexOf('/'); | |
2255 if (slashPos != -1) { | |
2256 String packageName = uri.path.substring(0, slashPos); | |
2257 return new PackageLocation(packageName); | |
2258 } else { | |
2259 return new UriLocation(uri); | |
2260 } | |
2261 } else { | |
2262 return new SchemeLocation(uri); | |
2263 } | |
2264 } | |
2265 } | |
2266 | |
2267 /// A code location defined by the scheme of the uri. | |
2268 /// | |
2269 /// Used for non-package uris, such as 'dart', 'file', and 'http'. | |
2270 class SchemeLocation implements CodeLocation { | |
2271 final Uri uri; | |
2272 | |
2273 SchemeLocation(this.uri); | |
2274 | |
2275 bool inSameLocation(Uri uri) { | |
2276 return this.uri.scheme == uri.scheme; | |
2277 } | |
2278 | |
2279 String relativize(Uri baseUri) { | |
2280 return uri_extras.relativize(baseUri, uri, false); | |
2281 } | |
2282 } | |
2283 | |
2284 /// A code location defined by the package name. | |
2285 /// | |
2286 /// Used for package uris, separated by their `package names`, that is, the | |
2287 /// 'foo' of 'package:foo/bar.dart'. | |
2288 class PackageLocation implements CodeLocation { | |
2289 final String packageName; | |
2290 | |
2291 PackageLocation(this.packageName); | |
2292 | |
2293 bool inSameLocation(Uri uri) { | |
2294 return uri.scheme == 'package' && uri.path.startsWith('$packageName/'); | |
2295 } | |
2296 | |
2297 String relativize(Uri baseUri) => 'package:$packageName'; | |
2298 } | |
2299 | |
2300 /// A code location defined by the whole uri. | |
2301 /// | |
2302 /// Used for package uris with no package name. For instance 'package:foo.dart'. | |
2303 class UriLocation implements CodeLocation { | |
2304 final Uri uri; | |
2305 | |
2306 UriLocation(this.uri); | |
2307 | |
2308 bool inSameLocation(Uri uri) => this.uri == uri; | |
2309 | |
2310 String relativize(Uri baseUri) { | |
2311 return uri_extras.relativize(baseUri, uri, false); | |
2312 } | |
2313 } | |
2314 | |
2315 /// A code location that contains any uri. | |
2316 class AnyLocation implements CodeLocation { | |
2317 const AnyLocation(); | |
2318 | |
2319 bool inSameLocation(Uri uri) => true; | |
2320 | |
2321 String relativize(Uri baseUri) => '$baseUri'; | |
2322 } | |
OLD | NEW |