Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: pkg/compiler/lib/src/compiler.dart

Issue 588183002: Emit warning on import of dart:mirrors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Optimize and limit import chain processing Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698