Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: pkg/analyzer/lib/source/embedder.dart

Issue 1584663006: Add EmbedderSdk to EmbedderUriResolver (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/source/embedder_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.source.embedder; 5 library analyzer.source.embedder;
6 6
7 import 'dart:collection' show HashMap; 7 import 'dart:collection' show HashMap;
8 import 'dart:core' hide Resource; 8 import 'dart:core' hide Resource;
9 9
10 import 'package:analyzer/file_system/file_system.dart'; 10 import 'package:analyzer/file_system/file_system.dart';
11 import 'package:analyzer/src/context/context.dart';
12 import 'package:analyzer/src/generated/engine.dart';
13 import 'package:analyzer/src/generated/java_core.dart';
14 import 'package:analyzer/src/generated/java_engine.dart';
11 import 'package:analyzer/src/generated/java_io.dart' show JavaFile; 15 import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
16 import 'package:analyzer/src/generated/sdk.dart';
12 import 'package:analyzer/src/generated/source.dart'; 17 import 'package:analyzer/src/generated/source.dart';
13 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource; 18 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
14 import 'package:path/path.dart' as pathos; 19 import 'package:path/path.dart' as pathos;
15 import 'package:yaml/yaml.dart'; 20 import 'package:yaml/yaml.dart';
16 21
22 const String _DART_COLON_PREFIX = 'dart:';
Brian Wilkerson 2016/01/14 16:47:17 nit: Personally, I dislike top-level declarations
23
17 /// Given a packageMap, check in each package's lib directory for the 24 /// Given a packageMap, check in each package's lib directory for the
18 /// existence of an `_embedder.yaml` file. If the file contains a top level 25 /// existence of an `_embedder.yaml` file. If the file contains a top level
19 /// YamlMap, it will be added to the [embedderYamls] map. 26 /// YamlMap, it will be added to the [embedderYamls] map.
20 class EmbedderYamlLocator { 27 class EmbedderYamlLocator {
21 static const String EMBEDDER_FILE_NAME = '_embedder.yaml'; 28 static const String EMBEDDER_FILE_NAME = '_embedder.yaml';
22 29
23 // Map from package's library directory to the parsed 30 // Map from package's library directory to the parsed
24 // YamlMap. 31 // YamlMap.
25 final Map<Folder, YamlMap> embedderYamls = new HashMap<Folder, YamlMap>(); 32 final Map<Folder, YamlMap> embedderYamls = new HashMap<Folder, YamlMap>();
26 33
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 return; 79 return;
73 } 80 }
74 if (yaml is! YamlMap) { 81 if (yaml is! YamlMap) {
75 // TODO(pquitslund): Notify developer that something is wrong with the 82 // TODO(pquitslund): Notify developer that something is wrong with the
76 // _embedder.yaml file in libDir. 83 // _embedder.yaml file in libDir.
77 return; 84 return;
78 } 85 }
79 embedderYamls[libDir] = yaml; 86 embedderYamls[libDir] = yaml;
80 } 87 }
81 88
82
83 /// Read the contents of [libDir]/[EMBEDDER_FILE_NAME] as a string. 89 /// Read the contents of [libDir]/[EMBEDDER_FILE_NAME] as a string.
84 /// Returns null if the file doesn't exist. 90 /// Returns null if the file doesn't exist.
85 String _readEmbedderYaml(Folder libDir) { 91 String _readEmbedderYaml(Folder libDir) {
86 File file = libDir.getChild(EMBEDDER_FILE_NAME); 92 File file = libDir.getChild(EMBEDDER_FILE_NAME);
87 try { 93 try {
88 return file.readAsStringSync(); 94 return file.readAsStringSync();
89 } on FileSystemException { 95 } on FileSystemException {
90 // File can't be read. 96 // File can't be read.
91 return null; 97 return null;
92 } 98 }
93 } 99 }
94 } 100 }
95 101
96 /// Given the [embedderYamls] from [EmbedderYamlLocator] check each one for the 102 /// Given the [embedderYamls] from [EmbedderYamlLocator] check each one for the
97 /// top level key 'embedder_libs'. Under the 'embedder_libs' key are key value 103 /// top level key 'embedder_libs'. Under the 'embedder_libs' key are key value
98 /// pairs. Each key is a 'dart:' library uri and each value is a path 104 /// pairs. Each key is a 'dart:' library uri and each value is a path
99 /// (relative to the directory containing `_embedder.yaml`) to a dart script 105 /// (relative to the directory containing `_embedder.yaml`) to a dart script
100 /// for the given library. For example: 106 /// for the given library. For example:
101 /// 107 ///
102 /// embedder_libs: 108 /// embedder_libs:
103 /// 'dart:io': '../../sdk/io/io.dart' 109 /// 'dart:io': '../../sdk/io/io.dart'
104 /// 110 ///
105 /// If a key doesn't begin with `dart:` it is ignored. 111 /// If a key doesn't begin with `dart:` it is ignored.
106 /// 112 ///
107 class EmbedderUriResolver extends UriResolver { 113 class EmbedderUriResolver extends DartUriResolver {
108 static const String DART_COLON_PREFIX = 'dart:';
109
110 final Map<String, String> _urlMappings = <String, String>{}; 114 final Map<String, String> _urlMappings = <String, String>{};
111 115
112 /// Construct a [EmbedderUriResolver] from a package map 116 /// Construct a [EmbedderUriResolver] from a package map
113 /// (see [PackageMapProvider]). 117 /// (see [PackageMapProvider]).
114 EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls) { 118 EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls)
119 : super(new _EmbedderSdk()) {
120 (dartSdk as _EmbedderSdk)._resolver = this;
115 if (embedderYamls == null) { 121 if (embedderYamls == null) {
116 return; 122 return;
117 } 123 }
118 embedderYamls.forEach(_processEmbedderYaml); 124 embedderYamls.forEach(_processEmbedderYaml);
119 } 125 }
120 126
121 void _processEmbedderYaml(Folder libDir, YamlMap map) { 127 void _processEmbedderYaml(Folder libDir, YamlMap map) {
122 YamlNode embedder_libs = map['embedder_libs']; 128 YamlNode embedder_libs = map['embedder_libs'];
123 if (embedder_libs == null) { 129 if (embedder_libs == null) {
124 return; 130 return;
125 } 131 }
126 if (embedder_libs is! YamlMap) { 132 if (embedder_libs is! YamlMap) {
127 return; 133 return;
128 } 134 }
129 (embedder_libs as YamlMap).forEach((k, v) => 135 (embedder_libs as YamlMap)
130 _processEmbedderLibs(k, v, libDir)); 136 .forEach((k, v) => _processEmbedderLibs(k, v, libDir));
131 } 137 }
132 138
133 /// Install the mapping from [name] to [libDir]/[file]. 139 /// Install the mapping from [name] to [libDir]/[file].
134 void _processEmbedderLibs(String name, String file, Folder libDir) { 140 void _processEmbedderLibs(String name, String file, Folder libDir) {
135 if (!name.startsWith(DART_COLON_PREFIX)) { 141 if (!name.startsWith(_DART_COLON_PREFIX)) {
136 // SDK libraries must begin with 'dart:'. 142 // SDK libraries must begin with 'dart:'.
137 // TODO(pquitslund): Notify developer that something is wrong with the 143 // TODO(pquitslund): Notify developer that something is wrong with the
138 // _embedder.yaml file in libDir. 144 // _embedder.yaml file in libDir.
139 return; 145 return;
140 } 146 }
141 String key = name; 147 String key = name;
142 String value = libDir.canonicalizePath(file); 148 String value = libDir.canonicalizePath(file);
143 _urlMappings[key] = value; 149 _urlMappings[key] = value;
150 String shortName = name.substring(_DART_COLON_PREFIX.length);
151 SdkLibraryImpl library = new SdkLibraryImpl(shortName);
152 library.path = value;
153 (dartSdk as _EmbedderSdk)._librariesMap.setLibrary(name, library);
144 } 154 }
145 155
146 /// Number of embedder libraries. 156 /// Number of embedder libraries.
147 int get length => _urlMappings.length; 157 int get length => _urlMappings.length;
148 158
149 /// Return the path mapping for [libName] or null if there is none. 159 /// Return the path mapping for [libName] or null if there is none.
150 String operator [](String libName) => _urlMappings[libName]; 160 String operator [](String libName) => _urlMappings[libName];
151 161
152 @override 162 @override
153 Source resolveAbsolute(Uri importUri, [Uri actualUri]) { 163 Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 /// Resolve a 'part' statement inside an sdk extension. 234 /// Resolve a 'part' statement inside an sdk extension.
225 Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) { 235 Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
226 // Library part. 236 // Library part.
227 String directory = pathos.dirname(libraryEntry.path); 237 String directory = pathos.dirname(libraryEntry.path);
228 Uri partUri = new Uri.file(pathos.join(directory, partPath)); 238 Uri partUri = new Uri.file(pathos.join(directory, partPath));
229 assert(partUri.isAbsolute); 239 assert(partUri.isAbsolute);
230 JavaFile javaFile = new JavaFile.fromUri(partUri); 240 JavaFile javaFile = new JavaFile.fromUri(partUri);
231 return new FileBasedSource(javaFile, importUri); 241 return new FileBasedSource(javaFile, importUri);
232 } 242 }
233 } 243 }
244
245 class _EmbedderSdk implements DartSdk {
246 // TODO(danrubel) Refactor this with DirectoryBasedDartSdk
247
248 /// The resolver associated with this embedder sdk.
249 EmbedderUriResolver _resolver;
250
251 /// The [AnalysisContext] which is used for all of the sources in this sdk.
252 InternalAnalysisContext _analysisContext;
253
254 /// The library map that is populated by visiting the AST structure parsed fro m
255 /// the contents of the libraries file.
256 final LibraryMap _librariesMap = new LibraryMap();
257
258 @override
259 AnalysisContext get context {
260 if (_analysisContext == null) {
261 _analysisContext = new SdkAnalysisContext();
262 SourceFactory factory = new SourceFactory([_resolver]);
263 _analysisContext.sourceFactory = factory;
264 List<String> uris = this.uris;
265 ChangeSet changeSet = new ChangeSet();
266 for (String uri in uris) {
267 changeSet.addedSource(factory.forUri(uri));
268 }
269 _analysisContext.applyChanges(changeSet);
270 }
271 return _analysisContext;
272 }
273
274 @override
275 List<SdkLibrary> get sdkLibraries => _librariesMap.sdkLibraries;
276
277 // TODO(danrubel) Determine SDK version
278 @override
279 String get sdkVersion => '0';
280
281 @override
282 List<String> get uris => _librariesMap.uris;
283
284 @override
285 Source fromFileUri(Uri uri) {
286 JavaFile file = new JavaFile.fromUri(uri);
287 String filePath = file.getAbsolutePath();
288 String srcPath = filePath.replaceAll('\\', '/');
289
290 String path;
291 for (SdkLibrary library in _librariesMap.sdkLibraries) {
292 String libraryPath = library.path;
293 if (srcPath == libraryPath) {
294 path = '$_DART_COLON_PREFIX${library.shortName}';
295 break;
296 }
297 }
298 if (path == null) {
299 for (SdkLibrary library in _librariesMap.sdkLibraries) {
300 String libraryPath = library.path;
301 int index = libraryPath.lastIndexOf('/');
302 if (index == -1) {
303 continue;
304 }
305 String prefix = libraryPath.substring(0, index + 1);
306 if (!srcPath.startsWith(prefix)) {
307 continue;
308 }
309 var relPath = srcPath.substring(prefix.length);
310 path = '$_DART_COLON_PREFIX${library.shortName}/$relPath';
311 break;
312 }
313 }
314
315 if (path != null) {
316 try {
317 return new FileBasedSource(file, parseUriWithException(path));
318 } on URISyntaxException catch (exception, stackTrace) {
319 AnalysisEngine.instance.logger.logInformation(
320 "Failed to create URI: $path",
321 new CaughtException(exception, stackTrace));
322 return null;
323 }
324 }
325 return null;
326 }
327
328 @override
329 SdkLibrary getSdkLibrary(String dartUri) => _librariesMap.getLibrary(dartUri);
330
331 @override
332 Source mapDartUri(String dartUri) {
333 String libraryName;
334 String relativePath;
335 int index = dartUri.indexOf('/');
336 if (index >= 0) {
337 libraryName = dartUri.substring(0, index);
338 relativePath = dartUri.substring(index + 1);
339 } else {
340 libraryName = dartUri;
341 relativePath = "";
342 }
343 SdkLibrary library = getSdkLibrary(libraryName);
344 if (library == null) {
345 return null;
346 }
347 String srcPath;
348 if (relativePath.isEmpty) {
349 srcPath = library.path;
350 } else {
351 String libraryPath = library.path;
352 int index = libraryPath.lastIndexOf('/');
353 if (index == -1) {
354 return null;
355 }
356 String prefix = libraryPath.substring(0, index + 1);
357 srcPath = '$prefix$relativePath';
358 }
359 String filePath = srcPath.replaceAll('/', JavaFile.separator);
360 try {
361 JavaFile file = new JavaFile(filePath);
362 return new FileBasedSource(file, parseUriWithException(dartUri));
363 } on URISyntaxException {
364 return null;
365 }
366 }
367 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/source/embedder_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698