OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 // This code was auto-generated, is not intended to be edited, and is subject to | |
6 // significant change. Please see the README file for more information. | |
7 | |
8 library engine.sdk.io; | |
9 | |
10 import 'dart:io'; | |
11 | |
12 import 'package:analyzer/src/context/context.dart' as newContext; | |
13 import 'package:analyzer/src/generated/java_engine.dart'; | |
14 | |
15 import 'ast.dart'; | |
16 import 'engine.dart'; | |
17 import 'error.dart'; | |
18 import 'java_core.dart'; | |
19 import 'java_engine_io.dart'; | |
20 import 'java_io.dart'; | |
21 import 'parser.dart'; | |
22 import 'scanner.dart'; | |
23 import 'sdk.dart'; | |
24 import 'source_io.dart'; | |
25 | |
26 /** | |
27 * A Dart SDK installed in a specified directory. Typical Dart SDK layout is | |
28 * something like... | |
29 * | |
30 * dart-sdk/ | |
31 * bin/ | |
32 * dart[.exe] <-- VM | |
33 * lib/ | |
34 * core/ | |
35 * core.dart | |
36 * ... other core library files ... | |
37 * ... other libraries ... | |
38 * util/ | |
39 * ... Dart utilities ... | |
40 * Chromium/ <-- Dartium typically exists in a sibling directory | |
41 */ | |
42 class DirectoryBasedDartSdk implements DartSdk { | |
43 /** | |
44 * The default SDK, or `null` if the default SDK either has not yet been | |
45 * created or cannot be created for some reason. | |
46 */ | |
47 static DirectoryBasedDartSdk _DEFAULT_SDK; | |
48 | |
49 /** | |
50 * The name of the directory within the SDK directory that contains | |
51 * executables. | |
52 */ | |
53 static String _BIN_DIRECTORY_NAME = "bin"; | |
54 | |
55 /** | |
56 * The name of the directory on non-Mac that contains dartium. | |
57 */ | |
58 static String _DARTIUM_DIRECTORY_NAME = "chromium"; | |
59 | |
60 /** | |
61 * The name of the dart2js executable on non-windows operating systems. | |
62 */ | |
63 static String _DART2JS_EXECUTABLE_NAME = "dart2js"; | |
64 | |
65 /** | |
66 * The name of the file containing the dart2js executable on Windows. | |
67 */ | |
68 static String _DART2JS_EXECUTABLE_NAME_WIN = "dart2js.bat"; | |
69 | |
70 /** | |
71 * The name of the file containing the Dartium executable on Linux. | |
72 */ | |
73 static String _DARTIUM_EXECUTABLE_NAME_LINUX = "chrome"; | |
74 | |
75 /** | |
76 * The name of the file containing the Dartium executable on Macintosh. | |
77 */ | |
78 static String _DARTIUM_EXECUTABLE_NAME_MAC = | |
79 "Chromium.app/Contents/MacOS/Chromium"; | |
80 | |
81 /** | |
82 * The name of the file containing the Dartium executable on Windows. | |
83 */ | |
84 static String _DARTIUM_EXECUTABLE_NAME_WIN = "Chrome.exe"; | |
85 | |
86 /** | |
87 * The name of the [System] property whose value is the path to the default | |
88 * Dart SDK directory. | |
89 */ | |
90 static String _DEFAULT_DIRECTORY_PROPERTY_NAME = "com.google.dart.sdk"; | |
91 | |
92 /** | |
93 * The name of the directory within the SDK directory that contains | |
94 * documentation for the libraries. | |
95 */ | |
96 static String _DOCS_DIRECTORY_NAME = "docs"; | |
97 | |
98 /** | |
99 * The suffix added to the name of a library to derive the name of the file | |
100 * containing the documentation for that library. | |
101 */ | |
102 static String _DOC_FILE_SUFFIX = "_api.json"; | |
103 | |
104 /** | |
105 * The name of the directory within the SDK directory that contains the | |
106 * sdk_library_metadata directory. | |
107 */ | |
108 static String _INTERNAL_DIR = "_internal"; | |
109 | |
110 /** | |
111 * The name of the sdk_library_metadata directory that contains the package | |
112 * holding the libraries.dart file. | |
113 */ | |
114 static String _SDK_LIBRARY_METADATA_DIR = "sdk_library_metadata"; | |
115 | |
116 /** | |
117 * The name of the directory within the sdk_library_metadata that contains | |
118 * libraries.dart. | |
119 */ | |
120 static String _SDK_LIBRARY_METADATA_LIB_DIR = "lib"; | |
121 | |
122 /** | |
123 * The name of the directory within the SDK directory that contains the | |
124 * libraries. | |
125 */ | |
126 static String _LIB_DIRECTORY_NAME = "lib"; | |
127 | |
128 /** | |
129 * The name of the libraries file. | |
130 */ | |
131 static String _LIBRARIES_FILE = "libraries.dart"; | |
132 | |
133 /** | |
134 * The name of the pub executable on windows. | |
135 */ | |
136 static String _PUB_EXECUTABLE_NAME_WIN = "pub.bat"; | |
137 | |
138 /** | |
139 * The name of the pub executable on non-windows operating systems. | |
140 */ | |
141 static String _PUB_EXECUTABLE_NAME = "pub"; | |
142 | |
143 /** | |
144 * The name of the file within the SDK directory that contains the version | |
145 * number of the SDK. | |
146 */ | |
147 static String _VERSION_FILE_NAME = "version"; | |
148 | |
149 /** | |
150 * The name of the file containing the VM executable on the Windows operating | |
151 * system. | |
152 */ | |
153 static String _VM_EXECUTABLE_NAME_WIN = "dart.exe"; | |
154 | |
155 /** | |
156 * The name of the file containing the VM executable on non-Windows operating | |
157 * systems. | |
158 */ | |
159 static String _VM_EXECUTABLE_NAME = "dart"; | |
160 | |
161 /** | |
162 * Return the default Dart SDK, or `null` if the directory containing the | |
163 * default SDK cannot be determined (or does not exist). | |
164 */ | |
165 static DirectoryBasedDartSdk get defaultSdk { | |
166 if (_DEFAULT_SDK == null) { | |
167 JavaFile sdkDirectory = defaultSdkDirectory; | |
168 if (sdkDirectory == null) { | |
169 return null; | |
170 } | |
171 _DEFAULT_SDK = new DirectoryBasedDartSdk(sdkDirectory); | |
172 } | |
173 return _DEFAULT_SDK; | |
174 } | |
175 | |
176 /** | |
177 * Return the default directory for the Dart SDK, or `null` if the directory | |
178 * cannot be determined (or does not exist). The default directory is provided | |
179 * by a system property named `com.google.dart.sdk`. | |
180 */ | |
181 static JavaFile get defaultSdkDirectory { | |
182 String sdkProperty = | |
183 JavaSystemIO.getProperty(_DEFAULT_DIRECTORY_PROPERTY_NAME); | |
184 if (sdkProperty == null) { | |
185 return null; | |
186 } | |
187 JavaFile sdkDirectory = new JavaFile(sdkProperty); | |
188 if (!sdkDirectory.exists()) { | |
189 return null; | |
190 } | |
191 return sdkDirectory; | |
192 } | |
193 | |
194 /** | |
195 * The [AnalysisContext] which is used for all of the sources in this sdk. | |
196 */ | |
197 InternalAnalysisContext _analysisContext; | |
198 | |
199 /** | |
200 * The directory containing the SDK. | |
201 */ | |
202 JavaFile _sdkDirectory; | |
203 | |
204 /** | |
205 * The revision number of this SDK, or `"0"` if the revision number cannot be | |
206 * discovered. | |
207 */ | |
208 String _sdkVersion; | |
209 | |
210 /** | |
211 * The file containing the dart2js executable. | |
212 */ | |
213 JavaFile _dart2jsExecutable; | |
214 | |
215 /** | |
216 * The file containing the Dartium executable. | |
217 */ | |
218 JavaFile _dartiumExecutable; | |
219 | |
220 /** | |
221 * The file containing the pub executable. | |
222 */ | |
223 JavaFile _pubExecutable; | |
224 | |
225 /** | |
226 * The file containing the VM executable. | |
227 */ | |
228 JavaFile _vmExecutable; | |
229 | |
230 /** | |
231 * A mapping from Dart library URI's to the library represented by that URI. | |
232 */ | |
233 LibraryMap _libraryMap; | |
234 | |
235 /** | |
236 * Initialize a newly created SDK to represent the Dart SDK installed in the | |
237 * [sdkDirectory]. The flag [useDart2jsPaths] is `true` if the dart2js path | |
238 * should be used when it is available | |
239 */ | |
240 DirectoryBasedDartSdk(JavaFile sdkDirectory, [bool useDart2jsPaths = false]) { | |
241 this._sdkDirectory = sdkDirectory.getAbsoluteFile(); | |
242 _libraryMap = initialLibraryMap(useDart2jsPaths); | |
243 } | |
244 | |
245 @override | |
246 AnalysisContext get context { | |
247 if (_analysisContext == null) { | |
248 if (AnalysisEngine.instance.useTaskModel) { | |
249 _analysisContext = new newContext.SdkAnalysisContext(); | |
250 } else { | |
251 _analysisContext = new SdkAnalysisContext(); | |
252 } | |
253 SourceFactory factory = new SourceFactory([new DartUriResolver(this)]); | |
254 _analysisContext.sourceFactory = factory; | |
255 List<String> uris = this.uris; | |
256 ChangeSet changeSet = new ChangeSet(); | |
257 for (String uri in uris) { | |
258 changeSet.addedSource(factory.forUri(uri)); | |
259 } | |
260 _analysisContext.applyChanges(changeSet); | |
261 } | |
262 return _analysisContext; | |
263 } | |
264 | |
265 /** | |
266 * Return the file containing the dart2js executable, or `null` if it does not | |
267 * exist. | |
268 */ | |
269 JavaFile get dart2JsExecutable { | |
270 if (_dart2jsExecutable == null) { | |
271 _dart2jsExecutable = _verifyExecutable(new JavaFile.relative( | |
272 new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), | |
273 OSUtilities.isWindows() | |
274 ? _DART2JS_EXECUTABLE_NAME_WIN | |
275 : _DART2JS_EXECUTABLE_NAME)); | |
276 } | |
277 return _dart2jsExecutable; | |
278 } | |
279 | |
280 /** | |
281 * Return the name of the file containing the Dartium executable. | |
282 */ | |
283 String get dartiumBinaryName { | |
284 if (OSUtilities.isWindows()) { | |
285 return _DARTIUM_EXECUTABLE_NAME_WIN; | |
286 } else if (OSUtilities.isMac()) { | |
287 return _DARTIUM_EXECUTABLE_NAME_MAC; | |
288 } else { | |
289 return _DARTIUM_EXECUTABLE_NAME_LINUX; | |
290 } | |
291 } | |
292 | |
293 /** | |
294 * Return the file containing the Dartium executable, or `null` if it does not | |
295 * exist. | |
296 */ | |
297 JavaFile get dartiumExecutable { | |
298 if (_dartiumExecutable == null) { | |
299 _dartiumExecutable = _verifyExecutable( | |
300 new JavaFile.relative(dartiumWorkingDirectory, dartiumBinaryName)); | |
301 } | |
302 return _dartiumExecutable; | |
303 } | |
304 | |
305 /** | |
306 * Return the directory where dartium can be found (the directory that will be | |
307 * the working directory is Dartium is invoked without changing the default). | |
308 */ | |
309 JavaFile get dartiumWorkingDirectory => | |
310 getDartiumWorkingDirectory(_sdkDirectory.getParentFile()); | |
311 | |
312 /** | |
313 * Return the directory containing the SDK. | |
314 */ | |
315 JavaFile get directory => _sdkDirectory; | |
316 | |
317 /** | |
318 * Return the directory containing documentation for the SDK. | |
319 */ | |
320 JavaFile get docDirectory => | |
321 new JavaFile.relative(_sdkDirectory, _DOCS_DIRECTORY_NAME); | |
322 | |
323 /** | |
324 * Return `true` if this SDK includes documentation. | |
325 */ | |
326 bool get hasDocumentation => docDirectory.exists(); | |
327 | |
328 /** | |
329 * Return `true` if the Dartium binary is available. | |
330 */ | |
331 bool get isDartiumInstalled => dartiumExecutable != null; | |
332 | |
333 /** | |
334 * Return the directory within the SDK directory that contains the libraries. | |
335 */ | |
336 JavaFile get libraryDirectory => | |
337 new JavaFile.relative(_sdkDirectory, _LIB_DIRECTORY_NAME); | |
338 | |
339 /** | |
340 * Return the file containing the Pub executable, or `null` if it does not exi
st. | |
341 */ | |
342 JavaFile get pubExecutable { | |
343 if (_pubExecutable == null) { | |
344 _pubExecutable = _verifyExecutable(new JavaFile.relative( | |
345 new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), OSUtilities | |
346 .isWindows() ? _PUB_EXECUTABLE_NAME_WIN : _PUB_EXECUTABLE_NAME)); | |
347 } | |
348 return _pubExecutable; | |
349 } | |
350 | |
351 @override | |
352 List<SdkLibrary> get sdkLibraries => _libraryMap.sdkLibraries; | |
353 | |
354 /** | |
355 * Return the revision number of this SDK, or `"0"` if the revision number | |
356 * cannot be discovered. | |
357 */ | |
358 @override | |
359 String get sdkVersion { | |
360 if (_sdkVersion == null) { | |
361 _sdkVersion = DartSdk.DEFAULT_VERSION; | |
362 JavaFile revisionFile = | |
363 new JavaFile.relative(_sdkDirectory, _VERSION_FILE_NAME); | |
364 try { | |
365 String revision = revisionFile.readAsStringSync(); | |
366 if (revision != null) { | |
367 _sdkVersion = revision.trim(); | |
368 } | |
369 } on FileSystemException { | |
370 // Fall through to return the default. | |
371 } | |
372 } | |
373 return _sdkVersion; | |
374 } | |
375 | |
376 @override | |
377 List<String> get uris => _libraryMap.uris; | |
378 | |
379 /** | |
380 * Return the name of the file containing the VM executable. | |
381 */ | |
382 String get vmBinaryName { | |
383 if (OSUtilities.isWindows()) { | |
384 return _VM_EXECUTABLE_NAME_WIN; | |
385 } else { | |
386 return _VM_EXECUTABLE_NAME; | |
387 } | |
388 } | |
389 | |
390 /** | |
391 * Return the file containing the VM executable, or `null` if it does not | |
392 * exist. | |
393 */ | |
394 JavaFile get vmExecutable { | |
395 if (_vmExecutable == null) { | |
396 _vmExecutable = _verifyExecutable(new JavaFile.relative( | |
397 new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), | |
398 vmBinaryName)); | |
399 } | |
400 return _vmExecutable; | |
401 } | |
402 | |
403 @override | |
404 Source fromFileUri(Uri uri) { | |
405 JavaFile file = new JavaFile.fromUri(uri); | |
406 String filePath = file.getAbsolutePath(); | |
407 String libPath = libraryDirectory.getAbsolutePath(); | |
408 if (!filePath.startsWith("$libPath${JavaFile.separator}")) { | |
409 return null; | |
410 } | |
411 filePath = filePath.substring(libPath.length + 1); | |
412 for (SdkLibrary library in _libraryMap.sdkLibraries) { | |
413 String libraryPath = library.path; | |
414 if (filePath.replaceAll('\\', '/') == libraryPath) { | |
415 String path = library.shortName; | |
416 try { | |
417 return new FileBasedSource(file, parseUriWithException(path)); | |
418 } on URISyntaxException catch (exception, stackTrace) { | |
419 AnalysisEngine.instance.logger.logInformation( | |
420 "Failed to create URI: $path", | |
421 new CaughtException(exception, stackTrace)); | |
422 return null; | |
423 } | |
424 } | |
425 libraryPath = new JavaFile(libraryPath).getParent(); | |
426 if (filePath.startsWith("$libraryPath${JavaFile.separator}")) { | |
427 String path = | |
428 "${library.shortName}/${filePath.substring(libraryPath.length + 1)}"
; | |
429 try { | |
430 return new FileBasedSource(file, parseUriWithException(path)); | |
431 } on URISyntaxException catch (exception, stackTrace) { | |
432 AnalysisEngine.instance.logger.logInformation( | |
433 "Failed to create URI: $path", | |
434 new CaughtException(exception, stackTrace)); | |
435 return null; | |
436 } | |
437 } | |
438 } | |
439 return null; | |
440 } | |
441 | |
442 /** | |
443 * Return the directory where dartium can be found (the directory that will be | |
444 * the working directory if Dartium is invoked without changing the default), | |
445 * assuming that the Editor was installed in the [installDir]. | |
446 */ | |
447 JavaFile getDartiumWorkingDirectory(JavaFile installDir) => | |
448 new JavaFile.relative(installDir, _DARTIUM_DIRECTORY_NAME); | |
449 | |
450 /** | |
451 * Return the auxiliary documentation file for the library with the given | |
452 * [libraryName], or `null` if no such file exists. | |
453 */ | |
454 JavaFile getDocFileFor(String libraryName) { | |
455 JavaFile dir = docDirectory; | |
456 if (!dir.exists()) { | |
457 return null; | |
458 } | |
459 JavaFile libDir = new JavaFile.relative(dir, libraryName); | |
460 JavaFile docFile = | |
461 new JavaFile.relative(libDir, "$libraryName$_DOC_FILE_SUFFIX"); | |
462 if (docFile.exists()) { | |
463 return docFile; | |
464 } | |
465 return null; | |
466 } | |
467 | |
468 @override | |
469 SdkLibrary getSdkLibrary(String dartUri) => _libraryMap.getLibrary(dartUri); | |
470 | |
471 /** | |
472 * Read all of the configuration files to initialize the library maps. The | |
473 * flag [useDart2jsPaths] is `true` if the dart2js path should be used when it | |
474 * is available. Return the initialized library map. | |
475 */ | |
476 LibraryMap initialLibraryMap(bool useDart2jsPaths) { | |
477 JavaFile librariesFile = new JavaFile.relative( | |
478 new JavaFile.relative( | |
479 new JavaFile.relative( | |
480 new JavaFile.relative(libraryDirectory, _INTERNAL_DIR), | |
481 _SDK_LIBRARY_METADATA_DIR), | |
482 _SDK_LIBRARY_METADATA_LIB_DIR), | |
483 _LIBRARIES_FILE); | |
484 try { | |
485 String contents = librariesFile.readAsStringSync(); | |
486 return new SdkLibrariesReader(useDart2jsPaths).readFromFile( | |
487 librariesFile, contents); | |
488 } catch (exception, stackTrace) { | |
489 AnalysisEngine.instance.logger.logError( | |
490 "Could not initialize the library map from ${librariesFile.getAbsolute
Path()}", | |
491 new CaughtException(exception, stackTrace)); | |
492 return new LibraryMap(); | |
493 } | |
494 } | |
495 | |
496 @override | |
497 Source mapDartUri(String dartUri) { | |
498 String libraryName; | |
499 String relativePath; | |
500 int index = dartUri.indexOf('/'); | |
501 if (index >= 0) { | |
502 libraryName = dartUri.substring(0, index); | |
503 relativePath = dartUri.substring(index + 1); | |
504 } else { | |
505 libraryName = dartUri; | |
506 relativePath = ""; | |
507 } | |
508 SdkLibrary library = getSdkLibrary(libraryName); | |
509 if (library == null) { | |
510 return null; | |
511 } | |
512 try { | |
513 JavaFile file = new JavaFile.relative(libraryDirectory, library.path); | |
514 if (!relativePath.isEmpty) { | |
515 file = file.getParentFile(); | |
516 file = new JavaFile.relative(file, relativePath); | |
517 } | |
518 return new FileBasedSource(file, parseUriWithException(dartUri)); | |
519 } on URISyntaxException { | |
520 return null; | |
521 } | |
522 } | |
523 | |
524 /** | |
525 * Return the given [file] if it exists and is executable, or `null` if it | |
526 * does not exist or is not executable. | |
527 */ | |
528 JavaFile _verifyExecutable(JavaFile file) => | |
529 file.isExecutable() ? file : null; | |
530 } | |
531 | |
532 /** | |
533 * An object used to read and parse the libraries file | |
534 * (dart-sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart) for informat
ion | |
535 * about the libraries in an SDK. The library information is represented as a | |
536 * Dart file containing a single top-level variable whose value is a const map. | |
537 * The keys of the map are the names of libraries defined in the SDK and the | |
538 * values in the map are info objects defining the library. For example, a | |
539 * subset of a typical SDK might have a libraries file that looks like the | |
540 * following: | |
541 * | |
542 * final Map<String, LibraryInfo> LIBRARIES = const <LibraryInfo> { | |
543 * // Used by VM applications | |
544 * "builtin" : const LibraryInfo( | |
545 * "builtin/builtin_runtime.dart", | |
546 * category: "Server", | |
547 * platforms: VM_PLATFORM), | |
548 * | |
549 * "compiler" : const LibraryInfo( | |
550 * "compiler/compiler.dart", | |
551 * category: "Tools", | |
552 * platforms: 0), | |
553 * }; | |
554 */ | |
555 class SdkLibrariesReader { | |
556 /** | |
557 * A flag indicating whether the dart2js path should be used when it is | |
558 * available. | |
559 */ | |
560 final bool _useDart2jsPaths; | |
561 | |
562 /** | |
563 * Initialize a newly created library reader to use the dart2js path if | |
564 * [_useDart2jsPaths] is `true`. | |
565 */ | |
566 SdkLibrariesReader(this._useDart2jsPaths); | |
567 | |
568 /** | |
569 * Return the library map read from the given [file], given that the content | |
570 * of the file is already known to be [libraryFileContents]. | |
571 */ | |
572 LibraryMap readFromFile(JavaFile file, String libraryFileContents) => | |
573 readFromSource(new FileBasedSource(file), libraryFileContents); | |
574 | |
575 /** | |
576 * Return the library map read from the given [source], given that the content | |
577 * of the file is already known to be [libraryFileContents]. | |
578 */ | |
579 LibraryMap readFromSource(Source source, String libraryFileContents) { | |
580 BooleanErrorListener errorListener = new BooleanErrorListener(); | |
581 Scanner scanner = new Scanner( | |
582 source, new CharSequenceReader(libraryFileContents), errorListener); | |
583 Parser parser = new Parser(source, errorListener); | |
584 CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize()); | |
585 SdkLibrariesReader_LibraryBuilder libraryBuilder = | |
586 new SdkLibrariesReader_LibraryBuilder(_useDart2jsPaths); | |
587 // If any syntactic errors were found then don't try to visit the AST | |
588 // structure. | |
589 if (!errorListener.errorReported) { | |
590 unit.accept(libraryBuilder); | |
591 } | |
592 return libraryBuilder.librariesMap; | |
593 } | |
594 } | |
OLD | NEW |