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

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

Issue 2673683003: Split core file tracking functionality from AnalysisDriver. (Closed)
Patch Set: Created 3 years, 10 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:collection';
6 import 'dart:typed_data';
7
8 import 'package:analyzer/file_system/file_system.dart';
9 import 'package:analyzer/src/dart/analysis/byte_store.dart';
10 import 'package:analyzer/src/dart/analysis/driver.dart';
11 import 'package:analyzer/src/dart/analysis/file_state.dart';
12 import 'package:analyzer/src/generated/engine.dart';
13 import 'package:analyzer/src/generated/source.dart';
14
15 /**
16 * Callback used by [FileTracker] to report to its client that files have been
17 * added, changed, or removed, and therefore more analysis may be necessary.
18 */
19 typedef void FileTrackerChangeHook();
20
21 /**
22 * Maintains the file system state needed by the analysis driver, as well as
23 * information about files that have changed and the impact of those changes.
24 *
25 * Three related sets of files are tracked: "added files" is the set of files
26 * for which the client would like analysis. "changed files" is the set of
27 * files which is known to have changed, but for which we have not yet measured
28 * the impact of the change. "pending files" is the subset of "added files"
29 * which have been impacted by a change, and thus need analysis.
scheglov 2017/02/02 21:52:17 It is more precise to say "might have been impacte
Paul Berry 2017/02/02 22:22:19 Done.
30 *
31 * Provides methods for updating the file system state in response to changes.
32 */
33 class FileTracker {
34 /**
35 * Callback invoked whenever a change occurs that may require the client to
36 * perform analysis.
37 */
38 final FileTrackerChangeHook _changeHook;
39
40 /**
41 * The logger to write performed operations and performance to.
42 */
43 final PerformanceLog logger;
44
45 /**
46 * The current file system state.
47 */
48 final FileSystemState fsState;
49
50 /**
51 * The set of added files.
52 */
53 final addedFiles = new LinkedHashSet<String>();
54
55 /**
56 * The set of files were reported as changed through [changeFile] and not
57 * checked for actual changes yet.
58 */
59 final _changedFiles = new LinkedHashSet<String>();
60
61 /**
62 * The set of files that are currently scheduled for analysis.
63 */
64 final _pendingFiles = new LinkedHashSet<String>();
65
66 FileTracker(
67 this.logger,
68 ByteStore byteStore,
69 FileContentOverlay contentOverlay,
70 ResourceProvider resourceProvider,
71 SourceFactory sourceFactory,
72 AnalysisOptions analysisOptions,
73 Uint32List salt,
74 this._changeHook)
75 : fsState = new FileSystemState(logger, byteStore, contentOverlay,
76 resourceProvider, sourceFactory, analysisOptions, salt);
77
78 /**
79 * Returns the path to exactly one that needs analysis. Throws a [StateError]
80 * if no files need analysis.
81 */
82 String get anyPendingFile => _pendingFiles.first;
83
84 /**
85 * Returns a boolean indicating whether there are any files that have changed,
86 * but for which the impact of the changes hasn't been measured.
87 */
88 bool get hasChangedFiles => _changedFiles.isNotEmpty;
89
90 /**
91 * Returns a boolean indicating whether there are any files that need
92 * analysis.
93 */
94 bool get hasPendingFiles => _pendingFiles.isNotEmpty;
95
96 /**
97 * Returns a count of how many files need analysis.
98 */
99 int get numberOfPendingFiles => _pendingFiles.length;
100
101 /**
102 * Adds the given [path] to the set of "added files".
103 */
104 void addFile(String path) {
105 addedFiles.add(path);
106 _pendingFiles.add(path);
107 _changeHook();
108 }
109
110 /**
111 * Adds the given [paths] to the set of "added files".
112 */
113 void addFiles(Iterable<String> paths) {
114 addedFiles.addAll(paths);
115 _pendingFiles.addAll(paths);
116 _changeHook();
117 }
118
119 /**
120 * Adds the given [path] to the set of "changed files".
121 */
122 void changeFile(String path) {
123 _changedFiles.add(path);
124 if (addedFiles.contains(path)) {
125 _pendingFiles.add(path);
126 }
127 _changeHook();
128 }
129
130 /**
131 * Removes the given [path] from the set of "pending files".
132 *
133 * Should be called after the client has analyzed a file.
134 */
135 void fileWasAnalyzed(String path) {
136 _pendingFiles.remove(path);
137 }
138
139 /**
140 * Returns a boolean indicating whether the given [path] points to a file that
141 * requires analysis.
142 */
143 bool isFilePending(String path) => _pendingFiles.contains(path);
144
145 /**
146 * Removes the given [path] from the set of "added files".
147 */
148 void removeFile(String path) {
149 addedFiles.remove(path);
150 _pendingFiles.remove(path);
151 // TODO(paulberry): removing the path from [fsState] and re-analyzing all
152 // files seems extreme.
153 fsState.removeFile(path);
154 _pendingFiles.addAll(addedFiles);
155 _changeHook();
156 }
157
158 /**
159 * Verify the API signature for the file with the given [path], and decide
160 * which linked libraries should be invalidated, and files reanalyzed.
161 */
162 FileState verifyApiSignature(String path) {
163 return logger.run('Verify API signature of $path', () {
164 bool anyApiChanged = false;
165 List<FileState> files = fsState.getFilesForPath(path);
166 for (FileState file in files) {
167 bool apiChanged = file.refresh();
168 if (apiChanged) {
169 anyApiChanged = true;
170 }
171 }
172 if (anyApiChanged) {
173 logger.writeln('API signatures mismatch found for $path');
174 // TODO(scheglov) schedule analysis of only affected files
175 _pendingFiles.addAll(addedFiles);
176 }
177 return files[0];
178 });
179 }
180
181 /**
182 * If at least one file is in the "changed files" set, determines the impact
183 * of the change, updates the set of pending files, and returns `true`.
184 *
185 * If no files are in the "changed files" set, returns `false`.
186 */
187 bool verifyChangedFilesIfNeeded() {
188 // Verify all changed files one at a time.
189 if (_changedFiles.isNotEmpty) {
190 String path = _changedFiles.first;
191 _changedFiles.remove(path);
192 // If the file has not been accessed yet, we either will eventually read
193 // it later while analyzing one of the added files, or don't need it.
194 if (fsState.knownFilePaths.contains(path)) {
195 verifyApiSignature(path);
196 }
197 return true;
198 }
199 return false;
200 }
201 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698