| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /// A file system that implements [CopilerOptions.multiRoots]. |
| 6 library front_end.src.multi_roots_file_system; |
| 7 |
| 8 import 'dart:async'; |
| 9 |
| 10 import 'package:front_end/file_system.dart'; |
| 11 |
| 12 /// Wraps a file system to create an overlay of files from multiple roots. |
| 13 /// |
| 14 /// Regular `file:` URIs are resolved directly in the underlying file system, |
| 15 /// but URIs that use a special [markerScheme] are resolved by searching |
| 16 /// under a set of given roots in order. |
| 17 /// |
| 18 /// For example, consider the following inputs: |
| 19 /// |
| 20 /// - markerScheme is `multi-root` |
| 21 /// - the set of roots are `file:///a/` and `file:///b/` |
| 22 /// - the underlying file system contains files: |
| 23 /// a/c/a1.dart |
| 24 /// a/c/a2.dart |
| 25 /// b/c/b1.dart |
| 26 /// b/c/a2.dart |
| 27 /// c/c1.dart |
| 28 /// |
| 29 /// Then: |
| 30 /// |
| 31 /// - file:///c/c1.dart is resolved as file:///c/c1.dart |
| 32 /// - multi-root:///c/a1.dart is resolved as file:///a/c/a1.dart |
| 33 /// - multi-root:///c/b1.dart is resolved as file:///b/c/b1.dart |
| 34 /// - multi-root:///c/a2.dart is resolved as file:///a/c/b2.dart |
| 35 class MultiRootFileSystem implements FileSystem { |
| 36 final String markerScheme; |
| 37 final List<Uri> roots; |
| 38 final FileSystem original; |
| 39 |
| 40 MultiRootFileSystem(this.markerScheme, List roots, this.original) |
| 41 : roots = roots.map(_normalize).toList(); |
| 42 |
| 43 @override |
| 44 FileSystemEntity entityForUri(Uri uri) => |
| 45 new MultiRootFileSystemEntity(this, uri); |
| 46 } |
| 47 |
| 48 /// Entity that searches the multiple roots and resolve a, possibly multi-root, |
| 49 /// entity to a plain entity under `multiRootFileSystem.original`. |
| 50 class MultiRootFileSystemEntity implements FileSystemEntity { |
| 51 final MultiRootFileSystem multiRootFileSystem; |
| 52 final Uri uri; |
| 53 FileSystemEntity _delegate; |
| 54 Future<FileSystemEntity> get delegate async => |
| 55 _delegate ??= await _resolveEntity(); |
| 56 |
| 57 Future<FileSystemEntity> _resolveEntity() async { |
| 58 if (uri.scheme == multiRootFileSystem.markerScheme && uri.isAbsolute) { |
| 59 var original = multiRootFileSystem.original; |
| 60 assert(uri.path.startsWith('/')); |
| 61 var path = uri.path.substring(1); |
| 62 for (var root in multiRootFileSystem.roots) { |
| 63 var candidate = original.entityForUri(root.resolve(path)); |
| 64 if (await candidate.exists()) return candidate; |
| 65 } |
| 66 } |
| 67 return multiRootFileSystem.original.entityForUri(uri); |
| 68 } |
| 69 |
| 70 MultiRootFileSystemEntity(this.multiRootFileSystem, this.uri); |
| 71 |
| 72 @override |
| 73 Future<bool> exists() async => (await delegate).exists(); |
| 74 |
| 75 @override |
| 76 Future<DateTime> lastModified() async => (await delegate).lastModified(); |
| 77 |
| 78 @override |
| 79 Future<List<int>> readAsBytes() async => (await delegate).readAsBytes(); |
| 80 |
| 81 @override |
| 82 Future<String> readAsString() async => (await delegate).readAsString(); |
| 83 } |
| 84 |
| 85 _normalize(Uri uri) => |
| 86 uri.path.endsWith('/') ? uri : uri.replace(path: '${uri.path}/'); |
| OLD | NEW |