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

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

Issue 2009303002: Embedder support refactoring (phase 1). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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
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/source/package_map_provider.dart' 11 import 'package:analyzer/source/package_map_provider.dart'
12 show PackageMapProvider; 12 show PackageMapProvider;
13 import 'package:analyzer/src/context/context.dart'; 13 import 'package:analyzer/src/context/context.dart';
14 import 'package:analyzer/src/generated/engine.dart'; 14 import 'package:analyzer/src/generated/engine.dart';
15 import 'package:analyzer/src/generated/java_core.dart'; 15 import 'package:analyzer/src/generated/java_core.dart';
16 import 'package:analyzer/src/generated/java_engine.dart'; 16 import 'package:analyzer/src/generated/java_engine.dart';
17 import 'package:analyzer/src/generated/java_io.dart' show JavaFile; 17 import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
18 import 'package:analyzer/src/generated/sdk.dart'; 18 import 'package:analyzer/src/generated/sdk.dart';
19 import 'package:analyzer/src/generated/source.dart'; 19 import 'package:analyzer/src/generated/source.dart';
20 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource; 20 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
21 import 'package:yaml/yaml.dart'; 21 import 'package:yaml/yaml.dart';
22 22
23 const String _DART_COLON_PREFIX = 'dart:'; 23 const String _DART_COLON_PREFIX = 'dart:';
24 const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs'; 24 const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs';
25 25
26 /// Check if this map defines embedded libraries. 26 /// Check if this map defines embedded libraries.
27 bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null; 27 bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null;
28 28
29 /// An SDK backed by URI mappings derived from an `_embedder.yaml` file.
29 class EmbedderSdk implements DartSdk { 30 class EmbedderSdk implements DartSdk {
30 // TODO(danrubel) Refactor this with DirectoryBasedDartSdk 31 /// The resolver associated with this SDK.
31
32 /// The resolver associated with this embedder sdk.
33 EmbedderUriResolver _resolver; 32 EmbedderUriResolver _resolver;
34 33
35 /// The [AnalysisContext] which is used for all of the sources in this sdk. 34 /// The [AnalysisContext] used for this SDK's sources.
36 InternalAnalysisContext _analysisContext; 35 InternalAnalysisContext _analysisContext;
37 36
38 /// The library map that is populated by visiting the AST structure parsed fro m
39 /// the contents of the libraries file.
40 final LibraryMap _librariesMap = new LibraryMap(); 37 final LibraryMap _librariesMap = new LibraryMap();
41 38
39 final Map<String, String> _urlMappings = new HashMap<String, String>();
40
41 /// Analysis options for this SDK.
42 AnalysisOptions analysisOptions;
43
44 EmbedderSdk([Map<Folder, YamlMap> embedderYamls]) {
45 embedderYamls?.forEach(_processEmbedderYaml);
46 _resolver = new EmbedderUriResolver(this);
47 }
48
42 @override 49 @override
43 AnalysisContext get context { 50 AnalysisContext get context {
44 if (_analysisContext == null) { 51 if (_analysisContext == null) {
45 _analysisContext = new SdkAnalysisContext(null); 52 _analysisContext = new SdkAnalysisContext(analysisOptions);
46 SourceFactory factory = new SourceFactory([_resolver]); 53 SourceFactory factory = new SourceFactory([_resolver]);
47 _analysisContext.sourceFactory = factory; 54 _analysisContext.sourceFactory = factory;
48 List<String> uris = this.uris; 55
49 ChangeSet changeSet = new ChangeSet(); 56 ChangeSet changeSet = new ChangeSet();
50 for (String uri in uris) { 57 for (String uri in uris) {
51 changeSet.addedSource(factory.forUri(uri)); 58 changeSet.addedSource(factory.forUri(uri));
52 } 59 }
53 _analysisContext.applyChanges(changeSet); 60 _analysisContext.applyChanges(changeSet);
54 } 61 }
55 return _analysisContext; 62 return _analysisContext;
56 } 63 }
57 64
58 @override 65 @override
59 List<SdkLibrary> get sdkLibraries => _librariesMap.sdkLibraries; 66 List<SdkLibrary> get sdkLibraries => _librariesMap.sdkLibraries;
60 67
61 // TODO(danrubel) Determine SDK version 68 // TODO(danrubel) Determine SDK version
62 @override 69 @override
63 String get sdkVersion => '0'; 70 String get sdkVersion => '0';
64 71
65 @override 72 @override
66 List<String> get uris => _librariesMap.uris; 73 List<String> get uris => _librariesMap.uris;
67 74
75 /// The url mappings for this SDK.
76 Map<String, String> get urlMappings => _urlMappings;
77
68 @override 78 @override
69 Source fromFileUri(Uri uri) { 79 Source fromFileUri(Uri uri) {
70 JavaFile file = new JavaFile.fromUri(uri); 80 JavaFile file = new JavaFile.fromUri(uri);
71 String filePath = file.getAbsolutePath(); 81 String filePath = file.getAbsolutePath();
72 82
73 String path; 83 String path;
74 for (SdkLibrary library in _librariesMap.sdkLibraries) { 84 for (SdkLibrary library in _librariesMap.sdkLibraries) {
75 String libraryPath = library.path.replaceAll('/', JavaFile.separator); 85 String libraryPath = library.path.replaceAll('/', JavaFile.separator);
76 if (filePath == libraryPath) { 86 if (filePath == libraryPath) {
77 path = '$_DART_COLON_PREFIX${library.shortName}'; 87 path = library.shortName;
78 break; 88 break;
79 } 89 }
80 } 90 }
81 if (path == null) { 91 if (path == null) {
82 for (SdkLibrary library in _librariesMap.sdkLibraries) { 92 for (SdkLibrary library in _librariesMap.sdkLibraries) {
83 String libraryPath = library.path.replaceAll('/', JavaFile.separator); 93 String libraryPath = library.path.replaceAll('/', JavaFile.separator);
84 int index = libraryPath.lastIndexOf(JavaFile.separator); 94 int index = libraryPath.lastIndexOf(JavaFile.separator);
85 if (index == -1) { 95 if (index == -1) {
86 continue; 96 continue;
87 } 97 }
88 String prefix = libraryPath.substring(0, index + 1); 98 String prefix = libraryPath.substring(0, index + 1);
89 if (!filePath.startsWith(prefix)) { 99 if (!filePath.startsWith(prefix)) {
90 continue; 100 continue;
91 } 101 }
92 var relPath = filePath 102 var relPath = filePath
93 .substring(prefix.length) 103 .substring(prefix.length)
94 .replaceAll(JavaFile.separator, '/'); 104 .replaceAll(JavaFile.separator, '/');
95 path = '$_DART_COLON_PREFIX${library.shortName}/$relPath'; 105 path = '${library.shortName}/$relPath';
96 break; 106 break;
97 } 107 }
98 } 108 }
99 109
100 if (path != null) { 110 if (path != null) {
101 try { 111 try {
102 return new FileBasedSource(file, parseUriWithException(path)); 112 return new FileBasedSource(file, parseUriWithException(path));
103 } on URISyntaxException catch (exception, stackTrace) { 113 } on URISyntaxException catch (exception, stackTrace) {
104 AnalysisEngine.instance.logger.logInformation( 114 AnalysisEngine.instance.logger.logInformation(
105 "Failed to create URI: $path", 115 "Failed to create URI: $path",
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 srcPath = '$prefix$relativePath'; 155 srcPath = '$prefix$relativePath';
146 } 156 }
147 String filePath = srcPath.replaceAll('/', JavaFile.separator); 157 String filePath = srcPath.replaceAll('/', JavaFile.separator);
148 try { 158 try {
149 JavaFile file = new JavaFile(filePath); 159 JavaFile file = new JavaFile(filePath);
150 return new FileBasedSource(file, parseUriWithException(dartUri)); 160 return new FileBasedSource(file, parseUriWithException(dartUri));
151 } on URISyntaxException { 161 } on URISyntaxException {
152 return null; 162 return null;
153 } 163 }
154 } 164 }
165
166 /// Install the mapping from [name] to [libDir]/[file].
167 void _processEmbeddedLibs(String name, String file, Folder libDir) {
168 if (!name.startsWith(_DART_COLON_PREFIX)) {
169 // SDK libraries must begin with 'dart:'.
170 return;
171 }
172 String libPath = libDir.canonicalizePath(file);
173 _urlMappings[name] = libPath;
174 SdkLibraryImpl library = new SdkLibraryImpl(name);
175 library.path = libPath;
176 _librariesMap.setLibrary(name, library);
177 }
178
179 /// Given the 'embedderYamls' from [EmbedderYamlLocator] check each one for th e
180 /// top level key 'embedded_libs'. Under the 'embedded_libs' key are key value
181 /// pairs. Each key is a 'dart:' library uri and each value is a path
182 /// (relative to the directory containing `_embedder.yaml`) to a dart script
183 /// for the given library. For example:
184 ///
185 /// embedded_libs:
186 /// 'dart:io': '../../sdk/io/io.dart'
187 ///
188 /// If a key doesn't begin with `dart:` it is ignored.
189 void _processEmbedderYaml(Folder libDir, YamlMap map) {
190 YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
191 if (embedded_libs is YamlMap) {
192 embedded_libs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
193 }
194 }
155 } 195 }
156 196
157 /// Given the 'embedderYamls' from [EmbedderYamlLocator] check each one for the 197 /// Given the 'embedderYamls' from [EmbedderYamlLocator] check each one for the
158 /// top level key 'embedded_libs'. Under the 'embedded_libs' key are key value 198 /// top level key 'embedded_libs'. Under the 'embedded_libs' key are key value
159 /// pairs. Each key is a 'dart:' library uri and each value is a path 199 /// pairs. Each key is a 'dart:' library uri and each value is a path
160 /// (relative to the directory containing `_embedder.yaml`) to a dart script 200 /// (relative to the directory containing `_embedder.yaml`) to a dart script
161 /// for the given library. For example: 201 /// for the given library. For example:
162 /// 202 ///
163 /// embedded_libs: 203 /// embedded_libs:
164 /// 'dart:io': '../../sdk/io/io.dart' 204 /// 'dart:io': '../../sdk/io/io.dart'
165 /// 205 ///
166 /// If a key doesn't begin with `dart:` it is ignored. 206 /// If a key doesn't begin with `dart:` it is ignored.
167 /// 207 ///
168 class EmbedderUriResolver extends DartUriResolver { 208 class EmbedderUriResolver implements DartUriResolver {
169 final Map<String, String> _urlMappings = <String, String>{}; 209 EmbedderSdk _embedderSdk;
210 DartUriResolver _dartUriResolver;
170 211
171 /// Construct a [EmbedderUriResolver] from a package map 212 /// Construct a [EmbedderUriResolver] from a package map
172 /// (see [PackageMapProvider]). 213 /// (see [PackageMapProvider]).
173 EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls) 214 EmbedderUriResolver(this._embedderSdk) {
174 : super(new EmbedderSdk()) { 215 _dartUriResolver = new DartUriResolver(_embedderSdk);
175 (dartSdk as EmbedderSdk)._resolver = this;
176 if (embedderYamls == null) {
177 return;
178 }
179 embedderYamls.forEach(_processEmbedderYaml);
180 } 216 }
181 217
218 @override
219 DartSdk get dartSdk => _embedderSdk;
220
182 /// Number of embedded libraries. 221 /// Number of embedded libraries.
183 int get length => _urlMappings.length; 222 int get length => _embedderSdk?.urlMappings?.length ?? 0;
223
224 @override
225 Source resolveAbsolute(Uri uri, [Uri actualUri]) =>
226 _dartUriResolver.resolveAbsolute(uri, actualUri);
184 227
185 @override 228 @override
186 Uri restoreAbsolute(Source source) { 229 Uri restoreAbsolute(Source source) {
187 String path = source.fullName; 230 String path = source.fullName;
188 if (path.length > 3 && path[1] == ':' && path[2] == '\\') { 231 if (path.length > 3 && path[1] == ':' && path[2] == '\\') {
189 path = '/${path[0]}:${path.substring(2).replaceAll('\\', '/')}'; 232 path = '/${path[0]}:${path.substring(2).replaceAll('\\', '/')}';
190 } 233 }
191 Source sdkSource = dartSdk.fromFileUri(Uri.parse('file://$path')); 234 Source sdkSource = dartSdk.fromFileUri(Uri.parse('file://$path'));
192 return sdkSource?.uri; 235 return sdkSource?.uri;
193 } 236 }
194
195 /// Install the mapping from [name] to [libDir]/[file].
196 void _processEmbeddedLibs(String name, String file, Folder libDir) {
197 if (!name.startsWith(_DART_COLON_PREFIX)) {
198 // SDK libraries must begin with 'dart:'.
199 // TODO(pquitslund): Notify developer that something is wrong with the
200 // _embedder.yaml file in libDir.
201 return;
202 }
203 String libPath = libDir.canonicalizePath(file);
204 _urlMappings[name] = libPath;
205 String shortName = name.substring(_DART_COLON_PREFIX.length);
206 SdkLibraryImpl library = new SdkLibraryImpl(shortName);
207 library.path = libPath;
208 (dartSdk as EmbedderSdk)._librariesMap.setLibrary(name, library);
209 }
210
211 void _processEmbedderYaml(Folder libDir, YamlMap map) {
212 YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
213 if (embedded_libs == null) {
214 return;
215 }
216 if (embedded_libs is YamlMap) {
217 embedded_libs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
218 }
219 }
220 } 237 }
221 238
222 /// Given a packageMap, check in each package's lib directory for the 239 /// Given a packageMap, check in each package's lib directory for the
223 /// existence of an `_embedder.yaml` file. If the file contains a top level 240 /// existence of an `_embedder.yaml` file. If the file contains a top level
224 /// YamlMap, it will be added to the [embedderYamls] map. 241 /// YamlMap, it will be added to the [embedderYamls] map.
225 class EmbedderYamlLocator { 242 class EmbedderYamlLocator {
226 static const String EMBEDDER_FILE_NAME = '_embedder.yaml'; 243 static const String EMBEDDER_FILE_NAME = '_embedder.yaml';
227 244
228 // Map from package's library directory to the parsed 245 /// Map from package's library directory to the parsed YamlMap.
229 // YamlMap.
230 final Map<Folder, YamlMap> embedderYamls = new HashMap<Folder, YamlMap>(); 246 final Map<Folder, YamlMap> embedderYamls = new HashMap<Folder, YamlMap>();
231 247
232 EmbedderYamlLocator(Map<String, List<Folder>> packageMap) { 248 EmbedderYamlLocator(Map<String, List<Folder>> packageMap) {
233 if (packageMap != null) { 249 if (packageMap != null) {
234 refresh(packageMap); 250 refresh(packageMap);
235 } 251 }
236 } 252 }
237 253
238 /// Programatically add an _embedder.yaml mapping. 254 /// Programatically add an _embedder.yaml mapping.
239 void addEmbedderYaml(Folder libDir, String embedderYaml) { 255 void addEmbedderYaml(Folder libDir, String embedderYaml) {
240 _processEmbedderYaml(libDir, embedderYaml); 256 _processEmbedderYaml(libDir, embedderYaml);
241 } 257 }
242 258
243 void refresh(Map<String, List<Folder>> packageMap) { 259 void refresh(Map<String, List<Folder>> packageMap) {
244 // Clear existing. 260 // Clear existing.
245 embedderYamls.clear(); 261 embedderYamls.clear();
246 if (packageMap == null) { 262 if (packageMap == null) {
247 return; 263 return;
248 } 264 }
249 packageMap.forEach(_processPackage); 265 packageMap.forEach(_processPackage);
250 } 266 }
251 267
252 /// Given the yaml for an embedder ([embedderYaml]) and a folder 268 /// Given the yaml for an embedder ([embedderYaml]) and a folder
253 /// ([libDir]), setup the uri mapping. 269 /// ([libDir]), setup the uri mapping.
254 void _processEmbedderYaml(Folder libDir, String embedderYaml) { 270 void _processEmbedderYaml(Folder libDir, String embedderYaml) {
255 YamlNode yaml; 271 YamlNode yaml;
256 try { 272 try {
257 yaml = loadYaml(embedderYaml); 273 yaml = loadYaml(embedderYaml);
258 } catch (_) { 274 } catch (_) {
259 // TODO(pquitslund): Notify developer that something is wrong with the
260 // _embedder.yaml file in libDir.
261 return;
262 }
263 if (yaml == null) {
264 // TODO(pquitslund): Notify developer that something is wrong with the
265 // _embedder.yaml file in libDir.
266 return; 275 return;
267 } 276 }
268 if (yaml is! YamlMap) { 277 if (yaml is! YamlMap) {
269 // TODO(pquitslund): Notify developer that something is wrong with the
270 // _embedder.yaml file in libDir.
271 return; 278 return;
272 } 279 }
273 embedderYamls[libDir] = yaml; 280 embedderYamls[libDir] = yaml;
274 } 281 }
275 282
276 /// Given a package [name] and a list of folders ([libDirs]), 283 /// Given a package [name] and a list of folders ([libDirs]),
277 /// add any found `_embedder.yaml` files. 284 /// add any found `_embedder.yaml` files.
278 void _processPackage(String name, List<Folder> libDirs) { 285 void _processPackage(String name, List<Folder> libDirs) {
279 for (Folder libDir in libDirs) { 286 for (Folder libDir in libDirs) {
280 String embedderYaml = _readEmbedderYaml(libDir); 287 String embedderYaml = _readEmbedderYaml(libDir);
281 if (embedderYaml != null) { 288 if (embedderYaml != null) {
282 _processEmbedderYaml(libDir, embedderYaml); 289 _processEmbedderYaml(libDir, embedderYaml);
283 } 290 }
284 } 291 }
285 } 292 }
286 293
287 /// Read the contents of [libDir]/[EMBEDDER_FILE_NAME] as a string. 294 /// Read the contents of [libDir]/[EMBEDDER_FILE_NAME] as a string.
288 /// Returns null if the file doesn't exist. 295 /// Returns null if the file doesn't exist.
289 String _readEmbedderYaml(Folder libDir) { 296 String _readEmbedderYaml(Folder libDir) {
290 File file = libDir.getChild(EMBEDDER_FILE_NAME); 297 File file = libDir.getChild(EMBEDDER_FILE_NAME);
291 try { 298 try {
292 return file.readAsStringSync(); 299 return file.readAsStringSync();
293 } on FileSystemException { 300 } on FileSystemException {
294 // File can't be read. 301 // File can't be read.
295 return null; 302 return null;
296 } 303 }
297 } 304 }
298 } 305 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698