| 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..39c084d954d32477d73f01a6c7f466b4148761fd 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
|
| @@ -6,12 +6,103 @@ 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.
|
| + *
|
| + * ## Resolved URI ##
|
| + *
|
| + * A 'resolved 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 resolved.
|
| + * A relative URI like for instance '../foo/bar.dart' is translated into an
|
| + * resolved 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 resolved 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 resolved 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 resolved URI is
|
| + * 'package:some/foo/bar.dart'.
|
| + *
|
| + * The resolved URI thus preserves the scheme through resolution: A readable
|
| + * file URI results in an resolved file URI and a readable package URI results
|
| + * in an resolved 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 resolved 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 ##
|
| + *
|
| + * 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.translateResolvedUri] method which checks whether a library by that
|
| + * name exists and in case of internal libraries whether access is granted.
|
| + *
|
| + * ## Resource URI ##
|
| + *
|
| + * A 'resource URI' is an absolute URI with a 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'
|
| + * will be resolved to the resource URI
|
| + * 'file:///current/working/dir/foo/bar.dart'.
|
| + *
|
| + * The distinction between readable URI and resource URI is necessary to ensure
|
| + * that these imports
|
| + *
|
| + * import 'package:foo.dart' as a;
|
| + * import 'packages/foo.dart' as b;
|
| + *
|
| + * do _not_ resolve to the same library when the package root URI happens to
|
| + * point to the 'packages' folder.
|
| + *
|
| */
|
| 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 [resolvedUri] 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 +111,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 resolvedUri, Node node, Uri canonicalUri);
|
|
|
| // TODO(johnniwinther): Remove this when patches don't need special parsing.
|
| void registerLibraryFromTag(LibraryDependencyHandler handler,
|
| @@ -133,12 +226,12 @@ class LibraryLoaderTask extends LibraryLoader {
|
|
|
| LibraryDependencyHandler currentHandler;
|
|
|
| - LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri) {
|
| + LibraryElement loadLibrary(Uri resolvedUri, Node node, Uri canonicalUri) {
|
| return measure(() {
|
| assert(currentHandler == null);
|
| currentHandler = new LibraryDependencyHandler(compiler);
|
| LibraryElement library =
|
| - createLibrary(currentHandler, uri, node, canonicalUri);
|
| + createLibrary(currentHandler, null, resolvedUri, node, canonicalUri);
|
| currentHandler.computeExports();
|
| currentHandler = null;
|
| return library;
|
| @@ -193,21 +286,21 @@ class LibraryLoaderTask extends LibraryLoader {
|
| } else if (tag.isPart) {
|
| Part part = tag;
|
| StringNode uri = part.uri;
|
| - Uri resolved = base.resolve(uri.dartString.slowToString());
|
| + Uri resolvedUri = base.resolve(uri.dartString.slowToString());
|
| tagState = checkTag(TagState.SOURCE, part);
|
| - scanPart(part, resolved, library);
|
| + scanPart(part, resolvedUri, 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 +338,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 +354,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 [resolvedUri] 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 resolvedUri, LibraryElement library) {
|
| + if (!resolvedUri.isAbsolute()) throw new ArgumentError(resolvedUri);
|
| + Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part);
|
| + Script sourceScript = compiler.readScript(readableUri, part);
|
| CompilationUnitElement unit =
|
| new CompilationUnitElementX(sourceScript, library);
|
| compiler.withCurrentElement(unit, () {
|
| @@ -295,32 +390,40 @@ class LibraryLoaderTask extends LibraryLoader {
|
| LibraryElement library,
|
| LibraryDependency tag) {
|
| Uri base = library.entryCompilationUnit.script.uri;
|
| - Uri resolved = base.resolve(tag.uri.dartString.slowToString());
|
| + Uri resolvedUri = base.resolve(tag.uri.dartString.slowToString());
|
| LibraryElement loadedLibrary =
|
| - createLibrary(handler, resolved, tag.uri, resolved);
|
| + createLibrary(handler, library, resolvedUri, tag.uri, resolvedUri);
|
| 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
|
| + * [resolvedUri].
|
| + *
|
| * If a new library is created, the [handler] is notified.
|
| */
|
| + // TODO(johnniwinther): Remove [canonicalUri] and make [resolvedUri] the
|
| + // canonical uri when [Compiler.scanBuiltinLibrary] is removed.
|
| LibraryElement createLibrary(LibraryDependencyHandler handler,
|
| - Uri uri, Node node, Uri canonicalUri) {
|
| + LibraryElement importingLibrary,
|
| + Uri resolvedUri, Node node, Uri canonicalUri) {
|
| bool newLibrary = false;
|
| + Uri readableUri =
|
| + compiler.translateResolvedUri(importingLibrary, resolvedUri, 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 +438,7 @@ class LibraryLoaderTask extends LibraryLoader {
|
| compiler.scanner.scanLibrary(library);
|
| processLibraryTags(handler, library);
|
| handler.registerLibraryExports(library);
|
| - compiler.onLibraryScanned(library, uri);
|
| + compiler.onLibraryScanned(library, resolvedUri);
|
| });
|
| }
|
| return library;
|
|
|