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

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: Create separate FileState instances for separate URIs for the same 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 the canonical URI of a path to the corresponding [FileState].
322 *
323 * Here "canonical" means that for URIs in a package `lib` we always choose
324 * the `package:` style URI.
325 */
326 final Map<String, FileState> _pathToCanonicalFile = {};
317 327
318 FileSystemState( 328 FileSystemState(
319 this._logger, 329 this._logger,
320 this._byteStore, 330 this._byteStore,
321 this._contentOverlay, 331 this._contentOverlay,
322 this._resourceProvider, 332 this._resourceProvider,
323 this._sourceFactory, 333 this._sourceFactory,
324 this._analysisOptions, 334 this._analysisOptions,
325 this._salt); 335 this._salt);
326 336
327 /** 337 /**
328 * Return the [FileState] for the give [path]. The returned file has the 338 * Return the [FileState] for the given absolute [path]. The returned file
329 * last known state since if was last refreshed. 339 * has the last known state since if was last refreshed.
330 */ 340 */
331 FileState getFile(String path, [Uri uri]) { 341 FileState getFileForPath(String path) {
332 FileState file = _pathToFile[path]; 342 FileState file = _pathToCanonicalFile[path];
333 if (file == null) { 343 if (file == null) {
334 uri ??= _uriForPath(path); 344 File resource = _resourceProvider.getFile(path);
335 file = new FileState(this, path, uri); 345 Source fileSource = resource.createSource();
336 _pathToFile[path] = file; 346 Uri uri = _sourceFactory.restoreUri(fileSource);
347 FileSource uriSource = new FileSource(resource, uri);
348 file = new FileState._(this, path, uri, uriSource);
349 _pathToCanonicalFile[path] = file;
337 file.refresh(); 350 file.refresh();
338 } 351 }
339 return file; 352 return file;
340 } 353 }
341 354
342 /** 355 /**
343 * Return the default [Uri] for the given path in [_sourceFactory]. 356 * Return the [FileState] for the given absolute [uri]. May return `null` if
357 * the [uri] is invalid, e.g. a `package:` URI without a package name. The
358 * returned file has the last known state since if was last refreshed.
344 */ 359 */
345 Uri _uriForPath(String path) { 360 FileState getFileForUri(Uri uri) {
346 Source fileSource = _resourceProvider.getFile(path).createSource(); 361 FileState file = _uriToFile[uri];
347 return _sourceFactory.restoreUri(fileSource); 362 if (file == null) {
363 Source uriSource = _sourceFactory.resolveUri(null, uri.toString());
364 // If the URI is invalid, for example package:/test/d.dart (note the
365 // leading '/'), then `null` is returned. We should ignore this URI.
366 if (uriSource == null) {
367 return null;
368 }
369 String path = uriSource.fullName;
370 File resource = _resourceProvider.getFile(path);
371 FileSource source = new FileSource(resource, uri);
372 file = new FileState._(this, path, uri, source);
373 _uriToFile[uri] = file;
374 if (uri.scheme == 'package') {
375 _pathToCanonicalFile[path] = file;
376 }
377 file.refresh();
378 }
379 return file;
348 } 380 }
349 } 381 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698