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/base/api_signature.dart'; | 10 import 'package:front_end/src/base/api_signature.dart'; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 List<int> _apiSignature; | 47 List<int> _apiSignature; |
48 | 48 |
49 List<NamespaceExport> _exports; | 49 List<NamespaceExport> _exports; |
50 List<FileState> _importedLibraries; | 50 List<FileState> _importedLibraries; |
51 List<FileState> _exportedLibraries; | 51 List<FileState> _exportedLibraries; |
52 List<FileState> _partFiles; | 52 List<FileState> _partFiles; |
53 | 53 |
54 Set<FileState> _directReferencedFiles = new Set<FileState>(); | 54 Set<FileState> _directReferencedFiles = new Set<FileState>(); |
55 List<FileState> _directReferencedLibraries = <FileState>[]; | 55 List<FileState> _directReferencedLibraries = <FileState>[]; |
56 | 56 |
| 57 /// This flag is set to `true` during the mark phase of garbage collection |
| 58 /// and set back to `false` for survived instances. |
| 59 bool _gcMarked = false; |
| 60 |
57 FileState._(this._fsState, this.uri, this.fileUri); | 61 FileState._(this._fsState, this.uri, this.fileUri); |
58 | 62 |
59 /// The MD5 signature of the file API as a byte array. | 63 /// The MD5 signature of the file API as a byte array. |
60 /// It depends on all non-comment tokens outside the block bodies. | 64 /// It depends on all non-comment tokens outside the block bodies. |
61 List<int> get apiSignature => _apiSignature; | 65 List<int> get apiSignature => _apiSignature; |
62 | 66 |
63 /// The content of the file. | 67 /// The content of the file. |
64 List<int> get content => _content; | 68 List<int> get content => _content; |
65 | 69 |
66 /// The MD5 hash of the [content]. | 70 /// The MD5 hash of the [content]. |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 /// files in this [FileSystem] always have the same content as the | 306 /// files in this [FileSystem] always have the same content as the |
303 /// corresponding [FileState]s, thus avoiding race conditions when a file | 307 /// corresponding [FileState]s, thus avoiding race conditions when a file |
304 /// is updated on the actual file system. | 308 /// is updated on the actual file system. |
305 FileSystem get fileSystemView { | 309 FileSystem get fileSystemView { |
306 return _fileSystemView ??= new _FileSystemView(this); | 310 return _fileSystemView ??= new _FileSystemView(this); |
307 } | 311 } |
308 | 312 |
309 /// The `file:` URI of all files currently tracked by this instance. | 313 /// The `file:` URI of all files currently tracked by this instance. |
310 Iterable<Uri> get fileUris => _fileUriToFile.keys; | 314 Iterable<Uri> get fileUris => _fileUriToFile.keys; |
311 | 315 |
| 316 /// Perform mark and sweep garbage collection of [FileState]s. |
| 317 void gc(Uri entryPoint) { |
| 318 void mark(FileState file) { |
| 319 if (!file._gcMarked) { |
| 320 file._gcMarked = true; |
| 321 file._directReferencedFiles.forEach(mark); |
| 322 } |
| 323 } |
| 324 |
| 325 var file = _uriToFile[entryPoint]; |
| 326 if (file == null) return; |
| 327 |
| 328 mark(file); |
| 329 |
| 330 var urisToRemove = new Set<Uri>(); |
| 331 var fileUrisToRemove = new Set<Uri>(); |
| 332 for (var file in _uriToFile.values) { |
| 333 if (file._gcMarked) { |
| 334 file._gcMarked = false; |
| 335 } else { |
| 336 urisToRemove.add(file.uri); |
| 337 fileUrisToRemove.add(file.fileUri); |
| 338 } |
| 339 } |
| 340 |
| 341 urisToRemove.forEach(_uriToFile.remove); |
| 342 fileUrisToRemove.forEach(_fileUriToFile.remove); |
| 343 } |
| 344 |
312 /// Return the [FileState] for the given [absoluteUri], or `null` if the | 345 /// Return the [FileState] for the given [absoluteUri], or `null` if the |
313 /// [absoluteUri] cannot be resolved into a file URI. | 346 /// [absoluteUri] cannot be resolved into a file URI. |
314 /// | 347 /// |
315 /// The returned file has the last known state since it was last refreshed. | 348 /// The returned file has the last known state since it was last refreshed. |
316 Future<FileState> getFile(Uri absoluteUri) async { | 349 Future<FileState> getFile(Uri absoluteUri) async { |
317 // Resolve the absolute URI into the absolute file URI. | 350 // Resolve the absolute URI into the absolute file URI. |
318 Uri fileUri; | 351 Uri fileUri; |
319 if (absoluteUri.isScheme('file')) { | 352 if (absoluteUri.isScheme('file')) { |
320 fileUri = absoluteUri; | 353 fileUri = absoluteUri; |
321 } else { | 354 } else { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 node.isEvaluated = true; | 539 node.isEvaluated = true; |
507 cycle.libraries.add(node.file); | 540 cycle.libraries.add(node.file); |
508 } | 541 } |
509 topologicallySortedCycles.add(cycle); | 542 topologicallySortedCycles.add(cycle); |
510 } | 543 } |
511 | 544 |
512 _LibraryNode getNode(FileState file) { | 545 _LibraryNode getNode(FileState file) { |
513 return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file)); | 546 return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file)); |
514 } | 547 } |
515 } | 548 } |
OLD | NEW |