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]; |
+ } |
+} |