Index: sdk/lib/_internal/compiler/implementation/compiler.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart |
index 646fefecd6b0f666607a99264ee00966b0b53697..59a79ee249a38ea3cb9dcbbda2c043bd31db2113 100644 |
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart |
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart |
@@ -428,7 +428,7 @@ abstract class Backend { |
/// This method is called when all new libraries loaded through |
/// [LibraryLoader.loadLibrary] has been loaded and their imports/exports |
/// have been computed. |
- Future onLibrariesLoaded(Map<Uri, LibraryElement> loadedLibraries) { |
+ Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
return new Future.value(); |
} |
@@ -903,6 +903,7 @@ abstract class Compiler implements DiagnosticListener { |
bool enabledFunctionApply = false; |
bool enabledInvokeOn = false; |
bool hasIsolateSupport = false; |
+ final bool enableExperimentalMirrors; |
Stopwatch progress; |
@@ -949,6 +950,7 @@ abstract class Compiler implements DiagnosticListener { |
this.useContentSecurityPolicy: false, |
this.suppressWarnings: false, |
bool hasIncrementalSupport: false, |
+ this.enableExperimentalMirrors: false, |
api.CompilerOutputProvider outputProvider, |
List<String> strips: const []}) |
: this.disableTypeInferenceFlag = |
@@ -1192,9 +1194,41 @@ abstract class Compiler implements DiagnosticListener { |
/// |
/// The method returns a [Future] allowing for the loading of additional |
/// libraries. |
- Future onLibrariesLoaded(Map<Uri, LibraryElement> loadedLibraries) { |
+ Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
return new Future.sync(() { |
- if (!loadedLibraries.containsKey(DART_CORE)) return new Future.value(); |
+ if (!loadedLibraries.containsLibrary(DART_CORE)) { |
+ return new Future.value(); |
floitsch
2014/09/22 20:52:59
return null is the same, since we are already in a
Johnni Winther
2014/11/12 13:06:26
Done.
|
+ } |
+ if (!enableExperimentalMirrors && |
+ loadedLibraries.containsLibrary(DART_MIRRORS)) { |
+ Uri rootUri = loadedLibraries.rootUri; |
+ Set<String> importChains = new Set<String>(); |
+ loadedLibraries.forEachImportChain( |
floitsch
2014/09/22 20:52:59
I would make this a function on LoadedLibraries:
Johnni Winther
2014/11/12 13:06:26
Added a TODO. We need to store the libraries for i
|
+ (LibraryElement library, Link<Uri> importChainReversed) { |
+ if (library.canonicalUri != DART_MIRRORS) return; |
+ Link<CodeLocation> compactImportChain = const Link<CodeLocation>(); |
+ CodeLocation currentCodeLocation = new UriLocation(DART_MIRRORS); |
+ compactImportChain = compactImportChain.prepend(currentCodeLocation); |
+ for (Link<Uri> link = importChainReversed; |
+ !link.isEmpty; |
+ link = link.tail) { |
+ Uri uri = link.head; |
+ if (!currentCodeLocation.inSameLocation(uri)) { |
+ currentCodeLocation = |
+ verbose ? new UriLocation(uri) : new CodeLocation(uri); |
+ compactImportChain = |
+ compactImportChain.prepend(currentCodeLocation); |
+ } |
+ } |
+ importChains.add(compactImportChain.map((CodeLocation codeLocation) { |
+ return codeLocation.relativize(rootUri); |
+ }).join(' => ')); |
+ }); |
+ reportWarning(NO_LOCATION_SPANNABLE, |
+ MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, |
+ {'importChain': importChains.join( |
+ MessageKind.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}); |
+ } |
functionClass.ensureResolved(this); |
functionApplyMethod = functionClass.lookupLocalMember('apply'); |
@@ -1203,8 +1237,8 @@ abstract class Compiler implements DiagnosticListener { |
resolver.constantCompiler.compileConstant(coreLibrary.find('proxy')); |
// TODO(johnniwinther): Move this to the JavaScript backend. |
- LibraryElement jsHelperLibrary = |
- loadedLibraries[js_backend.JavaScriptBackend.DART_JS_HELPER]; |
+ LibraryElement jsHelperLibrary = loadedLibraries.getLibrary( |
+ js_backend.JavaScriptBackend.DART_JS_HELPER); |
if (jsHelperLibrary != null) { |
patchConstant = resolver.constantCompiler.compileConstant( |
jsHelperLibrary.find('patch')); |
@@ -1934,40 +1968,29 @@ abstract class Compiler implements DiagnosticListener { |
/// If [assumeInUserCode] is `true`, [element] is assumed to be in user code |
/// if no entrypoints have been set. |
bool inUserCode(Element element, {bool assumeInUserCode: false}) { |
- List<Uri> entrypoints = <Uri>[]; |
+ if (element == null) return false; |
+ Iterable<CodeLocation> userCodeLocations = |
+ computeUserCodeLocations(assumeInUserCode: assumeInUserCode); |
+ Uri libraryUri = element.library.canonicalUri; |
+ return userCodeLocations.any( |
+ (CodeLocation codeLocation) => codeLocation.inSameLocation(libraryUri)); |
+ } |
+ |
+ Iterable<CodeLocation> computeUserCodeLocations( |
+ {bool assumeInUserCode: false}) { |
+ List<CodeLocation> userCodeLocations = <CodeLocation>[]; |
if (mainApp != null) { |
- entrypoints.add(mainApp.canonicalUri); |
+ userCodeLocations.add(new CodeLocation(mainApp.canonicalUri)); |
} |
if (librariesToAnalyzeWhenRun != null) { |
- entrypoints.addAll(librariesToAnalyzeWhenRun); |
+ userCodeLocations.addAll(librariesToAnalyzeWhenRun.map( |
+ (Uri uri) => new CodeLocation(uri))); |
} |
- if (entrypoints.isEmpty && assumeInUserCode) { |
+ if (userCodeLocations.isEmpty && assumeInUserCode) { |
// Assume in user code since [mainApp] has not been set yet. |
- return true; |
- } |
- if (element == null) return false; |
- Uri libraryUri = element.library.canonicalUri; |
- if (libraryUri.scheme == 'package') { |
- for (Uri uri in entrypoints) { |
- if (uri.scheme != 'package') continue; |
- int slashPos = libraryUri.path.indexOf('/'); |
- if (slashPos != -1) { |
- String packageName = libraryUri.path.substring(0, slashPos + 1); |
- if (uri.path.startsWith(packageName)) { |
- return true; |
- } |
- } else { |
- if (libraryUri.path == uri.path) { |
- return true; |
- } |
- } |
- } |
- } else { |
- for (Uri uri in entrypoints) { |
- if (libraryUri.scheme == uri.scheme) return true; |
- } |
+ userCodeLocations.add(const AnyLocation()); |
} |
- return false; |
+ return userCodeLocations; |
} |
/// Return a canonical URI for the source of [element]. |
@@ -2136,3 +2159,86 @@ class GenericTask extends CompilerTask { |
GenericTask(this.name, Compiler compiler) |
: super(compiler); |
} |
+ |
+/// [CodeLocation] divides uris into different classes. |
+/// |
+/// These are used to group uris from user code, platform libraries and |
+/// packages. |
+abstract class CodeLocation { |
+ /// Returns `true` if [uri] is in this code location. |
+ bool inSameLocation(Uri uri); |
+ |
+ /// Returns the uri of this location relative to [baseUri]. |
+ String relativize(Uri baseUri); |
+ |
+ factory CodeLocation(Uri uri) { |
+ if (uri.scheme == 'package') { |
+ int slashPos = uri.path.indexOf('/'); |
+ if (slashPos != -1) { |
+ String packageName = uri.path.substring(0, slashPos); |
+ return new PackageLocation(packageName); |
+ } else { |
+ return new UriLocation(uri); |
+ } |
+ } else { |
+ return new SchemeLocation(uri); |
+ } |
+ } |
+} |
+ |
+/// A code location defined by the scheme of the uri. |
+/// |
+/// Used for non-package uris, such as 'dart', 'file', and 'http'. |
+class SchemeLocation implements CodeLocation { |
+ final Uri uri; |
+ |
+ SchemeLocation(this.uri); |
+ |
+ bool inSameLocation(Uri uri) { |
+ return this.uri.scheme == uri.scheme; |
+ } |
+ |
+ String relativize(Uri baseUri) { |
+ return uri_extras.relativize(baseUri, uri, false); |
+ } |
+} |
+ |
+/// A code location defined by the package name. |
+/// |
+/// Used for package uris, separated by their `package names`, that is, the |
+/// 'foo' of 'package:foo/bar.dart'. |
+class PackageLocation implements CodeLocation { |
+ final String packageName; |
+ |
+ PackageLocation(this.packageName); |
+ |
+ bool inSameLocation(Uri uri) { |
+ return uri.scheme == 'package' && uri.path.startsWith('$packageName/'); |
+ } |
+ |
+ String relativize(Uri baseUri) => 'package:$packageName'; |
+} |
+ |
+/// A code location defined by the whole uri. |
+/// |
+/// Used for package uris with no package name. For instance 'package:foo.dart'. |
+class UriLocation implements CodeLocation { |
+ final Uri uri; |
+ |
+ UriLocation(this.uri); |
+ |
+ bool inSameLocation(Uri uri) => this.uri == uri; |
+ |
+ String relativize(Uri baseUri) { |
+ return uri_extras.relativize(baseUri, uri, false); |
+ } |
+} |
+ |
+/// A code location that contains any uri. |
+class AnyLocation implements CodeLocation { |
+ const AnyLocation(); |
+ |
+ bool inSameLocation(Uri uri) => true; |
+ |
+ String relativize(Uri baseUri) => '$baseUri'; |
+} |