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

Side by Side Diff: pkg/analyzer/lib/src/dart/analysis/file_state.dart

Issue 2469323004: Mix file: and package: URIs during analysis. (Closed)
Patch Set: Refresh all FileState instances for a path. Created 4 years, 1 month 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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:convert'; 5 import 'dart:convert';
6 import 'dart:typed_data'; 6 import 'dart:typed_data';
7 7
8 import 'package:analyzer/dart/ast/ast.dart'; 8 import 'package:analyzer/dart/ast/ast.dart';
9 import 'package:analyzer/dart/ast/token.dart'; 9 import 'package:analyzer/dart/ast/token.dart';
10 import 'package:analyzer/error/listener.dart'; 10 import 'package:analyzer/error/listener.dart';
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 /** 69 /**
70 * The absolute path of the file. 70 * The absolute path of the file.
71 */ 71 */
72 final String path; 72 final String path;
73 73
74 /** 74 /**
75 * The absolute URI of the file. 75 * The absolute URI of the file.
76 */ 76 */
77 final Uri uri; 77 final Uri uri;
78 78
79 Source _source; 79 /**
80 * The [Source] of the file with the [uri].
81 */
82 Source source;
80 83
81 String _content; 84 String _content;
82 String _contentHash; 85 String _contentHash;
83 LineInfo _lineInfo; 86 LineInfo _lineInfo;
84 UnlinkedUnit _unlinked; 87 UnlinkedUnit _unlinked;
85 List<int> _apiSignature; 88 List<int> _apiSignature;
86 89
87 List<FileState> _importedFiles; 90 List<FileState> _importedFiles;
88 List<FileState> _exportedFiles; 91 List<FileState> _exportedFiles;
89 List<FileState> _partedFiles; 92 List<FileState> _partedFiles;
90 List<FileState> _dependencies; 93 List<FileState> _dependencies;
91 94
92 FileState(this._fsState, this.path, this.uri) { 95 FileState._(this._fsState, this.path, this.uri, this.source);
93 _source = new FileSource(_fsState._resourceProvider.getFile(path), uri);
94 }
95 96
96 /** 97 /**
97 * The unlinked API signature of the file. 98 * The unlinked API signature of the file.
98 */ 99 */
99 List<int> get apiSignature => _apiSignature; 100 List<int> get apiSignature => _apiSignature;
100 101
101 /** 102 /**
102 * The content of the file. 103 * The content of the file.
103 */ 104 */
104 String get content => _content; 105 String get content => _content;
105 106
106 /** 107 /**
107 * The MD5 hash of the [content]. 108 * The MD5 hash of the [content].
108 */ 109 */
109 String get contentHash => _contentHash; 110 String get contentHash => _contentHash;
110 111
111 /** 112 /**
112 * Return information about line in the file.
113 */
114 LineInfo get lineInfo => _lineInfo;
115
116 /**
117 * Return the list of all direct dependencies. 113 * Return the list of all direct dependencies.
118 */ 114 */
119 List<FileState> get dependencies => _dependencies; 115 List<FileState> get dependencies => _dependencies;
120 116
121 /** 117 /**
122 * The list of files this file exports. 118 * The list of files this file exports.
123 */ 119 */
124 List<FileState> get exportedFiles => _exportedFiles; 120 List<FileState> get exportedFiles => _exportedFiles;
125 121
126 /** 122 /**
127 * The list of files this file imports. 123 * The list of files this file imports.
128 */ 124 */
129 List<FileState> get importedFiles => _importedFiles; 125 List<FileState> get importedFiles => _importedFiles;
130 126
131 /** 127 /**
128 * Return information about line in the file.
129 */
130 LineInfo get lineInfo => _lineInfo;
131
132 /**
132 * The list of files this library file references as parts. 133 * The list of files this library file references as parts.
133 */ 134 */
134 List<FileState> get partedFiles => _partedFiles; 135 List<FileState> get partedFiles => _partedFiles;
135 136
136 /** 137 /**
137 * The [Source] of the file in the [SourceFactory].
138 */
139 Source get source => _source;
140
141 /**
142 * The [UnlinkedUnit] of the file. 138 * The [UnlinkedUnit] of the file.
143 */ 139 */
144 UnlinkedUnit get unlinked => _unlinked; 140 UnlinkedUnit get unlinked => _unlinked;
145 141
146 /** 142 /**
147 * Read the file content and ensure that all of the file properties are 143 * Read the file content and ensure that all of the file properties are
148 * consistent with the read content, including API signature. 144 * consistent with the read content, including API signature.
149 * 145 *
150 * Return `true` if the API signature changed since the last refresh. 146 * Return `true` if the API signature changed since the last refresh.
151 */ 147 */
(...skipping 28 matching lines...) Expand all
180 signature.addBytes(contentBytes); 176 signature.addBytes(contentBytes);
181 unlinkedKey = '${signature.toHex()}.unlinked'; 177 unlinkedKey = '${signature.toHex()}.unlinked';
182 } 178 }
183 179
184 // Prepare bytes of the unlinked bundle - existing or new. 180 // Prepare bytes of the unlinked bundle - existing or new.
185 List<int> bytes; 181 List<int> bytes;
186 { 182 {
187 bytes = _fsState._byteStore.get(unlinkedKey); 183 bytes = _fsState._byteStore.get(unlinkedKey);
188 if (bytes == null) { 184 if (bytes == null) {
189 CompilationUnit unit = 185 CompilationUnit unit =
190 _parse(_source, _content, _fsState._analysisOptions); 186 _parse(source, _content, _fsState._analysisOptions);
191 _fsState._logger.run('Create unlinked for $path', () { 187 _fsState._logger.run('Create unlinked for $path', () {
192 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit); 188 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
193 bytes = unlinkedUnit.toBuffer(); 189 bytes = unlinkedUnit.toBuffer();
194 _fsState._byteStore.put(unlinkedKey, bytes); 190 _fsState._byteStore.put(unlinkedKey, bytes);
195 }); 191 });
196 } 192 }
197 } 193 }
198 194
199 // Read the unlinked bundle. 195 // Read the unlinked bundle.
200 _unlinked = new UnlinkedUnit.fromBuffer(bytes); 196 _unlinked = new UnlinkedUnit.fromBuffer(bytes);
201 _lineInfo = new LineInfo(_unlinked.lineStarts); 197 _lineInfo = new LineInfo(_unlinked.lineStarts);
202 List<int> newApiSignature = _unlinked.apiSignature; 198 List<int> newApiSignature = _unlinked.apiSignature;
203 bool apiSignatureChanged = _apiSignature != null && 199 bool apiSignatureChanged = _apiSignature != null &&
204 !_equalByteLists(_apiSignature, newApiSignature); 200 !_equalByteLists(_apiSignature, newApiSignature);
205 _apiSignature = newApiSignature; 201 _apiSignature = newApiSignature;
206 202
207 // Build the graph. 203 // Build the graph.
208 _importedFiles = <FileState>[]; 204 _importedFiles = <FileState>[];
209 _exportedFiles = <FileState>[]; 205 _exportedFiles = <FileState>[];
210 _partedFiles = <FileState>[]; 206 _partedFiles = <FileState>[];
211 for (UnlinkedImport import in _unlinked.imports) { 207 for (UnlinkedImport import in _unlinked.imports) {
212 if (!import.isImplicit) { 208 if (!import.isImplicit) {
213 String uri = import.uri; 209 String uri = import.uri;
214 if (!_isDartUri(uri)) { 210 if (!_isDartUri(uri)) {
215 FileState file = _fileForRelativeUri(uri); 211 FileState file = _fileForRelativeUri(uri);
216 _importedFiles.add(file); 212 if (file != null) {
213 _importedFiles.add(file);
214 }
217 } 215 }
218 } 216 }
219 } 217 }
220 for (UnlinkedExportPublic export in _unlinked.publicNamespace.exports) { 218 for (UnlinkedExportPublic export in _unlinked.publicNamespace.exports) {
221 String uri = export.uri; 219 String uri = export.uri;
222 if (!_isDartUri(uri)) { 220 if (!_isDartUri(uri)) {
223 FileState file = _fileForRelativeUri(uri); 221 FileState file = _fileForRelativeUri(uri);
224 _exportedFiles.add(file); 222 if (file != null) {
223 _exportedFiles.add(file);
224 }
225 } 225 }
226 } 226 }
227 for (String uri in _unlinked.publicNamespace.parts) { 227 for (String uri in _unlinked.publicNamespace.parts) {
228 if (!_isDartUri(uri)) { 228 if (!_isDartUri(uri)) {
229 FileState file = _fileForRelativeUri(uri); 229 FileState file = _fileForRelativeUri(uri);
230 _partedFiles.add(file); 230 if (file != null) {
231 _partedFiles.add(file);
232 }
231 } 233 }
232 } 234 }
233 235
234 // Compute direct dependencies. 236 // Compute direct dependencies.
235 _dependencies = (new Set<FileState>() 237 _dependencies = (new Set<FileState>()
236 ..addAll(_importedFiles) 238 ..addAll(_importedFiles)
237 ..addAll(_exportedFiles) 239 ..addAll(_exportedFiles)
238 ..addAll(_partedFiles)) 240 ..addAll(_partedFiles))
239 .toList(); 241 .toList();
240 242
241 // Return whether the API signature changed. 243 // Return whether the API signature changed.
242 return apiSignatureChanged; 244 return apiSignatureChanged;
243 } 245 }
244 246
245 @override 247 @override
246 String toString() => path; 248 String toString() => path;
247 249
248 /** 250 /**
249 * Return the [FileState] for the given [relativeUri]. 251 * Return the [FileState] for the given [relativeUri].
250 */ 252 */
251 FileState _fileForRelativeUri(String relativeUri) { 253 FileState _fileForRelativeUri(String relativeUri) {
252 Uri absoluteUri = resolveRelativeUri(uri, FastUri.parse(relativeUri)); 254 Uri absoluteUri = resolveRelativeUri(uri, FastUri.parse(relativeUri));
253 String absolutePath = _fsState._sourceFactory 255 return _fsState.getFileForUri(absoluteUri);
254 .resolveUri(null, absoluteUri.toString())
255 .fullName;
256 return _fsState.getFile(absolutePath, absoluteUri);
257 } 256 }
258 257
259 /** 258 /**
260 * Return `true` if the given byte lists are equal. 259 * Return `true` if the given byte lists are equal.
261 */ 260 */
262 static bool _equalByteLists(List<int> a, List<int> b) { 261 static bool _equalByteLists(List<int> a, List<int> b) {
263 if (a == null) { 262 if (a == null) {
264 return b == null; 263 return b == null;
265 } else if (b == null) { 264 } else if (b == null) {
266 return false; 265 return false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 */ 305 */
307 class FileSystemState { 306 class FileSystemState {
308 final PerformanceLog _logger; 307 final PerformanceLog _logger;
309 final ResourceProvider _resourceProvider; 308 final ResourceProvider _resourceProvider;
310 final ByteStore _byteStore; 309 final ByteStore _byteStore;
311 final FileContentOverlay _contentOverlay; 310 final FileContentOverlay _contentOverlay;
312 final SourceFactory _sourceFactory; 311 final SourceFactory _sourceFactory;
313 final AnalysisOptions _analysisOptions; 312 final AnalysisOptions _analysisOptions;
314 final Uint32List _salt; 313 final Uint32List _salt;
315 314
316 final Map<String, FileState> _pathToFile = <String, FileState>{}; 315 /**
316 * Mapping from a URI to the corresponding [FileState].
317 */
318 final Map<Uri, FileState> _uriToFile = {};
319
320 /**
321 * Mapping from a path to the corresponding [FileState]s, canonical or not.
322 */
323 final Map<String, List<FileState>> _pathToFiles = {};
324
325 /**
326 * Mapping from a path to the corresponding canonical [FileState].
327 */
328 final Map<String, FileState> _pathToCanonicalFile = {};
317 329
318 FileSystemState( 330 FileSystemState(
319 this._logger, 331 this._logger,
320 this._byteStore, 332 this._byteStore,
321 this._contentOverlay, 333 this._contentOverlay,
322 this._resourceProvider, 334 this._resourceProvider,
323 this._sourceFactory, 335 this._sourceFactory,
324 this._analysisOptions, 336 this._analysisOptions,
325 this._salt); 337 this._salt);
326 338
327 /** 339 /**
328 * Return the [FileState] for the give [path]. The returned file has the 340 * Return the canonical [FileState] for the given absolute [path]. The
329 * last known state since if was last refreshed. 341 * returned file has the last known state since if was last refreshed.
342 *
343 * Here "canonical" means that if the [path] is in a package `lib` then the
344 * returned file will have the `package:` style URI.
330 */ 345 */
331 FileState getFile(String path, [Uri uri]) { 346 FileState getFileForPath(String path) {
332 FileState file = _pathToFile[path]; 347 FileState file = _pathToCanonicalFile[path];
333 if (file == null) { 348 if (file == null) {
334 uri ??= _uriForPath(path); 349 File resource = _resourceProvider.getFile(path);
335 file = new FileState(this, path, uri); 350 Source fileSource = resource.createSource();
336 _pathToFile[path] = file; 351 Uri uri = _sourceFactory.restoreUri(fileSource);
352 // Try to get the existing instance.
353 file = _uriToFile[uri];
354 // If we have a file, call it the canonical one and return it.
355 if (file != null) {
356 _pathToCanonicalFile[path] = file;
357 return file;
358 }
359 // Create a new file.
360 FileSource uriSource = new FileSource(resource, uri);
361 file = new FileState._(this, path, uri, uriSource);
362 _uriToFile[uri] = file;
363 _pathToFiles.putIfAbsent(path, () => <FileState>[]).add(file);
364 _pathToCanonicalFile[path] = file;
337 file.refresh(); 365 file.refresh();
338 } 366 }
339 return file; 367 return file;
340 } 368 }
341 369
342 /** 370 /**
343 * Return the default [Uri] for the given path in [_sourceFactory]. 371 * Return the [FileState] for the given absolute [uri]. May return `null` if
372 * the [uri] is invalid, e.g. a `package:` URI without a package name. The
373 * returned file has the last known state since if was last refreshed.
344 */ 374 */
345 Uri _uriForPath(String path) { 375 FileState getFileForUri(Uri uri) {
346 Source fileSource = _resourceProvider.getFile(path).createSource(); 376 FileState file = _uriToFile[uri];
347 return _sourceFactory.restoreUri(fileSource); 377 if (file == null) {
378 Source uriSource = _sourceFactory.resolveUri(null, uri.toString());
379 // If the URI is invalid, for example package:/test/d.dart (note the
380 // leading '/'), then `null` is returned. We should ignore this URI.
381 if (uriSource == null) {
382 return null;
383 }
384 String path = uriSource.fullName;
385 File resource = _resourceProvider.getFile(path);
386 FileSource source = new FileSource(resource, uri);
387 file = new FileState._(this, path, uri, source);
388 _uriToFile[uri] = file;
389 _pathToFiles.putIfAbsent(path, () => <FileState>[]).add(file);
390 file.refresh();
391 }
392 return file;
393 }
394
395 /**
396 * Return the list of all [FileState]s corresponding to the given [path]. The
397 * list has at least one item, and the first item is the canonical file.
398 */
399 List<FileState> getFilesForPath(String path) {
400 FileState canonicalFile = getFileForPath(path);
401 List<FileState> allFiles = _pathToFiles[path].toList();
402 if (allFiles.length == 1) {
403 return allFiles;
404 }
405 return allFiles
406 ..remove(canonicalFile)
407 ..insert(0, canonicalFile);
348 } 408 }
349 } 409 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/analysis/driver.dart ('k') | pkg/analyzer/test/src/dart/analysis/driver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698