OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 fasta.uri_translator_impl; | 5 library fasta.uri_translator_impl; |
6 | 6 |
7 import 'dart:async' show Future; | 7 import 'package:front_end/src/base/libraries_spec.dart' |
8 import 'dart:convert' show JSON; | 8 show TargetLibrariesSpecification; |
9 | |
10 import 'package:front_end/file_system.dart' | |
11 show FileSystem, FileSystemException; | |
12 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext; | 9 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext; |
13 import 'package:front_end/src/fasta/fasta_codes.dart'; | 10 import 'package:front_end/src/fasta/fasta_codes.dart'; |
14 import 'package:front_end/src/fasta/severity.dart' show Severity; | 11 import 'package:front_end/src/fasta/severity.dart' show Severity; |
15 import 'package:front_end/src/fasta/uri_translator.dart'; | 12 import 'package:front_end/src/fasta/uri_translator.dart'; |
16 import 'package:package_config/packages_file.dart' as packages_file show parse; | |
17 import 'package:package_config/packages.dart' show Packages; | 13 import 'package:package_config/packages.dart' show Packages; |
18 import 'package:package_config/src/packages_impl.dart' show MapPackages; | |
19 | |
20 import 'deprecated_problems.dart' show deprecated_inputError; | |
21 | |
22 /// Read the JSON file with defined SDK libraries from the given [uri] in the | |
23 /// [fileSystem] and return the mapping from parsed Dart library names (e.g. | |
24 /// `math`) to file URIs. | |
25 Future<Map<String, Uri>> computeDartLibraries( | |
26 FileSystem fileSystem, Uri uri) async { | |
27 if (uri == null) return const <String, Uri>{}; | |
28 Map<String, String> libraries = JSON | |
29 .decode(await fileSystem.entityForUri(uri).readAsString())["libraries"]; | |
30 Map<String, Uri> result = <String, Uri>{}; | |
31 libraries.forEach((String name, String path) { | |
32 result[name] = uri.resolveUri(new Uri.file(path)); | |
33 }); | |
34 return result; | |
35 } | |
36 | |
37 Future<Map<String, List<Uri>>> computeDartPatches( | |
38 FileSystem fileSystem, Uri uri) async { | |
39 // TODO(ahe): Read patch information. | |
40 return const <String, List<Uri>>{}; | |
41 } | |
42 | 14 |
43 /// Implementation of [UriTranslator] for absolute `dart` and `package` URIs. | 15 /// Implementation of [UriTranslator] for absolute `dart` and `package` URIs. |
44 class UriTranslatorImpl implements UriTranslator { | 16 class UriTranslatorImpl implements UriTranslator { |
45 /// Mapping from Dart library names (e.g. `math`) to file URIs. | 17 /// Library information for platform libraries. |
46 final Map<String, Uri> dartLibraries; | 18 final TargetLibrariesSpecification dartLibraries; |
47 | |
48 // TODO(ahe): We probably want this to be `Map<String, Uri>`, that is, just | |
49 // one patch library (with parts). | |
50 /// Mapping from Dart library names to the file URIs of patches to apply. | |
51 final Map<String, List<Uri>> dartPatches; | |
52 | 19 |
53 /// Mapping from package names (e.g. `angular`) to the file URIs. | 20 /// Mapping from package names (e.g. `angular`) to the file URIs. |
54 final Packages packages; | 21 final Packages packages; |
55 | 22 |
56 UriTranslatorImpl(this.dartLibraries, this.dartPatches, this.packages); | 23 UriTranslatorImpl(this.dartLibraries, this.packages); |
57 | 24 |
58 @override | 25 @override |
59 List<Uri> getDartPatches(String libraryName) => dartPatches[libraryName]; | 26 List<Uri> getDartPatches(String libraryName) => |
| 27 dartLibraries.libraryInfoFor(libraryName)?.patches; |
60 | 28 |
61 @override | 29 @override |
62 bool isPlatformImplementation(Uri uri) { | 30 bool isPlatformImplementation(Uri uri) { |
63 if (uri.scheme != "dart") return false; | 31 if (uri.scheme != "dart") return false; |
64 String path = uri.path; | 32 String path = uri.path; |
65 return dartLibraries[path] == null || path.startsWith("_"); | 33 return dartLibraries.libraryInfoFor(path) == null || path.startsWith("_"); |
66 } | 34 } |
67 | 35 |
68 @override | 36 @override |
69 // TODO(sigmund, ahe): consider expanding this API to include an error | 37 // TODO(sigmund, ahe): consider expanding this API to include an error |
70 // callback, so we can provide an error location when one is available. For | 38 // callback, so we can provide an error location when one is available. For |
71 // example, if the error occurs in an `import`. | 39 // example, if the error occurs in an `import`. |
72 Uri translate(Uri uri) { | 40 Uri translate(Uri uri) { |
73 if (uri.scheme == "dart") return _translateDartUri(uri); | 41 if (uri.scheme == "dart") return _translateDartUri(uri); |
74 if (uri.scheme == "package") return _translatePackageUri(uri); | 42 if (uri.scheme == "package") return _translatePackageUri(uri); |
75 return null; | 43 return null; |
76 } | 44 } |
77 | 45 |
78 /// Return the file URI that corresponds to the given `dart` URI, or `null` | 46 /// Return the file URI that corresponds to the given `dart` URI, or `null` |
79 /// if there is no corresponding Dart library registered. | 47 /// if there is no corresponding Dart library registered. |
80 Uri _translateDartUri(Uri uri) { | 48 Uri _translateDartUri(Uri uri) { |
81 if (!uri.isScheme('dart')) return null; | 49 if (!uri.isScheme('dart')) return null; |
82 String path = uri.path; | 50 String path = uri.path; |
83 | 51 |
84 int index = path.indexOf('/'); | 52 int index = path.indexOf('/'); |
85 if (index == -1) return dartLibraries[path]; | 53 if (index == -1) return dartLibraries.libraryInfoFor(path)?.uri; |
86 | 54 |
87 String libraryName = path.substring(0, index); | 55 String libraryName = path.substring(0, index); |
88 String relativePath = path.substring(index + 1); | 56 String relativePath = path.substring(index + 1); |
89 Uri libraryFileUri = dartLibraries[libraryName]; | 57 Uri libraryFileUri = dartLibraries.libraryInfoFor(libraryName).uri; |
90 return libraryFileUri?.resolve(relativePath); | 58 return libraryFileUri?.resolve(relativePath); |
91 } | 59 } |
92 | 60 |
93 /// Return the file URI that corresponds to the given `package` URI, or | 61 /// Return the file URI that corresponds to the given `package` URI, or |
94 /// `null` if the `package` [uri] format is invalid, or there is no | 62 /// `null` if the `package` [uri] format is invalid, or there is no |
95 /// corresponding package registered. | 63 /// corresponding package registered. |
96 Uri _translatePackageUri(Uri uri) { | 64 Uri _translatePackageUri(Uri uri) { |
97 try { | 65 try { |
98 // TODO(sigmund): once we remove the `parse` API, we can ensure that | 66 // TODO(sigmund): once we remove the `parse` API, we can ensure that |
99 // packages will never be null and get rid of `?` below. | 67 // packages will never be null and get rid of `?` below. |
100 return packages?.resolve(uri, notFound: _packageUriNotFound); | 68 return packages?.resolve(uri, notFound: _packageUriNotFound); |
101 } on ArgumentError catch (e) { | 69 } on ArgumentError catch (e) { |
102 // TODO(sigmund): catch a more precise error when | 70 // TODO(sigmund): catch a more precise error when |
103 // https://github.com/dart-lang/package_config/issues/40 is fixed. | 71 // https://github.com/dart-lang/package_config/issues/40 is fixed. |
104 CompilerContext.current.reportWithoutLocation( | 72 CompilerContext.current.reportWithoutLocation( |
105 templateInvalidPackageUri.withArguments(uri, '$e'), Severity.error); | 73 templateInvalidPackageUri.withArguments(uri, '$e'), Severity.error); |
106 return null; | 74 return null; |
107 } | 75 } |
108 } | 76 } |
109 | 77 |
110 static Uri _packageUriNotFound(Uri uri) { | 78 static Uri _packageUriNotFound(Uri uri) { |
111 String name = uri.pathSegments.first; | 79 String name = uri.pathSegments.first; |
112 CompilerContext.current.reportWithoutLocation( | 80 CompilerContext.current.reportWithoutLocation( |
113 templatePackageNotFound.withArguments(name, uri), Severity.error); | 81 templatePackageNotFound.withArguments(name, uri), Severity.error); |
114 // TODO(sigmund, ahe): ensure we only report an error once, | 82 // TODO(sigmund, ahe): ensure we only report an error once, |
115 // this null result will likely cause another error further down in the | 83 // this null result will likely cause another error further down in the |
116 // compiler. | 84 // compiler. |
117 return null; | 85 return null; |
118 } | 86 } |
119 | |
120 static Future<UriTranslator> parse(FileSystem fileSystem, Uri sdk, | |
121 {Uri packages}) async { | |
122 Uri librariesJson = sdk?.resolve("lib/libraries.json"); | |
123 | |
124 // TODO(ahe): Provide a value for this file. | |
125 Uri patches = null; | |
126 | |
127 packages ??= Uri.base.resolve(".packages"); | |
128 | |
129 List<int> bytes; | |
130 try { | |
131 bytes = await fileSystem.entityForUri(packages).readAsBytes(); | |
132 } on FileSystemException catch (e) { | |
133 deprecated_inputError(packages, -1, e.message); | |
134 } | |
135 | |
136 Packages parsedPackages; | |
137 try { | |
138 parsedPackages = new MapPackages(packages_file.parse(bytes, packages)); | |
139 } on FormatException catch (e) { | |
140 return deprecated_inputError(packages, e.offset, e.message); | |
141 } | |
142 | |
143 var dartLibraries = await computeDartLibraries(fileSystem, librariesJson); | |
144 return new UriTranslatorImpl(dartLibraries, | |
145 await computeDartPatches(fileSystem, patches), parsedPackages); | |
146 } | |
147 } | 87 } |
OLD | NEW |