OLD | NEW |
---|---|
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:typed_data'; | 6 import 'dart:typed_data'; |
7 | 7 |
8 import 'package:crypto/crypto.dart'; | 8 import 'package:crypto/crypto.dart'; |
9 import 'package:front_end/file_system.dart'; | 9 import 'package:front_end/file_system.dart'; |
10 import 'package:front_end/src/dependency_walker.dart' as graph; | 10 import 'package:front_end/src/dependency_walker.dart' as graph; |
(...skipping 17 matching lines...) Expand all Loading... | |
28 /// The absolute URI of the file. | 28 /// The absolute URI of the file. |
29 final Uri uri; | 29 final Uri uri; |
30 | 30 |
31 /// The resolved URI of the file in the file system. | 31 /// The resolved URI of the file in the file system. |
32 final Uri fileUri; | 32 final Uri fileUri; |
33 | 33 |
34 bool _exists; | 34 bool _exists; |
35 List<int> _content; | 35 List<int> _content; |
36 List<int> _contentHash; | 36 List<int> _contentHash; |
37 | 37 |
38 List<NamespaceExport> _exports; | |
38 List<FileState> _importedLibraries; | 39 List<FileState> _importedLibraries; |
39 List<FileState> _exportedLibraries; | 40 List<FileState> _exportedLibraries; |
40 List<FileState> _partFiles; | 41 List<FileState> _partFiles; |
41 | 42 |
42 Set<FileState> _directReferencedFiles = new Set<FileState>(); | 43 Set<FileState> _directReferencedFiles = new Set<FileState>(); |
43 List<FileState> _directReferencedLibraries = <FileState>[]; | 44 List<FileState> _directReferencedLibraries = <FileState>[]; |
44 | 45 |
45 FileState._(this._fsState, this.uri, this.fileUri); | 46 FileState._(this._fsState, this.uri, this.fileUri); |
46 | 47 |
47 /// The content of the file. | 48 /// The content of the file. |
48 List<int> get content => _content; | 49 List<int> get content => _content; |
49 | 50 |
50 /** | 51 /** |
51 * The MD5 hash of the [content]. | 52 * The MD5 hash of the [content]. |
52 */ | 53 */ |
53 List<int> get contentHash => _contentHash; | 54 List<int> get contentHash => _contentHash; |
54 | 55 |
55 /// Libraries that this library file directly imports or exports. | 56 /// Libraries that this library file directly imports or exports. |
56 List<FileState> get directReferencedLibraries => _directReferencedLibraries; | 57 List<FileState> get directReferencedLibraries => _directReferencedLibraries; |
57 | 58 |
58 /// Whether the file exists. | 59 /// Whether the file exists. |
59 bool get exists => _exists; | 60 bool get exists => _exists; |
60 | 61 |
61 /// The list of the libraries exported by this library. | 62 /// The list of the libraries exported by this library. |
62 List<FileState> get exportedLibraries => _exportedLibraries; | 63 List<FileState> get exportedLibraries => _exportedLibraries; |
63 | 64 |
65 /// The list of the exported files with combinators. | |
66 List<NamespaceExport> get exports => _exports; | |
67 | |
64 @override | 68 @override |
65 int get hashCode => uri.hashCode; | 69 int get hashCode => uri.hashCode; |
66 | 70 |
67 /// The list of the libraries imported by this library. | 71 /// The list of the libraries imported by this library. |
68 List<FileState> get importedLibraries => _importedLibraries; | 72 List<FileState> get importedLibraries => _importedLibraries; |
69 | 73 |
70 /// The list of files this library file references as parts. | 74 /// The list of files this library file references as parts. |
71 List<FileState> get partFiles => _partFiles; | 75 List<FileState> get partFiles => _partFiles; |
72 | 76 |
73 /// Return topologically sorted cycles of dependencies for this library. | 77 /// Return topologically sorted cycles of dependencies for this library. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 | 120 |
117 // Parse directives. | 121 // Parse directives. |
118 ScannerResult scannerResults = _scan(); | 122 ScannerResult scannerResults = _scan(); |
119 var listener = new _DirectiveListenerWithNative(); | 123 var listener = new _DirectiveListenerWithNative(); |
120 new TopLevelParser(listener).parseUnit(scannerResults.tokens); | 124 new TopLevelParser(listener).parseUnit(scannerResults.tokens); |
121 | 125 |
122 // Build the graph. | 126 // Build the graph. |
123 _importedLibraries = <FileState>[]; | 127 _importedLibraries = <FileState>[]; |
124 _exportedLibraries = <FileState>[]; | 128 _exportedLibraries = <FileState>[]; |
125 _partFiles = <FileState>[]; | 129 _partFiles = <FileState>[]; |
126 await _addFileForRelativeUri(_importedLibraries, 'dart:core'); | 130 _exports = <NamespaceExport>[]; |
127 for (String uri in listener.imports) { | 131 { |
128 await _addFileForRelativeUri(_importedLibraries, uri); | 132 FileState coreFile = await _getFileForRelativeUri('dart:core'); |
133 if (coreFile != null) { | |
134 _importedLibraries.add(coreFile); | |
Paul Berry
2017/05/15 20:28:30
Should we report an error? It seems like this sho
| |
135 } | |
136 } | |
137 for (ImportDirective import_ in listener.imports) { | |
138 FileState file = await _getFileForRelativeUri(import_.uri); | |
139 if (file != null) { | |
140 _importedLibraries.add(file); | |
141 } | |
129 } | 142 } |
130 await _addVmTargetImportsForCore(); | 143 await _addVmTargetImportsForCore(); |
131 for (String uri in listener.exports) { | 144 for (ExportDirective export_ in listener.exports) { |
132 await _addFileForRelativeUri(_exportedLibraries, uri); | 145 FileState file = await _getFileForRelativeUri(export_.uri); |
146 if (file != null) { | |
147 _exportedLibraries.add(file); | |
148 _exports.add(new NamespaceExport(file, export_.combinators)); | |
149 } | |
133 } | 150 } |
134 for (String uri in listener.parts) { | 151 for (String uri in listener.parts) { |
135 await _addFileForRelativeUri(_partFiles, uri); | 152 FileState file = await _getFileForRelativeUri(uri); |
153 if (file != null) { | |
154 _partFiles.add(file); | |
155 } | |
136 } | 156 } |
137 | 157 |
138 // Compute referenced files. | 158 // Compute referenced files. |
139 _directReferencedFiles = new Set<FileState>() | 159 _directReferencedFiles = new Set<FileState>() |
140 ..addAll(_importedLibraries) | 160 ..addAll(_importedLibraries) |
141 ..addAll(_exportedLibraries) | 161 ..addAll(_exportedLibraries) |
142 ..addAll(_partFiles); | 162 ..addAll(_partFiles); |
143 _directReferencedLibraries = (new Set<FileState>() | 163 _directReferencedLibraries = (new Set<FileState>() |
144 ..addAll(_importedLibraries) | 164 ..addAll(_importedLibraries) |
145 ..addAll(_exportedLibraries)) | 165 ..addAll(_exportedLibraries)) |
146 .toList(); | 166 .toList(); |
147 } | 167 } |
148 | 168 |
149 @override | 169 @override |
150 String toString() { | 170 String toString() { |
151 if (fileUri.scheme == 'file') return fileUri.path; | 171 if (fileUri.scheme == 'file') return fileUri.path; |
152 return fileUri.toString(); | 172 return fileUri.toString(); |
153 } | 173 } |
154 | 174 |
155 /// Add the [FileState] for the given [relativeUri] to the [files]. | 175 /// Fasta unconditionally loads all VM libraries. In order to be able to |
156 /// Do nothing if the URI cannot be parsed, cannot correspond any file, etc. | 176 /// serve them using the file system view, pretend that all of them were |
157 Future<Null> _addFileForRelativeUri( | 177 /// imported into `dart:core`. |
158 List<FileState> files, String relativeUri) async { | 178 /// TODO(scheglov) Ask VM people whether all these libraries are required. |
159 if (relativeUri.isEmpty) return; | 179 Future<Null> _addVmTargetImportsForCore() async { |
180 if (uri.toString() != 'dart:core') return; | |
181 for (String uri in new VmTarget(null).extraRequiredLibraries) { | |
182 FileState file = await _getFileForRelativeUri(uri); | |
183 if (file != null) { | |
184 _importedLibraries.add(file); | |
Paul Berry
2017/05/15 20:28:30
Similar question here.
| |
185 } | |
186 } | |
187 } | |
188 | |
189 /// Return the [FileState] for the given [relativeUri] or `null` if the URI | |
190 /// cannot be parsed, cannot correspond any file, etc. | |
191 Future<FileState> _getFileForRelativeUri(String relativeUri) async { | |
192 if (relativeUri.isEmpty) return null; | |
160 | 193 |
161 // Resolve the relative URI into absolute. | 194 // Resolve the relative URI into absolute. |
162 // The result is either: | 195 // The result is either: |
163 // 1) The absolute file URI. | 196 // 1) The absolute file URI. |
164 // 2) The absolute non-file URI, e.g. `package:foo/foo.dart`. | 197 // 2) The absolute non-file URI, e.g. `package:foo/foo.dart`. |
165 Uri absoluteUri; | 198 Uri absoluteUri; |
166 try { | 199 try { |
167 absoluteUri = fileUri.resolve(relativeUri); | 200 absoluteUri = fileUri.resolve(relativeUri); |
168 } on FormatException { | 201 } on FormatException { |
169 return; | 202 return null; |
170 } | 203 } |
171 | 204 |
172 FileState file = await _fsState.getFile(absoluteUri); | 205 return await _fsState.getFile(absoluteUri); |
173 if (file == null) return; | |
174 files.add(file); | |
175 } | |
176 | |
177 /// Fasta unconditionally loads all VM libraries. In order to be able to | |
178 /// serve them using the file system view, pretend that all of them were | |
179 /// imported into `dart:core`. | |
180 /// TODO(scheglov) Ask VM people whether all these libraries are required. | |
181 Future<Null> _addVmTargetImportsForCore() async { | |
182 if (uri.toString() != 'dart:core') return; | |
183 for (String uri in new VmTarget(null).extraRequiredLibraries) { | |
184 await _addFileForRelativeUri(_importedLibraries, uri); | |
185 } | |
186 } | 206 } |
187 | 207 |
188 /// Scan the content of the file. | 208 /// Scan the content of the file. |
189 ScannerResult _scan() { | 209 ScannerResult _scan() { |
190 var zeroTerminatedBytes = new Uint8List(_content.length + 1); | 210 var zeroTerminatedBytes = new Uint8List(_content.length + 1); |
191 zeroTerminatedBytes.setRange(0, _content.length, _content); | 211 zeroTerminatedBytes.setRange(0, _content.length, _content); |
192 return scan(zeroTerminatedBytes); | 212 return scan(zeroTerminatedBytes); |
193 } | 213 } |
194 } | 214 } |
195 | 215 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 | 270 |
251 @override | 271 @override |
252 String toString() { | 272 String toString() { |
253 if (_isForVm) { | 273 if (_isForVm) { |
254 return '[core + vm]'; | 274 return '[core + vm]'; |
255 } | 275 } |
256 return '[' + libraries.join(', ') + ']'; | 276 return '[' + libraries.join(', ') + ']'; |
257 } | 277 } |
258 } | 278 } |
259 | 279 |
280 /// Information about a single `export` directive. | |
281 class NamespaceExport { | |
282 final FileState library; | |
283 final List<NamespaceCombinator> combinators; | |
284 | |
285 NamespaceExport(this.library, this.combinators); | |
286 | |
287 /// Return `true` if the [name] satisfies the sequence of the [combinators]. | |
288 bool filter(String name) { | |
289 for (NamespaceCombinator combinator in combinators) { | |
290 if (combinator.isShow) { | |
291 if (!combinator.names.contains(name)) { | |
292 return false; | |
293 } | |
294 } else { | |
295 if (combinator.names.contains(name)) { | |
296 return false; | |
297 } | |
298 } | |
299 } | |
300 return true; | |
301 } | |
302 } | |
303 | |
260 /// [DirectiveListener] that skips native clauses. | 304 /// [DirectiveListener] that skips native clauses. |
261 class _DirectiveListenerWithNative extends DirectiveListener { | 305 class _DirectiveListenerWithNative extends DirectiveListener { |
262 @override | 306 @override |
263 Token handleNativeClause(Token token) => skipNativeClause(token); | 307 Token handleNativeClause(Token token) => skipNativeClause(token); |
264 } | 308 } |
265 | 309 |
266 /// [FileSystemState] based implementation of [FileSystem]. | 310 /// [FileSystemState] based implementation of [FileSystem]. |
267 /// It provides a consistent view on the known file system state. | 311 /// It provides a consistent view on the known file system state. |
268 class _FileSystemView implements FileSystem { | 312 class _FileSystemView implements FileSystem { |
269 final FileSystemState fsState; | 313 final FileSystemState fsState; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
346 node.isEvaluated = true; | 390 node.isEvaluated = true; |
347 cycle.libraries.add(node.file); | 391 cycle.libraries.add(node.file); |
348 } | 392 } |
349 topologicallySortedCycles.add(cycle); | 393 topologicallySortedCycles.add(cycle); |
350 } | 394 } |
351 | 395 |
352 _LibraryNode getNode(FileState file) { | 396 _LibraryNode getNode(FileState file) { |
353 return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file)); | 397 return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file)); |
354 } | 398 } |
355 } | 399 } |
OLD | NEW |