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

Side by Side Diff: pkg/front_end/lib/src/incremental_resolved_ast_generator_impl.dart

Issue 2645923002: Create a "file repository" data structure to help interface analyzer and front_end code. (Closed)
Patch Set: Created 3 years, 11 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
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 6
7 import 'package:analyzer/file_system/file_system.dart'; 7 import 'package:analyzer/file_system/file_system.dart';
8 import 'package:analyzer/src/context/context.dart'; 8 import 'package:analyzer/src/context/context.dart';
9 import 'package:analyzer/src/dart/analysis/byte_store.dart'; 9 import 'package:analyzer/src/dart/analysis/byte_store.dart';
10 import 'package:analyzer/src/dart/analysis/driver.dart' as driver; 10 import 'package:analyzer/src/dart/analysis/driver.dart' as driver;
11 import 'package:analyzer/src/dart/analysis/file_state.dart'; 11 import 'package:analyzer/src/dart/analysis/file_state.dart';
12 import 'package:analyzer/src/generated/engine.dart'; 12 import 'package:analyzer/src/generated/engine.dart';
13 import 'package:analyzer/src/generated/sdk.dart'; 13 import 'package:analyzer/src/generated/sdk.dart';
14 import 'package:analyzer/src/generated/source.dart'; 14 import 'package:analyzer/src/generated/source.dart';
15 import 'package:analyzer/src/summary/idl.dart'; 15 import 'package:analyzer/src/summary/idl.dart';
16 import 'package:analyzer/src/summary/summary_sdk.dart'; 16 import 'package:analyzer/src/summary/summary_sdk.dart';
17 import 'package:analyzer/src/util/absolute_path.dart'; 17 import 'package:analyzer/src/util/absolute_path.dart';
18 import 'package:front_end/incremental_resolved_ast_generator.dart'; 18 import 'package:front_end/incremental_resolved_ast_generator.dart';
19 import 'package:front_end/src/base/file_repository.dart';
19 import 'package:front_end/src/base/processed_options.dart'; 20 import 'package:front_end/src/base/processed_options.dart';
20 import 'package:front_end/src/base/source.dart'; 21 import 'package:front_end/src/base/source.dart';
21 import 'package:front_end/src/dependency_grapher_impl.dart'; 22 import 'package:front_end/src/dependency_grapher_impl.dart';
22 import 'package:path/src/context.dart'; 23 import 'package:path/src/context.dart';
23 24
24 dynamic unimplemented() { 25 dynamic unimplemented() {
25 // TODO(paulberry): get rid of this. 26 // TODO(paulberry): get rid of this.
26 throw new UnimplementedError(); 27 throw new UnimplementedError();
27 } 28 }
28 29
29 /// Implementation of [IncrementalKernelGenerator]. 30 /// Implementation of [IncrementalKernelGenerator].
30 /// 31 ///
31 /// Theory of operation: this class is a thin wrapper around 32 /// Theory of operation: this class is a thin wrapper around
32 /// [driver.AnalysisDriver]. When the client requests a new delta, we forward 33 /// [driver.AnalysisDriver]. When the client requests a new delta, we forward
33 /// the request to the analysis driver. When the client calls an invalidate 34 /// the request to the analysis driver. When the client calls an invalidate
34 /// method, we ensure that the proper files will be re-read next time a delta is 35 /// method, we ensure that the proper files will be re-read next time a delta is
35 /// requested. 36 /// requested.
36 /// 37 ///
37 /// Note that the analysis driver expects to be able to read file contents 38 /// Note that the analysis driver expects to be able to read file contents
38 /// synchronously based on filesystem path rather than asynchronously based on 39 /// synchronously based on filesystem path rather than asynchronously based on
39 /// URI, so the file contents are first read into memory using the asynchronous 40 /// URI, so the file contents are first read into memory using the asynchronous
40 /// FileSystem API, and then these are fed into the analysis driver using a 41 /// FileSystem API, and then these are fed into the analysis driver using a
41 /// proxy implementation of [ResourceProvider]. TODO(paulberry): make this (and 42 /// proxy implementation of [ResourceProvider]. TODO(paulberry): make this (and
42 /// other proxies in this file) unnecessary. 43 /// other proxies in this file) unnecessary.
43 class IncrementalResolvedAstGeneratorImpl 44 class IncrementalResolvedAstGeneratorImpl
44 implements IncrementalResolvedAstGenerator { 45 implements IncrementalResolvedAstGenerator {
45 driver.AnalysisDriverScheduler _scheduler; 46 driver.AnalysisDriverScheduler _scheduler;
46 final _pathToUriMap = <String, Uri>{}; 47 final _fileRepository = new FileRepository();
47 final _uriToPathMap = <Uri, String>{};
48 final _fileContents = <String, String>{};
49 _ResourceProviderProxy _resourceProvider; 48 _ResourceProviderProxy _resourceProvider;
50 driver.AnalysisDriver _driver; 49 driver.AnalysisDriver _driver;
51 bool _isInitialized = false; 50 bool _isInitialized = false;
52 final ProcessedOptions _options; 51 final ProcessedOptions _options;
53 final Uri _source; 52 final Uri _source;
54 bool _schedulerStarted = false; 53 bool _schedulerStarted = false;
55 54
56 IncrementalResolvedAstGeneratorImpl(this._source, this._options); 55 IncrementalResolvedAstGeneratorImpl(this._source, this._options);
57 56
58 @override 57 @override
59 Future<DeltaLibraries> computeDelta() async { 58 Future<DeltaLibraries> computeDelta() async {
60 if (!_isInitialized) { 59 if (!_isInitialized) {
61 await init(); 60 await init();
62 } 61 }
63 // The analysis driver doesn't currently support an asynchronous file API, 62 // The analysis driver doesn't currently support an asynchronous file API,
64 // so we have to find all the files first to read their contents. 63 // so we have to find all the files first to read their contents.
65 // TODO(paulberry): this is an unnecessary source of duplicate work and 64 // TODO(paulberry): this is an unnecessary source of duplicate work and
66 // should be eliminated ASAP. 65 // should be eliminated ASAP.
67 var graph = await graphForProgram([_source], _options); 66 var graph = await graphForProgram([_source], _options);
68 var libraries = <Uri, ResolvedLibrary>{}; 67 var libraries = <Uri, ResolvedLibrary>{};
69 // TODO(paulberry): it should be possible to seed the driver using a URI,
70 // not a file path.
71 if (!_schedulerStarted) { 68 if (!_schedulerStarted) {
72 _scheduler.start(); 69 _scheduler.start();
73 _schedulerStarted = true; 70 _schedulerStarted = true;
74 } 71 }
75 _driver.addFile(_source.path); 72 // The driver will request files from dart:, even though it actually uses
73 // the data from the summary. TODO(paulberry): fix this.
74 _fileRepository.store(Uri.parse('dart:core'), '');
76 for (var libraryCycle in graph.topologicallySortedCycles) { 75 for (var libraryCycle in graph.topologicallySortedCycles) {
77 for (var uri in libraryCycle.libraries.keys) { 76 for (var uri in libraryCycle.libraries.keys) {
78 var contents = 77 var contents =
79 await _options.fileSystem.entityForUri(uri).readAsString(); 78 await _options.fileSystem.entityForUri(uri).readAsString();
80 _storeVirtualFile(uri, uri.path, contents); 79 _fileRepository.store(uri, contents);
81 } 80 }
82 // The driver will request files from dart:, even though it actually uses
83 // the data from the summary. TODO(paulberry): fix this.
84 _storeVirtualFile(_DartSdkProxy._dartCoreSource.uri, 'core.dart', '');
85 for (var uri in libraryCycle.libraries.keys) { 81 for (var uri in libraryCycle.libraries.keys) {
86 var result = await _driver.getResult(uri.path); 82 var result = await _driver.getResult(_fileRepository.pathForUri(uri));
87 // TODO(paulberry): handle errors. 83 // TODO(paulberry): handle errors.
88 libraries[uri] = new ResolvedLibrary(result.unit); 84 libraries[uri] = new ResolvedLibrary(result.unit);
89 } 85 }
90 } 86 }
87 _driver.addFile(_fileRepository.pathForUri(_source));
91 // TODO(paulberry): stop the scheduler 88 // TODO(paulberry): stop the scheduler
92 return new DeltaLibraries(libraries); 89 return new DeltaLibraries(libraries);
93 } 90 }
94 91
95 Future<Null> init() async { 92 Future<Null> init() async {
96 // TODO(paulberry): can we just use null? 93 // TODO(paulberry): can we just use null?
97 var performanceLog = new driver.PerformanceLog(new _NullStringSink()); 94 var performanceLog = new driver.PerformanceLog(new _NullStringSink());
98 _scheduler = new driver.AnalysisDriverScheduler(performanceLog); 95 _scheduler = new driver.AnalysisDriverScheduler(performanceLog);
99 _resourceProvider = 96 _resourceProvider = new _ResourceProviderProxy(_fileRepository);
100 new _ResourceProviderProxy(_fileContents, _pathToUriMap);
101 // TODO(paulberry): MemoryByteStore leaks memory (it never discards data). 97 // TODO(paulberry): MemoryByteStore leaks memory (it never discards data).
102 // Do something better here. 98 // Do something better here.
103 var byteStore = new MemoryByteStore(); 99 var byteStore = new MemoryByteStore();
104 // TODO(paulberry): can we just use null? 100 // TODO(paulberry): can we just use null?
105 var fileContentOverlay = new FileContentOverlay(); 101 var fileContentOverlay = new FileContentOverlay();
106 var sdkContext = new AnalysisContextImpl(); 102 var sdkContext = new AnalysisContextImpl();
107 var dartSdk = new _DartSdkProxy(await _options.getSdkSummary(), sdkContext); 103 var dartSdk = new _DartSdkProxy(await _options.getSdkSummary(), sdkContext);
108 sdkContext.sourceFactory = 104 sdkContext.sourceFactory =
109 new SourceFactory([new DartUriResolver(dartSdk)]); 105 new SourceFactory([new DartUriResolver(dartSdk)]);
110 bool strongMode = true; // TODO(paulberry): support strong mode flag. 106 bool strongMode = true; // TODO(paulberry): support strong mode flag.
111 sdkContext.resultProvider = new SdkSummaryResultProvider( 107 sdkContext.resultProvider = new SdkSummaryResultProvider(
112 sdkContext, await _options.getSdkSummary(), strongMode); 108 sdkContext, await _options.getSdkSummary(), strongMode);
113 109
114 var sourceFactory = 110 var sourceFactory = new _SourceFactoryProxy(dartSdk, _fileRepository);
115 new _SourceFactoryProxy(dartSdk, _pathToUriMap, _uriToPathMap);
116 var analysisOptions = new AnalysisOptionsImpl(); 111 var analysisOptions = new AnalysisOptionsImpl();
117 _driver = new driver.AnalysisDriver( 112 _driver = new driver.AnalysisDriver(
118 _scheduler, 113 _scheduler,
119 performanceLog, 114 performanceLog,
120 _resourceProvider, 115 _resourceProvider,
121 byteStore, 116 byteStore,
122 fileContentOverlay, 117 fileContentOverlay,
123 'front_end', 118 'front_end',
124 sourceFactory, 119 sourceFactory,
125 analysisOptions); 120 analysisOptions);
126 _isInitialized = true; 121 _isInitialized = true;
127 } 122 }
128 123
129 @override 124 @override
130 void invalidate(String path) { 125 void invalidate(String path) {
131 throw new UnimplementedError(); 126 throw new UnimplementedError();
132 } 127 }
133 128
134 @override 129 @override
135 void invalidateAll() { 130 void invalidateAll() {
136 // TODO(paulberry): verify that this has an effect (requires a multi-file 131 // TODO(paulberry): verify that this has an effect (requires a multi-file
137 // test). 132 // test).
138 if (_isInitialized) { 133 if (_isInitialized) {
139 _driver.knownFiles.forEach(_driver.changeFile); 134 _driver.knownFiles.forEach(_driver.changeFile);
140 } 135 }
141 } 136 }
142
143 void _storeVirtualFile(Uri uri, String path, String contents) {
144 _pathToUriMap[path] = uri;
145 _uriToPathMap[uri] = path;
146 _fileContents[path] = contents;
147 }
148 } 137 }
149 138
150 class _DartSdkProxy implements DartSdk { 139 class _DartSdkProxy implements DartSdk {
151 static final _dartCoreSource =
152 new _SourceProxy(Uri.parse('dart:core'), 'core.dart');
153
154 final PackageBundle summary; 140 final PackageBundle summary;
155 141
156 final AnalysisContext context; 142 final AnalysisContext context;
157 143
158 _DartSdkProxy(this.summary, this.context); 144 _DartSdkProxy(this.summary, this.context);
159 145
160 @override 146 @override
161 PackageBundle getLinkedBundle() => summary; 147 PackageBundle getLinkedBundle() => summary;
162 148
163 @override 149 @override
(...skipping 21 matching lines...) Expand all
185 @override 171 @override
186 Source createSource([Uri uri]) { 172 Source createSource([Uri uri]) {
187 assert(uri == null); 173 assert(uri == null);
188 return _source; 174 return _source;
189 } 175 }
190 176
191 noSuchMethod(Invocation invocation) => unimplemented(); 177 noSuchMethod(Invocation invocation) => unimplemented();
192 178
193 @override 179 @override
194 String readAsStringSync() { 180 String readAsStringSync() {
195 assert(_resourceProvider.fileContents.containsKey(path)); 181 return _resourceProvider._fileRepository.contentsForPath(path);
196 return _resourceProvider.fileContents[path];
197 } 182 }
198 } 183 }
199 184
200 /// A string sink that ignores everything written to it. 185 /// A string sink that ignores everything written to it.
201 class _NullStringSink implements StringSink { 186 class _NullStringSink implements StringSink {
202 void write(Object obj) {} 187 void write(Object obj) {}
203 void writeAll(Iterable objects, [String separator = ""]) {} 188 void writeAll(Iterable objects, [String separator = ""]) {}
204 void writeCharCode(int charCode) {} 189 void writeCharCode(int charCode) {}
205 void writeln([Object obj = ""]) {} 190 void writeln([Object obj = ""]) {}
206 } 191 }
207 192
208 class _ResourceProviderProxy implements ResourceProvider { 193 class _ResourceProviderProxy implements ResourceProvider {
209 final Map<String, String> fileContents; 194 final FileRepository _fileRepository;
210 final Map<String, Uri> pathToUriMap;
211 195
212 _ResourceProviderProxy(this.fileContents, this.pathToUriMap); 196 _ResourceProviderProxy(this._fileRepository);
213 197
214 @override 198 @override
215 AbsolutePathContext get absolutePathContext => throw new UnimplementedError(); 199 AbsolutePathContext get absolutePathContext => throw new UnimplementedError();
216 200
217 @override 201 @override
218 Context get pathContext => throw new UnimplementedError(); 202 Context get pathContext => throw new UnimplementedError();
219 203
220 @override 204 @override
221 File getFile(String path) { 205 File getFile(String path) {
222 assert(fileContents.containsKey(path)); 206 return new _FileProxy(
223 assert(pathToUriMap.containsKey(path)); 207 new _SourceProxy(_fileRepository.uriForPath(path), path), this);
224 return new _FileProxy(new _SourceProxy(pathToUriMap[path], path), this);
225 } 208 }
226 209
227 @override 210 @override
228 Folder getFolder(String path) => throw new UnimplementedError(); 211 Folder getFolder(String path) => throw new UnimplementedError();
229 212
230 @override 213 @override
231 Future<List<int>> getModificationTimes(List<Source> sources) => 214 Future<List<int>> getModificationTimes(List<Source> sources) =>
232 throw new UnimplementedError(); 215 throw new UnimplementedError();
233 216
234 @override 217 @override
235 Resource getResource(String path) => throw new UnimplementedError(); 218 Resource getResource(String path) => throw new UnimplementedError();
236 219
237 @override 220 @override
238 Folder getStateLocation(String pluginId) => throw new UnimplementedError(); 221 Folder getStateLocation(String pluginId) => throw new UnimplementedError();
239 } 222 }
240 223
241 class _SourceFactoryProxy implements SourceFactory { 224 class _SourceFactoryProxy implements SourceFactory {
242 @override 225 @override
243 final DartSdk dartSdk; 226 final DartSdk dartSdk;
244 227
245 final Map<String, Uri> pathToUriMap; 228 final FileRepository _fileRepository;
246
247 final Map<Uri, String> uriToPathMap;
248 229
249 @override 230 @override
250 AnalysisContext context; 231 AnalysisContext context;
251 232
252 _SourceFactoryProxy(this.dartSdk, this.pathToUriMap, this.uriToPathMap); 233 _SourceFactoryProxy(this.dartSdk, this._fileRepository);
253 234
254 @override 235 @override
255 SourceFactory clone() => 236 SourceFactory clone() => new _SourceFactoryProxy(dartSdk, _fileRepository);
256 new _SourceFactoryProxy(dartSdk, pathToUriMap, uriToPathMap);
257 237
258 @override 238 @override
259 Source forUri(String absoluteUri) { 239 Source forUri(String absoluteUri) {
260 if (absoluteUri == 'dart:core') return _DartSdkProxy._dartCoreSource;
261 Uri uri = Uri.parse(absoluteUri); 240 Uri uri = Uri.parse(absoluteUri);
262 assert(uriToPathMap.containsKey(uri)); 241 return new _SourceProxy(uri, _fileRepository.pathForUri(uri));
263 return new _SourceProxy(uri, uriToPathMap[uri]);
264 } 242 }
265 243
266 noSuchMethod(Invocation invocation) => unimplemented(); 244 noSuchMethod(Invocation invocation) => unimplemented();
267 245
268 Source resolveUri(Source containingSource, String containedUri) { 246 Source resolveUri(Source containingSource, String containedUri) {
269 // TODO(paulberry): re-use code from dependency_grapher_impl, and support 247 // TODO(paulberry): re-use code from dependency_grapher_impl, and support
270 // SDK URI resolution logic. 248 // SDK URI resolution logic.
271 var absoluteUri = containingSource.uri.resolve(containedUri); 249 var absoluteUri = containingSource.uri.resolve(containedUri);
272 return forUri(absoluteUri.toString()); 250 return forUri(absoluteUri.toString());
273 } 251 }
274 252
275 @override 253 @override
276 Uri restoreUri(Source source) => source.uri; 254 Uri restoreUri(Source source) => source.uri;
277 } 255 }
278 256
279 class _SourceProxy extends BasicSource { 257 class _SourceProxy extends BasicSource {
280 @override 258 @override
281 final String fullName; 259 final String fullName;
282 260
283 _SourceProxy(Uri uri, this.fullName) : super(uri); 261 _SourceProxy(Uri uri, this.fullName) : super(uri);
284 262
285 int get modificationStamp => 0; 263 int get modificationStamp => 0;
286 264
287 noSuchMethod(Invocation invocation) => unimplemented(); 265 noSuchMethod(Invocation invocation) => unimplemented();
288 } 266 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/base/file_repository.dart ('k') | pkg/front_end/test/src/base/file_repository_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698