| Index: mojo/public/dart/third_party/analyzer/lib/source/sdk_ext.dart
|
| diff --git a/mojo/public/dart/third_party/analyzer/lib/source/sdk_ext.dart b/mojo/public/dart/third_party/analyzer/lib/source/sdk_ext.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d16bb4775ed28d1c5aaacfb7d7f903f39636e5ab
|
| --- /dev/null
|
| +++ b/mojo/public/dart/third_party/analyzer/lib/source/sdk_ext.dart
|
| @@ -0,0 +1,183 @@
|
| +// Copyright (c) 2015, 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.
|
| +
|
| +library source.sdk_ext;
|
| +
|
| +import 'dart:convert';
|
| +import 'dart:core' hide Resource;
|
| +
|
| +import 'package:analyzer/file_system/file_system.dart';
|
| +import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
|
| +import 'package:path/path.dart' as pathos;
|
| +
|
| +/// Given a packageMap (see [PackageMapProvider]), check in each package's lib
|
| +/// directory for the existence of a `_sdkext` file. This file must contain a
|
| +/// JSON encoded map. Each key in the map is a `dart:` library name. Each value
|
| +/// is a path (relative to the directory containing `_sdkext`) to a dart script
|
| +/// for the given library. For example:
|
| +/// {
|
| +/// "dart:sky": "../sdk_ext/dart_sky.dart"
|
| +/// }
|
| +///
|
| +/// If a key doesn't begin with `dart:` it is ignored.
|
| +class SdkExtUriResolver extends UriResolver {
|
| + static const String SDK_EXT_NAME = '_sdkext';
|
| + static const String DART_COLON_PREFIX = 'dart:';
|
| +
|
| + final Map<String, String> _urlMappings = <String,String>{};
|
| +
|
| + /// Construct a [SdkExtUriResolver] from a package map
|
| + /// (see [PackageMapProvider]).
|
| + SdkExtUriResolver(Map<String, List<Folder>> packageMap) {
|
| + if (packageMap == null) {
|
| + return;
|
| + }
|
| + packageMap.forEach(_processPackage);
|
| + }
|
| +
|
| + /// Number of sdk extensions.
|
| + int get length => _urlMappings.length;
|
| +
|
| + /// Return the path mapping for [libName] or null if there is none.
|
| + String operator[](String libName) => _urlMappings[libName];
|
| +
|
| + /// Programmatically add a new SDK extension given a JSON description
|
| + /// ([sdkExtJSON]) and a lib directory ([libDir]).
|
| + void addSdkExt(String sdkExtJSON, Folder libDir) {
|
| + _processSdkExt(sdkExtJSON, libDir);
|
| + }
|
| +
|
| + @override
|
| + Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
|
| + String libraryName = _libraryName(importUri);
|
| + String partPath = _partPath(importUri);
|
| + // Lookup library name in mappings.
|
| + String mapping = _urlMappings[libraryName];
|
| + if (mapping == null) {
|
| + // Not found.
|
| + return null;
|
| + }
|
| + // This mapping points to the main entry file of the sdk extension.
|
| + Uri libraryEntry = new Uri.file(mapping);
|
| + if (!libraryEntry.isAbsolute) {
|
| + // We expect an absolute path.
|
| + return null;
|
| + }
|
| +
|
| + if (partPath != null) {
|
| + return _resolvePart(libraryEntry, partPath, importUri);
|
| + } else {
|
| + return _resolveEntry(libraryEntry, importUri);
|
| + }
|
| + }
|
| +
|
| + @override
|
| + Uri restoreAbsolute(Source source) {
|
| + String extensionName = _findExtensionNameFor(source.fullName);
|
| + if (extensionName != null) {
|
| + return Uri.parse(extensionName);
|
| + }
|
| + // TODO(johnmccutchan): Handle restoring parts.
|
| + return null;
|
| + }
|
| +
|
| + /// Return the extension name for [fullName] or `null`.
|
| + String _findExtensionNameFor(String fullName) {
|
| + var result;
|
| + _urlMappings.forEach((extensionName, pathMapping) {
|
| + if (pathMapping == fullName) {
|
| + result = extensionName;
|
| + }
|
| + });
|
| + return result;
|
| + }
|
| +
|
| + /// Return the library name of [importUri].
|
| + String _libraryName(Uri importUri) {
|
| + var uri = importUri.toString();
|
| + int index = uri.indexOf('/');
|
| + if (index >= 0) {
|
| + return uri.substring(0, index);
|
| + }
|
| + return uri;
|
| + }
|
| +
|
| + /// Return the part path of [importUri].
|
| + String _partPath(Uri importUri) {
|
| + var uri = importUri.toString();
|
| + int index = uri.indexOf('/');
|
| + if (index >= 0) {
|
| + return uri.substring(index + 1);
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + /// Given a package [name] and a list of folders ([libDirs]),
|
| + /// add any found sdk extensions.
|
| + void _processPackage(String name, List<Folder> libDirs) {
|
| + for (var libDir in libDirs) {
|
| + var sdkExt = _readDotSdkExt(libDir);
|
| + if (sdkExt != null) {
|
| + _processSdkExt(sdkExt, libDir);
|
| + }
|
| + }
|
| + }
|
| +
|
| + /// Given the JSON for an SDK extension ([sdkExtJSON]) and a folder
|
| + /// ([libDir]), setup the uri mapping.
|
| + void _processSdkExt(String sdkExtJSON, Folder libDir) {
|
| + var sdkExt;
|
| + try {
|
| + sdkExt = JSON.decode(sdkExtJSON);
|
| + } catch (e) {
|
| + return;
|
| + }
|
| + if ((sdkExt == null) || (sdkExt is! Map)) {
|
| + return;
|
| + }
|
| + sdkExt.forEach((k, v) => _processSdkExtension(k, v, libDir));
|
| + }
|
| +
|
| + /// Install the mapping from [name] to [libDir]/[file].
|
| + void _processSdkExtension(String name, String file, Folder libDir) {
|
| + if (!name.startsWith(DART_COLON_PREFIX)) {
|
| + // SDK extensions must begin with 'dart:'.
|
| + return;
|
| + }
|
| + var key = name;
|
| + var value = libDir.canonicalizePath(file);
|
| + _urlMappings[key] = value;
|
| + }
|
| +
|
| + /// Read the contents of [libDir]/[SDK_EXT_NAME] as a string.
|
| + /// Returns null if the file doesn't exist.
|
| + String _readDotSdkExt(Folder libDir) {
|
| + var file = libDir.getChild(SDK_EXT_NAME);
|
| + try {
|
| + return file.readAsStringSync();
|
| + } on FileSystemException {
|
| + // File can't be read.
|
| + return null;
|
| + }
|
| + }
|
| +
|
| + /// Resolve an import of an sdk extension.
|
| + Source _resolveEntry(Uri libraryEntry, Uri importUri) {
|
| + // Library entry.
|
| + JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
|
| + return new FileBasedSource(javaFile, importUri);
|
| + }
|
| +
|
| + /// Resolve a 'part' statement inside an sdk extension.
|
| + Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
|
| + // Library part.
|
| + var directory = pathos.dirname(libraryEntry.path);
|
| + var partUri = new Uri.file(pathos.join(directory, partPath));
|
| + assert(partUri.isAbsolute);
|
| + JavaFile javaFile = new JavaFile.fromUri(partUri);
|
| + return new FileBasedSource(javaFile, importUri);
|
| + }
|
| +}
|
|
|