Chromium Code Reviews| 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..683fd0424aafb2cc82702aeb0b762f4d956d24e7 |
| --- /dev/null |
| +++ b/pkg/compiler/lib/src/resolved_uri_translator.dart |
| @@ -0,0 +1,125 @@ |
| +// 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; |
| + |
| +/// 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 |
|
Johnni Winther
2016/04/13 08:21:43
[:null:] -> `null`
The [: ... :] notation is arch
Harry Terkelsen
2016/04/13 20:23:40
Done.
|
| + /// [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]); |
| +} |
| + |
| +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]; |
| + } |
| +} |