| Index: pkg/compiler/lib/src/resolved_uri_translator.dart
|
| diff --git a/pkg/compiler/lib/src/resolved_uri_translator.dart b/pkg/compiler/lib/src/resolved_uri_translator.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..41a96b3c92f54e447e826787f9e07f754600b104
|
| --- /dev/null
|
| +++ b/pkg/compiler/lib/src/resolved_uri_translator.dart
|
| @@ -0,0 +1,161 @@
|
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +import 'common.dart';
|
| +import 'elements/elements.dart' show LibraryElement;
|
| +import 'util/emptyset.dart';
|
| +
|
| +/// API used by the library loader to translate internal SDK URIs into file
|
| +/// system readable URIs.
|
| +abstract class ResolvedUriTranslator {
|
| + factory ResolvedUriTranslator(
|
| + Map<String, Uri> sdkLibraries, DiagnosticReporter reporter) =
|
| + _ResolvedUriTranslator;
|
| +
|
| + /// The set of platform libraries reported as unsupported.
|
| + ///
|
| + /// For instance when importing 'dart:io' without '--categories=Server'.
|
| + Set<Uri> get disallowedLibraryUris;
|
| +
|
| + /// Whether or not a mockable library has been translated.
|
| + bool get mockableLibraryUsed;
|
| +
|
| + /// A mapping from dart: library names to their location.
|
| + Map<String, Uri> get sdkLibraries;
|
| +
|
| + /// Translates the resolved [uri] into a readable URI.
|
| + ///
|
| + /// The [importingLibrary] holds the library importing [uri] or `null` if
|
| + /// [uri] is loaded as the main library. The [importingLibrary] is used to
|
| + /// grant access to internal libraries from platform libraries and patch
|
| + /// libraries.
|
| + ///
|
| + /// If the [uri] is not accessible from [importingLibrary], this method is
|
| + /// responsible for reporting errors.
|
| + ///
|
| + /// See [LibraryLoader] for terminology on URIs.
|
| + Uri translate(LibraryElement importingLibrary, Uri uri,
|
| + [Spannable spannable]);
|
| +}
|
| +
|
| +/// A translator that forwards all methods to an internal
|
| +/// [ResolvedUriTranslator].
|
| +///
|
| +/// The translator to forward to may be set after the instance is constructed.
|
| +/// This is useful for the compiler because some tasks that are instantiated at
|
| +/// compiler construction time need a [ResolvedUriTranslator], but the data
|
| +/// required to instantiate it cannot be obtained at construction time. So a
|
| +/// [ForwardingResolvedUriTranslator] may be passed instead, and the translator
|
| +/// to forward to can be set once the required data has been retrieved.
|
| +class ForwardingResolvedUriTranslator implements ResolvedUriTranslator {
|
| + ResolvedUriTranslator resolvedUriTranslator;
|
| +
|
| + /// Returns `true` if [resolvedUriTranslator] is not `null`.
|
| + bool get isSet => resolvedUriTranslator != null;
|
| +
|
| + /// The opposite of [isSet].
|
| + bool get isNotSet => resolvedUriTranslator == null;
|
| +
|
| + @override
|
| + Uri translate(LibraryElement importingLibrary, Uri resolvedUri,
|
| + [Spannable spannable]) =>
|
| + resolvedUriTranslator.translate(importingLibrary, resolvedUri, spannable);
|
| +
|
| + @override
|
| + Set<Uri> get disallowedLibraryUris =>
|
| + resolvedUriTranslator?.disallowedLibraryUris ??
|
| + const ImmutableEmptySet<Uri>();
|
| +
|
| + @override
|
| + bool get mockableLibraryUsed => resolvedUriTranslator.mockableLibraryUsed;
|
| +
|
| + @override
|
| + Map<String, Uri> get sdkLibraries => resolvedUriTranslator.sdkLibraries;
|
| +}
|
| +
|
| +class _ResolvedUriTranslator implements ResolvedUriTranslator {
|
| + final Map<String, Uri> _sdkLibraries;
|
| + final DiagnosticReporter _reporter;
|
| +
|
| + Set<Uri> disallowedLibraryUris = new Set<Uri>();
|
| + bool mockableLibraryUsed = false;
|
| +
|
| + _ResolvedUriTranslator(this._sdkLibraries, this._reporter);
|
| +
|
| + Map<String, Uri> get sdkLibraries => _sdkLibraries;
|
| +
|
| + @override
|
| + Uri translate(LibraryElement importingLibrary, Uri uri,
|
| + [Spannable spannable]) {
|
| + if (uri.scheme == 'dart') {
|
| + return translateDartUri(importingLibrary, uri, spannable);
|
| + }
|
| + return uri;
|
| + }
|
| +
|
| + /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
|
| + /// to `options.platformConfigUri` according to the information in the file at
|
| + /// `options.platformConfigUri`.
|
| + ///
|
| + /// Returns `null` and emits an error if the library could not be found or
|
| + /// imported into [importingLibrary].
|
| + ///
|
| + /// Internal libraries (whose name starts with '_') can be only resolved if
|
| + /// [importingLibrary] is a platform or patch library.
|
| + Uri translateDartUri(
|
| + LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable) {
|
| + Uri location = lookupLibraryUri(resolvedUri.path);
|
| +
|
| + if (location == null) {
|
| + _reporter.reportErrorMessage(spannable, MessageKind.LIBRARY_NOT_FOUND,
|
| + {'resolvedUri': resolvedUri});
|
| + return null;
|
| + }
|
| +
|
| + if (resolvedUri.path.startsWith('_')) {
|
| + bool allowInternalLibraryAccess = importingLibrary != null &&
|
| + (importingLibrary.isPlatformLibrary ||
|
| + importingLibrary.isPatch ||
|
| + importingLibrary.canonicalUri.path
|
| + .contains('sdk/tests/compiler/dart2js_native'));
|
| +
|
| + if (!allowInternalLibraryAccess) {
|
| + if (importingLibrary != null) {
|
| + _reporter.reportErrorMessage(
|
| + spannable, MessageKind.INTERNAL_LIBRARY_FROM, {
|
| + 'resolvedUri': resolvedUri,
|
| + 'importingUri': importingLibrary.canonicalUri
|
| + });
|
| + } else {
|
| + _reporter.reportErrorMessage(spannable, MessageKind.INTERNAL_LIBRARY,
|
| + {'resolvedUri': resolvedUri});
|
| + registerDisallowedLibraryUse(resolvedUri);
|
| + }
|
| + return null;
|
| + }
|
| + }
|
| +
|
| + if (location.scheme == "unsupported") {
|
| + _reporter.reportErrorMessage(spannable, MessageKind.LIBRARY_NOT_SUPPORTED,
|
| + {'resolvedUri': resolvedUri});
|
| + registerDisallowedLibraryUse(resolvedUri);
|
| + return null;
|
| + }
|
| +
|
| + if (resolvedUri.path == 'html' || resolvedUri.path == 'io') {
|
| + // TODO(ahe): Get rid of mockableLibraryUsed when test.dart
|
| + // supports this use case better.
|
| + mockableLibraryUsed = true;
|
| + }
|
| + return location;
|
| + }
|
| +
|
| + void registerDisallowedLibraryUse(Uri uri) {
|
| + disallowedLibraryUris.add(uri);
|
| + }
|
| +
|
| + Uri lookupLibraryUri(String libraryName) {
|
| + return _sdkLibraries[libraryName];
|
| + }
|
| +}
|
|
|