Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/library_loader.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart |
| index ccf513c2c692b6f7c01aa47a30b54db2c852f713..bcac74aa6ded9dfe9c742dabe574cb27009eb213 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/library_loader.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart |
| @@ -6,12 +6,93 @@ part of dart2js; |
| /** |
| * [CompilerTask] for loading libraries and setting up the import/export scopes. |
| + * |
| + * The library loader uses four different kinds of URIs in different parts of |
| + * the loading process. |
| + * |
| + * ## User URI ## |
| + * |
| + * A 'user URI' is a URI provided by the user in code and as the main entry URI |
| + * at the command line. These generally come in 3 versions: |
| + * |
| + * * A relative URI such as 'foo.dart', '../bar.dart', and 'baz/boz.dart'. |
| + * |
| + * * A dart URI such as 'dart:core' and 'dart:_js_helper'. |
| + * |
| + * * A package URI such as 'package:foo.dart' and 'package:bar/baz.dart'. |
| + * |
| + * A user URI can also be absolute, like 'file:///foo.dart' or |
| + * 'http://example.com/bar.dart', but such URIs cannot necessarily be used for |
| + * locating source files, since the scheme must be supported by the input |
| + * provider. The standard input provider for dart2js only supports the 'file' |
| + * scheme. |
| + * |
| + * ## Absolute URI ## |
|
ahe
2013/01/24 10:00:57
I would call this "resolved".
Johnni Winther
2013/01/24 13:04:59
Done.
|
| + * |
| + * An 'absolute URI' is a (user) URI that has been resolved to an absolute URI |
| + * based on the readable URI (see below) from which it was loaded. A URI with an |
| + * explicit scheme (such as 'dart:', 'package:' or 'file:') is already absolute. |
| + * A relative URI like for instance '../foo/bar.dart' is resolved into an |
| + * absolute URI in one of three ways: |
| + * |
| + * * If provided as the main entry URI at the command line, the URI is resolved |
| + * relative to the current working directory, say |
| + * 'file:///current/working/dir/', and the absolute URI is therefore |
| + * 'file:///current/working/foo/bar.dart'. |
| + * |
| + * * If the relative URI is provided in an import, export or part tag, and the |
| + * readable URI of the enclosing compilation unit is a file URI, |
| + * 'file://some/path/baz.dart', then the absolute URI is |
| + * 'file://some/foo/bar.dart'. |
| + * |
| + * * If the relative URI is provided in an import, export or part tag, and the |
| + * readable URI of the enclosing compilation unit is a package URI, |
| + * 'package:some/path/baz.dart', then the absolute URI is |
| + * 'package:some/foo/bar.dart'. |
| + * |
| + * The absolute URI thus preserves the scheme through resolution: A readable |
| + * file URI results in an absolute file URI and a readable package URI results |
| + * in an absolute package URI. Note that since a dart URI is not a readable URI, |
| + * import, export or part tags within platform libraries are not interpreted as |
| + * dart URIs but instead relative to the library source file location. |
| + * |
| + * The absolute URI of a library is also used as the canonical URI |
| + * ([LibraryElement.canonicalUri]) by which we identify which libraries are |
| + * identical. This means that libraries loaded through the 'package' scheme will |
| + * resolve to the same library when loaded from within using relative URIs (see |
| + * for instance the test 'standalone/package/package1_test.dart'). But loading a |
| + * platform library using a relative URI will _not_ result in the same library |
| + * as when loaded through the dart URI. |
| + * |
| + * ## Readable URI ## |
|
ahe
2013/01/24 10:00:57
I don't understand why we need both "readable URIs
Johnni Winther
2013/01/24 13:04:59
Added a discussion of this.
|
| + * |
| + * A 'readable URI' is an absolute URI whose scheme is either 'package' or |
| + * something supported by the input provider, normally 'file'. Dart URIs such as |
| + * 'dart:core' and 'dart:_js_helper' are not readable themselves but are instead |
| + * resolved into a readable URI using the library root URI provided from the |
| + * command line and the list of platform libraries found in |
| + * 'sdk/lib/_internal/libraries.dart'. This is done through the |
| + * [Compiler.resolveAbsoluteUri] method which checks whether a library by that |
| + * name exacts and in case of internal libraries whether access is granted. |
|
ahe
2013/01/24 10:00:57
exacts -> exists
Johnni Winther
2013/01/24 13:04:59
Done.
|
| + * |
| + * ## Resource URI ## |
| + * |
| + * A 'resource URI' is an absolute URI with is scheme supported by the input |
| + * provider. For the standard implementation this means a URI with the 'file' |
| + * scheme. Readable URIs are converted into resource URIs as part of the |
| + * [Compiler.readScript] method. In the standard implementation the package URIs |
| + * are converted to file URIs using the package root URI provided on the |
| + * command line as base. If the package root URI is |
| + * 'file:///current/working/dir/' then the package URI 'package:../foo/bar.dart' |
|
ahe
2013/01/24 10:00:57
This is a good example of something that shouldn't
Johnni Winther
2013/01/24 13:04:59
Changed the example since that was not crucial to
|
| + * will be resolved to the resource URI 'file:///current/working/foo/bar.dart'. |
| + * |
| */ |
| abstract class LibraryLoader extends CompilerTask { |
| LibraryLoader(Compiler compiler) : super(compiler); |
| /** |
| - * Loads the library located at [uri] and returns its [LibraryElement]. |
| + * Loads the library specified by the [absoluteUri] and returns its |
| + * [LibraryElement]. |
| * |
| * If the library is not already loaded, the method creates the |
| * [LibraryElement] for the library and computes the import/export scope, |
| @@ -20,7 +101,9 @@ abstract class LibraryLoader extends CompilerTask { |
| * |
| * This is the main entry point for [LibraryLoader]. |
| */ |
| - LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri); |
| + // TODO(johnniwinther): Remove [canonicalUri] together with |
| + // [Compiler.scanBuiltinLibrary]. |
| + LibraryElement loadLibrary(Uri absoluteUri, Node node, Uri canonicalUri); |
| // TODO(johnniwinther): Remove this when patches don't need special parsing. |
| void registerLibraryFromTag(LibraryDependencyHandler handler, |
| @@ -133,12 +216,12 @@ class LibraryLoaderTask extends LibraryLoader { |
| LibraryDependencyHandler currentHandler; |
| - LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri) { |
| + LibraryElement loadLibrary(Uri absoluteUri, Node node, Uri canonicalUri) { |
| return measure(() { |
| assert(currentHandler == null); |
| currentHandler = new LibraryDependencyHandler(compiler); |
| LibraryElement library = |
| - createLibrary(currentHandler, uri, node, canonicalUri); |
| + createLibrary(currentHandler, null, absoluteUri, node, canonicalUri); |
| currentHandler.computeExports(); |
| currentHandler = null; |
| return library; |
| @@ -193,21 +276,21 @@ class LibraryLoaderTask extends LibraryLoader { |
| } else if (tag.isPart) { |
| Part part = tag; |
| StringNode uri = part.uri; |
| - Uri resolved = base.resolve(uri.dartString.slowToString()); |
| + Uri absoluteUri = base.resolve(uri.dartString.slowToString()); |
| tagState = checkTag(TagState.SOURCE, part); |
| - scanPart(part, resolved, library); |
| + scanPart(part, absoluteUri, library); |
| } else { |
| compiler.internalError("Unhandled library tag.", node: tag); |
| } |
| } |
| // Apply patch, if any. |
| - if (library.uri.scheme == 'dart') { |
| - patchDartLibrary(handler, library, library.uri.path); |
| + if (library.isPlatformLibrary) { |
| + patchDartLibrary(handler, library, library.canonicalUri.path); |
| } |
| // Import dart:core if not already imported. |
| - if (!importsDartCore && !isDartCore(library.uri)) { |
| + if (!importsDartCore && !isDartCore(library.canonicalUri)) { |
| handler.registerDependency(library, null, loadCoreLibrary(handler)); |
| } |
| @@ -245,7 +328,8 @@ class LibraryLoaderTask extends LibraryLoader { |
| LibraryElement loadCoreLibrary(LibraryDependencyHandler handler) { |
| if (compiler.coreLibrary == null) { |
| Uri coreUri = new Uri.fromComponents(scheme: 'dart', path: 'core'); |
| - compiler.coreLibrary = createLibrary(handler, coreUri, null, coreUri); |
| + compiler.coreLibrary |
| + = createLibrary(handler, null, coreUri, null, coreUri); |
| } |
| return compiler.coreLibrary; |
| } |
| @@ -260,12 +344,13 @@ class LibraryLoaderTask extends LibraryLoader { |
| } |
| /** |
| - * Handle a part tag in the scope of [library]. The [path] given is used as |
| - * is, any URI resolution should be done beforehand. |
| + * Handle a part tag in the scope of [library]. The [absoluteUri] given is |
| + * used as is, any URI resolution should be done beforehand. |
| */ |
| - void scanPart(Part part, Uri path, LibraryElement library) { |
| - if (!path.isAbsolute()) throw new ArgumentError(path); |
| - Script sourceScript = compiler.readScript(path, part); |
| + void scanPart(Part part, Uri absoluteUri, LibraryElement library) { |
| + if (!absoluteUri.isAbsolute()) throw new ArgumentError(absoluteUri); |
| + Uri readableUri = compiler.resolveAbsoluteUri(library, absoluteUri, part); |
| + Script sourceScript = compiler.readScript(readableUri, part); |
| CompilationUnitElement unit = |
| new CompilationUnitElementX(sourceScript, library); |
| compiler.withCurrentElement(unit, () { |
| @@ -295,32 +380,40 @@ class LibraryLoaderTask extends LibraryLoader { |
| LibraryElement library, |
| LibraryDependency tag) { |
| Uri base = library.entryCompilationUnit.script.uri; |
| - Uri resolved = base.resolve(tag.uri.dartString.slowToString()); |
| + Uri absoluteUri = base.resolve(tag.uri.dartString.slowToString()); |
| LibraryElement loadedLibrary = |
| - createLibrary(handler, resolved, tag.uri, resolved); |
| + createLibrary(handler, library, absoluteUri, tag.uri, absoluteUri); |
| handler.registerDependency(library, tag, loadedLibrary); |
| if (!loadedLibrary.hasLibraryName()) { |
| compiler.withCurrentElement(library, () { |
| compiler.reportError(tag == null ? null : tag.uri, |
| - 'no library name found in ${loadedLibrary.uri}'); |
| + 'no library name found in ${loadedLibrary.canonicalUri}'); |
| }); |
| } |
| } |
| /** |
| - * Create (or reuse) a library element for the library located at [uri]. |
| + * Create (or reuse) a library element for the library specified by the |
| + * [absoluteUri]. |
| + * |
| * If a new library is created, the [handler] is notified. |
| */ |
| + // TODO(johnniwinther): Remove [canonicalUri] and make [absoluteUri] the |
| + // canonical uri when [Compiler.scanBuiltinLibrary] is removed. |
| LibraryElement createLibrary(LibraryDependencyHandler handler, |
| - Uri uri, Node node, Uri canonicalUri) { |
| + LibraryElement importingLibrary, |
| + Uri absoluteUri, Node node, Uri canonicalUri) { |
| bool newLibrary = false; |
| + Uri readableUri = |
| + compiler.resolveAbsoluteUri(importingLibrary, absoluteUri, node); |
| + if (readableUri == null) return null; |
| LibraryElement createLibrary() { |
| newLibrary = true; |
| - Script script = compiler.readScript(uri, node); |
| + Script script = compiler.readScript(readableUri, node); |
| LibraryElement element = new LibraryElementX(script, canonicalUri); |
| handler.registerNewLibrary(element); |
| - native.maybeEnableNative(compiler, element, uri); |
| + native.maybeEnableNative(compiler, element); |
| return element; |
| } |
| LibraryElement library; |
| @@ -335,7 +428,7 @@ class LibraryLoaderTask extends LibraryLoader { |
| compiler.scanner.scanLibrary(library); |
| processLibraryTags(handler, library); |
| handler.registerLibraryExports(library); |
| - compiler.onLibraryScanned(library, uri); |
| + compiler.onLibraryScanned(library, absoluteUri); |
| }); |
| } |
| return library; |