Chromium Code Reviews| Index: pkg/analyzer/lib/source/embedder.dart |
| diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart |
| index c82e4f3780b5988bff4bcb935d69f6337240f681..5874d4f9873a5f67fc4f0e6d391590c03d063b75 100644 |
| --- a/pkg/analyzer/lib/source/embedder.dart |
| +++ b/pkg/analyzer/lib/source/embedder.dart |
| @@ -8,12 +8,19 @@ import 'dart:collection' show HashMap; |
| import 'dart:core' hide Resource; |
| import 'package:analyzer/file_system/file_system.dart'; |
| +import 'package:analyzer/src/context/context.dart'; |
| +import 'package:analyzer/src/generated/engine.dart'; |
| +import 'package:analyzer/src/generated/java_core.dart'; |
| +import 'package:analyzer/src/generated/java_engine.dart'; |
| import 'package:analyzer/src/generated/java_io.dart' show JavaFile; |
| +import 'package:analyzer/src/generated/sdk.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource; |
| import 'package:path/path.dart' as pathos; |
| import 'package:yaml/yaml.dart'; |
| +const String _DART_COLON_PREFIX = 'dart:'; |
|
Brian Wilkerson
2016/01/14 16:47:17
nit: Personally, I dislike top-level declarations
|
| + |
| /// Given a packageMap, check in each package's lib directory for the |
| /// existence of an `_embedder.yaml` file. If the file contains a top level |
| /// YamlMap, it will be added to the [embedderYamls] map. |
| @@ -79,7 +86,6 @@ class EmbedderYamlLocator { |
| embedderYamls[libDir] = yaml; |
| } |
| - |
| /// Read the contents of [libDir]/[EMBEDDER_FILE_NAME] as a string. |
| /// Returns null if the file doesn't exist. |
| String _readEmbedderYaml(Folder libDir) { |
| @@ -104,14 +110,14 @@ class EmbedderYamlLocator { |
| /// |
| /// If a key doesn't begin with `dart:` it is ignored. |
| /// |
| -class EmbedderUriResolver extends UriResolver { |
| - static const String DART_COLON_PREFIX = 'dart:'; |
| - |
| +class EmbedderUriResolver extends DartUriResolver { |
| final Map<String, String> _urlMappings = <String, String>{}; |
| /// Construct a [EmbedderUriResolver] from a package map |
| /// (see [PackageMapProvider]). |
| - EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls) { |
| + EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls) |
| + : super(new _EmbedderSdk()) { |
| + (dartSdk as _EmbedderSdk)._resolver = this; |
| if (embedderYamls == null) { |
| return; |
| } |
| @@ -126,13 +132,13 @@ class EmbedderUriResolver extends UriResolver { |
| if (embedder_libs is! YamlMap) { |
| return; |
| } |
| - (embedder_libs as YamlMap).forEach((k, v) => |
| - _processEmbedderLibs(k, v, libDir)); |
| + (embedder_libs as YamlMap) |
| + .forEach((k, v) => _processEmbedderLibs(k, v, libDir)); |
| } |
| /// Install the mapping from [name] to [libDir]/[file]. |
| void _processEmbedderLibs(String name, String file, Folder libDir) { |
| - if (!name.startsWith(DART_COLON_PREFIX)) { |
| + if (!name.startsWith(_DART_COLON_PREFIX)) { |
| // SDK libraries must begin with 'dart:'. |
| // TODO(pquitslund): Notify developer that something is wrong with the |
| // _embedder.yaml file in libDir. |
| @@ -141,6 +147,10 @@ class EmbedderUriResolver extends UriResolver { |
| String key = name; |
| String value = libDir.canonicalizePath(file); |
| _urlMappings[key] = value; |
| + String shortName = name.substring(_DART_COLON_PREFIX.length); |
| + SdkLibraryImpl library = new SdkLibraryImpl(shortName); |
| + library.path = value; |
| + (dartSdk as _EmbedderSdk)._librariesMap.setLibrary(name, library); |
| } |
| /// Number of embedder libraries. |
| @@ -231,3 +241,127 @@ class EmbedderUriResolver extends UriResolver { |
| return new FileBasedSource(javaFile, importUri); |
| } |
| } |
| + |
| +class _EmbedderSdk implements DartSdk { |
| + // TODO(danrubel) Refactor this with DirectoryBasedDartSdk |
| + |
| + /// The resolver associated with this embedder sdk. |
| + EmbedderUriResolver _resolver; |
| + |
| + /// The [AnalysisContext] which is used for all of the sources in this sdk. |
| + InternalAnalysisContext _analysisContext; |
| + |
| + /// The library map that is populated by visiting the AST structure parsed from |
| + /// the contents of the libraries file. |
| + final LibraryMap _librariesMap = new LibraryMap(); |
| + |
| + @override |
| + AnalysisContext get context { |
| + if (_analysisContext == null) { |
| + _analysisContext = new SdkAnalysisContext(); |
| + SourceFactory factory = new SourceFactory([_resolver]); |
| + _analysisContext.sourceFactory = factory; |
| + List<String> uris = this.uris; |
| + ChangeSet changeSet = new ChangeSet(); |
| + for (String uri in uris) { |
| + changeSet.addedSource(factory.forUri(uri)); |
| + } |
| + _analysisContext.applyChanges(changeSet); |
| + } |
| + return _analysisContext; |
| + } |
| + |
| + @override |
| + List<SdkLibrary> get sdkLibraries => _librariesMap.sdkLibraries; |
| + |
| + // TODO(danrubel) Determine SDK version |
| + @override |
| + String get sdkVersion => '0'; |
| + |
| + @override |
| + List<String> get uris => _librariesMap.uris; |
| + |
| + @override |
| + Source fromFileUri(Uri uri) { |
| + JavaFile file = new JavaFile.fromUri(uri); |
| + String filePath = file.getAbsolutePath(); |
| + String srcPath = filePath.replaceAll('\\', '/'); |
| + |
| + String path; |
| + for (SdkLibrary library in _librariesMap.sdkLibraries) { |
| + String libraryPath = library.path; |
| + if (srcPath == libraryPath) { |
| + path = '$_DART_COLON_PREFIX${library.shortName}'; |
| + break; |
| + } |
| + } |
| + if (path == null) { |
| + for (SdkLibrary library in _librariesMap.sdkLibraries) { |
| + String libraryPath = library.path; |
| + int index = libraryPath.lastIndexOf('/'); |
| + if (index == -1) { |
| + continue; |
| + } |
| + String prefix = libraryPath.substring(0, index + 1); |
| + if (!srcPath.startsWith(prefix)) { |
| + continue; |
| + } |
| + var relPath = srcPath.substring(prefix.length); |
| + path = '$_DART_COLON_PREFIX${library.shortName}/$relPath'; |
| + break; |
| + } |
| + } |
| + |
| + if (path != null) { |
| + try { |
| + return new FileBasedSource(file, parseUriWithException(path)); |
| + } on URISyntaxException catch (exception, stackTrace) { |
| + AnalysisEngine.instance.logger.logInformation( |
| + "Failed to create URI: $path", |
| + new CaughtException(exception, stackTrace)); |
| + return null; |
| + } |
| + } |
| + return null; |
| + } |
| + |
| + @override |
| + SdkLibrary getSdkLibrary(String dartUri) => _librariesMap.getLibrary(dartUri); |
| + |
| + @override |
| + Source mapDartUri(String dartUri) { |
| + String libraryName; |
| + String relativePath; |
| + int index = dartUri.indexOf('/'); |
| + if (index >= 0) { |
| + libraryName = dartUri.substring(0, index); |
| + relativePath = dartUri.substring(index + 1); |
| + } else { |
| + libraryName = dartUri; |
| + relativePath = ""; |
| + } |
| + SdkLibrary library = getSdkLibrary(libraryName); |
| + if (library == null) { |
| + return null; |
| + } |
| + String srcPath; |
| + if (relativePath.isEmpty) { |
| + srcPath = library.path; |
| + } else { |
| + String libraryPath = library.path; |
| + int index = libraryPath.lastIndexOf('/'); |
| + if (index == -1) { |
| + return null; |
| + } |
| + String prefix = libraryPath.substring(0, index + 1); |
| + srcPath = '$prefix$relativePath'; |
| + } |
| + String filePath = srcPath.replaceAll('/', JavaFile.separator); |
| + try { |
| + JavaFile file = new JavaFile(filePath); |
| + return new FileBasedSource(file, parseUriWithException(dartUri)); |
| + } on URISyntaxException { |
| + return null; |
| + } |
| + } |
| +} |