Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: pkg/front_end/lib/src/incremental/file_state.dart

Issue 2864243004: Revert "Start using FileState/FileSystemState to provide consistent view." (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 import 'dart:async';
6 import 'dart:convert';
7 import 'dart:typed_data';
8
9 import 'package:front_end/file_system.dart';
10 import 'package:front_end/src/fasta/parser/top_level_parser.dart';
11 import 'package:front_end/src/fasta/scanner.dart';
12 import 'package:front_end/src/fasta/source/directive_listener.dart';
13 import 'package:front_end/src/fasta/translate_uri.dart';
14
15 /// Information about a file being compiled, explicitly or implicitly.
16 ///
17 /// It provides a consistent view on its properties.
18 ///
19 /// The properties are not guaranteed to represent the most recent state
20 /// of the file system. To update the file to the most recent state, [refresh]
21 /// should be called.
22 class FileState {
23 final FileSystemState _fsState;
24
25 /// The resolved URI of the file in the file system.
26 final Uri fileUri;
27
28 bool _exists;
29 List<int> _contentBytes;
30 String _content;
31
32 List<FileState> _importedFiles;
33 List<FileState> _exportedFiles;
34 List<FileState> _partFiles;
35
36 Set<FileState> _directReferencedFiles = new Set<FileState>();
37
38 FileState._(this._fsState, this.fileUri);
39
40 /// The content of the file.
41 String get content => _content;
42
43 /// The content bytes of the file.
44 List<int> get contentBytes => _contentBytes;
45
46 /// Whether the file exists.
47 bool get exists => _exists;
48
49 @override
50 int get hashCode => fileUri.hashCode;
51
52 /// Return the set of transitive files - the file itself and all of the
53 /// directly or indirectly referenced files.
54 Set<FileState> get transitiveFiles {
55 // TODO(scheglov) add caching.
56 var transitiveFiles = new Set<FileState>();
57
58 void appendReferenced(FileState file) {
59 if (transitiveFiles.add(file)) {
60 file._directReferencedFiles.forEach(appendReferenced);
61 }
62 }
63
64 appendReferenced(this);
65 return transitiveFiles;
66 }
67
68 @override
69 bool operator ==(Object other) {
70 return other is FileState && other.fileUri == fileUri;
71 }
72
73 /// Read the file content and ensure that all of the file properties are
74 /// consistent with the read content, including all its dependencies.
75 Future<Null> refresh() async {
76 // Read the content.
77 try {
78 FileSystemEntity entry = _fsState.fileSystem.entityForUri(fileUri);
79 _contentBytes = await entry.readAsBytes();
80 _content = UTF8.decode(_contentBytes);
81 _exists = true;
82 } catch (_) {
83 _contentBytes = new Uint8List(0);
84 _content = '';
85 _exists = false;
86 }
87
88 // Parse directives.
89 ScannerResult scannerResults = scanString(_content);
90 var listener = new DirectiveListener();
91 new TopLevelParser(listener).parseUnit(scannerResults.tokens);
92
93 // Build the graph.
94 _importedFiles = <FileState>[];
95 _exportedFiles = <FileState>[];
96 _partFiles = <FileState>[];
97 await _addFileForRelativeUri(_importedFiles, 'dart:core');
98 for (String uri in listener.imports) {
99 await _addFileForRelativeUri(_importedFiles, uri);
100 }
101 for (String uri in listener.exports) {
102 await _addFileForRelativeUri(_exportedFiles, uri);
103 }
104 for (String uri in listener.parts) {
105 await _addFileForRelativeUri(_partFiles, uri);
106 }
107
108 // Compute referenced files.
109 _directReferencedFiles = new Set<FileState>()
110 ..addAll(_importedFiles)
111 ..addAll(_exportedFiles)
112 ..addAll(_partFiles);
113 }
114
115 /// Add the [FileState] for the given [relativeUri] to the [files].
116 /// Do nothing if the URI cannot be parsed, cannot correspond any file, etc.
117 Future<Null> _addFileForRelativeUri(
118 List<FileState> files, String relativeUri) async {
119 if (relativeUri.isEmpty) return;
120
121 // Resolve the relative URI into absolute.
122 // The result is either:
123 // 1) The absolute file URI.
124 // 2) The absolute non-file URI, e.g. `package:foo/foo.dart`.
125 Uri absoluteUri;
126 try {
127 absoluteUri = fileUri.resolve(relativeUri);
128 } on FormatException {
129 return;
130 }
131
132 // Resolve the absolute URI into the absolute file URI.
133 Uri resolvedUri = _fsState.uriTranslator.translate(absoluteUri);
134 if (resolvedUri == null) return;
135
136 FileState file = await _fsState.getFile(resolvedUri);
137 files.add(file);
138 }
139 }
140
141 /// Information about known file system state.
142 class FileSystemState {
143 final FileSystem fileSystem;
144 final TranslateUri uriTranslator;
145
146 _FileSystemView _fileSystemView;
147
148 /// Mapping from file URIs to corresponding [FileState]s.
149 final Map<Uri, FileState> _fileUriToFile = {};
150
151 FileSystemState(this.fileSystem, this.uriTranslator);
152
153 /// Return the [FileSystem] that is backed by this [FileSystemState]. The
154 /// files in this [FileSystem] always have the same content as the
155 /// corresponding [FileState]s, thus avoiding race conditions when a file
156 /// is updated on the actual file system.
157 FileSystem get fileSystemView {
158 return _fileSystemView ??= new _FileSystemView(this);
159 }
160
161 /// Return the [FileState] for the given resolved file [fileUri].
162 /// The returned file has the last known state since it was last refreshed.
163 Future<FileState> getFile(Uri fileUri) async {
164 FileState file = _fileUriToFile[fileUri];
165 if (file == null) {
166 file = new FileState._(this, fileUri);
167 _fileUriToFile[fileUri] = file;
168
169 // Build the sub-graph of the file.
170 await file.refresh();
171 }
172 return file;
173 }
174 }
175
176 /// [FileSystemState] based implementation of [FileSystem].
177 /// It provides a consistent view on the known file system state.
178 class _FileSystemView implements FileSystem {
179 final FileSystemState fsState;
180
181 _FileSystemView(this.fsState);
182
183 @override
184 FileSystemEntity entityForUri(Uri uri) {
185 FileState file = fsState._fileUriToFile[uri];
186 return new _FileSystemViewEntry(uri, file);
187 }
188 }
189
190 /// [FileSystemState] based implementation of [FileSystemEntity].
191 class _FileSystemViewEntry implements FileSystemEntity {
192 @override
193 final Uri uri;
194
195 final FileState file;
196
197 _FileSystemViewEntry(this.uri, this.file);
198
199 @override
200 Future<bool> exists() async => file?.exists ?? false;
201
202 @override
203 Future<DateTime> lastModified() async {
204 throw new StateError(
205 'FileSystemViewEntry modification stamp should not be queried');
206 }
207
208 @override
209 Future<List<int>> readAsBytes() async {
210 _throwIfDoesNotExist();
211 return file.contentBytes;
212 }
213
214 @override
215 Future<String> readAsString() async {
216 _throwIfDoesNotExist();
217 return file.content;
218 }
219
220 void _throwIfDoesNotExist() {
221 if (file == null) {
222 throw new FileSystemException(uri, 'File $uri does not exist.');
223 }
224 }
225 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/incremental_kernel_generator.dart ('k') | pkg/front_end/lib/src/incremental_kernel_generator_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698