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

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

Issue 2516003003: Compute and flush sets of transitively referenced files in File[System]State. (Closed)
Patch Set: 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';
11 import 'package:analyzer/file_system/file_system.dart'; 11 import 'package:analyzer/file_system/file_system.dart';
12 import 'package:analyzer/src/dart/analysis/byte_store.dart'; 12 import 'package:analyzer/src/dart/analysis/byte_store.dart';
13 import 'package:analyzer/src/dart/analysis/driver.dart'; 13 import 'package:analyzer/src/dart/analysis/driver.dart';
14 import 'package:analyzer/src/dart/scanner/reader.dart'; 14 import 'package:analyzer/src/dart/scanner/reader.dart';
15 import 'package:analyzer/src/dart/scanner/scanner.dart'; 15 import 'package:analyzer/src/dart/scanner/scanner.dart';
16 import 'package:analyzer/src/generated/engine.dart'; 16 import 'package:analyzer/src/generated/engine.dart';
17 import 'package:analyzer/src/generated/parser.dart'; 17 import 'package:analyzer/src/generated/parser.dart';
18 import 'package:analyzer/src/generated/source.dart'; 18 import 'package:analyzer/src/generated/source.dart';
19 import 'package:analyzer/src/generated/utilities_dart.dart'; 19 import 'package:analyzer/src/generated/utilities_dart.dart';
20 import 'package:analyzer/src/source/source_resource.dart'; 20 import 'package:analyzer/src/source/source_resource.dart';
21 import 'package:analyzer/src/summary/api_signature.dart'; 21 import 'package:analyzer/src/summary/api_signature.dart';
22 import 'package:analyzer/src/summary/format.dart'; 22 import 'package:analyzer/src/summary/format.dart';
23 import 'package:analyzer/src/summary/idl.dart'; 23 import 'package:analyzer/src/summary/idl.dart';
24 import 'package:analyzer/src/summary/summarize_ast.dart'; 24 import 'package:analyzer/src/summary/summarize_ast.dart';
25 import 'package:analyzer/src/util/fast_uri.dart'; 25 import 'package:analyzer/src/util/fast_uri.dart';
26 import 'package:convert/convert.dart'; 26 import 'package:convert/convert.dart';
27 import 'package:crypto/crypto.dart'; 27 import 'package:crypto/crypto.dart';
28 import 'package:meta/meta.dart';
28 29
29 /** 30 /**
30 * [FileContentOverlay] is used to temporary override content of files. 31 * [FileContentOverlay] is used to temporary override content of files.
31 */ 32 */
32 class FileContentOverlay { 33 class FileContentOverlay {
33 final _map = <String, String>{}; 34 final _map = <String, String>{};
34 35
35 /** 36 /**
36 * Return the content of the file with the given [path], or `null` the 37 * Return the content of the file with the given [path], or `null` the
37 * overlay does not override the content of the file. 38 * overlay does not override the content of the file.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 84
84 String _content; 85 String _content;
85 String _contentHash; 86 String _contentHash;
86 LineInfo _lineInfo; 87 LineInfo _lineInfo;
87 UnlinkedUnit _unlinked; 88 UnlinkedUnit _unlinked;
88 List<int> _apiSignature; 89 List<int> _apiSignature;
89 90
90 List<FileState> _importedFiles; 91 List<FileState> _importedFiles;
91 List<FileState> _exportedFiles; 92 List<FileState> _exportedFiles;
92 List<FileState> _partedFiles; 93 List<FileState> _partedFiles;
93 List<FileState> _dependencies; 94 Set<FileState> _directReferencedFiles = new Set<FileState>();
95 Set<FileState> _transitiveFiles;
94 96
95 FileState._(this._fsState, this.path, this.uri, this.source); 97 FileState._(this._fsState, this.path, this.uri, this.source);
96 98
97 /** 99 /**
98 * The unlinked API signature of the file. 100 * The unlinked API signature of the file.
99 */ 101 */
100 List<int> get apiSignature => _apiSignature; 102 List<int> get apiSignature => _apiSignature;
101 103
102 /** 104 /**
103 * The content of the file. 105 * The content of the file.
104 */ 106 */
105 String get content => _content; 107 String get content => _content;
106 108
107 /** 109 /**
108 * The MD5 hash of the [content]. 110 * The MD5 hash of the [content].
109 */ 111 */
110 String get contentHash => _contentHash; 112 String get contentHash => _contentHash;
111 113
112 /** 114 /**
113 * Return the list of all direct dependencies. 115 * Return the set of all directly referenced files - imported, exported or
116 * parted.
114 */ 117 */
115 List<FileState> get dependencies => _dependencies; 118 Set<FileState> get directReferencedFiles => _directReferencedFiles;
116 119
117 /** 120 /**
118 * The list of files this file exports. 121 * The list of files this file exports.
119 */ 122 */
120 List<FileState> get exportedFiles => _exportedFiles; 123 List<FileState> get exportedFiles => _exportedFiles;
121 124
122 @override 125 @override
123 int get hashCode => uri.hashCode; 126 int get hashCode => uri.hashCode;
124 127
125 /** 128 /**
(...skipping 24 matching lines...) Expand all
150 * Return information about line in the file. 153 * Return information about line in the file.
151 */ 154 */
152 LineInfo get lineInfo => _lineInfo; 155 LineInfo get lineInfo => _lineInfo;
153 156
154 /** 157 /**
155 * The list of files this library file references as parts. 158 * The list of files this library file references as parts.
156 */ 159 */
157 List<FileState> get partedFiles => _partedFiles; 160 List<FileState> get partedFiles => _partedFiles;
158 161
159 /** 162 /**
163 * Return the set of transitive files - the file itself and all of the
164 * directly or indirectly referenced files.
165 */
166 Set<FileState> get transitiveFiles {
167 if (_transitiveFiles == null) {
168 _transitiveFiles = new Set<FileState>();
169
170 void appendReferenced(FileState file) {
171 if (_transitiveFiles.add(file)) {
172 file._directReferencedFiles.forEach(appendReferenced);
173 }
174 }
175
176 appendReferenced(this);
177 }
178 return _transitiveFiles;
179 }
180
181 /**
160 * The [UnlinkedUnit] of the file. 182 * The [UnlinkedUnit] of the file.
161 */ 183 */
162 UnlinkedUnit get unlinked => _unlinked; 184 UnlinkedUnit get unlinked => _unlinked;
163 185
164 @override 186 @override
165 bool operator ==(Object other) { 187 bool operator ==(Object other) {
166 return other is FileState && other.uri == uri; 188 return other is FileState && other.uri == uri;
167 } 189 }
168 190
169 /** 191 /**
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 if (file != null) { 304 if (file != null) {
283 _partedFiles.add(file); 305 _partedFiles.add(file);
284 // TODO(scheglov) Sort for stable results? 306 // TODO(scheglov) Sort for stable results?
285 _fsState._partToLibraries 307 _fsState._partToLibraries
286 .putIfAbsent(file, () => <FileState>[]) 308 .putIfAbsent(file, () => <FileState>[])
287 .add(this); 309 .add(this);
288 } 310 }
289 } 311 }
290 } 312 }
291 313
292 // Compute direct dependencies. 314 // Compute referenced files.
293 _dependencies = (new Set<FileState>() 315 Set<FileState> oldDirectReferencedFiles = _directReferencedFiles;
294 ..addAll(_importedFiles) 316 _directReferencedFiles = new Set<FileState>()
295 ..addAll(_exportedFiles) 317 ..addAll(_importedFiles)
296 ..addAll(_partedFiles)) 318 ..addAll(_exportedFiles)
297 .toList(); 319 ..addAll(_partedFiles);
320
321 // If the set of directly referenced files of this file is changed,
322 // then the transitive sets of files that include this file are also
323 // changed. Reset these transitive sets.
324 if (_directReferencedFiles.length != oldDirectReferencedFiles.length ||
325 !_directReferencedFiles.containsAll(oldDirectReferencedFiles)) {
326 for (FileState file in _fsState._uriToFile.values) {
327 if (file._transitiveFiles != null &&
328 file._transitiveFiles.contains(this)) {
329 file._transitiveFiles = null;
330 }
331 }
332 }
298 333
299 // Return whether the API signature changed. 334 // Return whether the API signature changed.
300 return apiSignatureChanged; 335 return apiSignatureChanged;
301 } 336 }
302 337
303 @override 338 @override
304 String toString() => path; 339 String toString() => path;
305 340
306 /** 341 /**
307 * Return the [FileState] for the given [relativeUri]. 342 * Return the [FileState] for the given [relativeUri].
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 /** 396 /**
362 * Mapping from a path to the corresponding canonical [FileState]. 397 * Mapping from a path to the corresponding canonical [FileState].
363 */ 398 */
364 final Map<String, FileState> _pathToCanonicalFile = {}; 399 final Map<String, FileState> _pathToCanonicalFile = {};
365 400
366 /** 401 /**
367 * Mapping from a part to the libraries it is a part of. 402 * Mapping from a part to the libraries it is a part of.
368 */ 403 */
369 final Map<FileState, List<FileState>> _partToLibraries = {}; 404 final Map<FileState, List<FileState>> _partToLibraries = {};
370 405
406 FileSystemStateTestView _testView;
407
371 FileSystemState( 408 FileSystemState(
372 this._logger, 409 this._logger,
373 this._byteStore, 410 this._byteStore,
374 this._contentOverlay, 411 this._contentOverlay,
375 this._resourceProvider, 412 this._resourceProvider,
376 this._sourceFactory, 413 this._sourceFactory,
377 this._analysisOptions, 414 this._analysisOptions,
378 this._salt); 415 this._salt) {
416 _testView = new FileSystemStateTestView(this);
417 }
379 418
380 /** 419 /**
381 * Return the set of known files. 420 * Return the set of known files.
382 */ 421 */
383 Set<String> get knownFiles => _pathToFiles.keys.toSet(); 422 Set<String> get knownFiles => _pathToFiles.keys.toSet();
384 423
424 @visibleForTesting
425 FileSystemStateTestView get test => _testView;
426
385 /** 427 /**
386 * Return the canonical [FileState] for the given absolute [path]. The 428 * Return the canonical [FileState] for the given absolute [path]. The
387 * returned file has the last known state since if was last refreshed. 429 * returned file has the last known state since if was last refreshed.
388 * 430 *
389 * Here "canonical" means that if the [path] is in a package `lib` then the 431 * Here "canonical" means that if the [path] is in a package `lib` then the
390 * returned file will have the `package:` style URI. 432 * returned file will have the `package:` style URI.
391 */ 433 */
392 FileState getFileForPath(String path) { 434 FileState getFileForPath(String path) {
393 FileState file = _pathToCanonicalFile[path]; 435 FileState file = _pathToCanonicalFile[path];
394 if (file == null) { 436 if (file == null) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 FileState canonicalFile = getFileForPath(path); 488 FileState canonicalFile = getFileForPath(path);
447 List<FileState> allFiles = _pathToFiles[path].toList(); 489 List<FileState> allFiles = _pathToFiles[path].toList();
448 if (allFiles.length == 1) { 490 if (allFiles.length == 1) {
449 return allFiles; 491 return allFiles;
450 } 492 }
451 return allFiles 493 return allFiles
452 ..remove(canonicalFile) 494 ..remove(canonicalFile)
453 ..insert(0, canonicalFile); 495 ..insert(0, canonicalFile);
454 } 496 }
455 } 497 }
498
499 @visibleForTesting
500 class FileSystemStateTestView {
501 final FileSystemState state;
502
503 FileSystemStateTestView(this.state);
504
505 Set<FileState> get filesWithoutTransitive {
506 return state._uriToFile.values
507 .where((f) => f._transitiveFiles == null)
508 .toSet();
509 }
510 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/analysis/driver.dart ('k') | pkg/analyzer/test/src/dart/analysis/file_state_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698