| OLD | NEW |
| 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:collection'; | 5 import 'dart:collection'; |
| 6 import 'dart:typed_data'; | |
| 7 | 6 |
| 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'; | 7 import 'package:analyzer/src/dart/analysis/driver.dart'; |
| 11 import 'package:analyzer/src/dart/analysis/file_state.dart'; | 8 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 import 'package:analyzer/src/summary/package_bundle_reader.dart'; | |
| 15 | 9 |
| 16 /** | 10 /** |
| 17 * Callback used by [FileTracker] to report to its client that files have been | 11 * Callback used by [FileTracker] to report to its client that files have been |
| 18 * added, changed, or removed, and therefore more analysis may be necessary. | 12 * added, changed, or removed, and therefore more analysis may be necessary. |
| 19 */ | 13 */ |
| 20 typedef void FileTrackerChangeHook(); | 14 typedef void FileTrackerChangeHook(); |
| 21 | 15 |
| 22 /** | 16 /** |
| 23 * Maintains the file system state needed by the analysis driver, as well as | 17 * Maintains the file system state needed by the analysis driver, as well as |
| 24 * information about files that have changed and the impact of those changes. | 18 * information about files that have changed and the impact of those changes. |
| 25 * | 19 * |
| 26 * Three related sets of files are tracked: "added files" is the set of files | 20 * Three related sets of files are tracked: "added files" is the set of files |
| 27 * for which the client would like analysis. "changed files" is the set of | 21 * for which the client would like analysis. "changed files" is the set of |
| 28 * files which is known to have changed, but for which we have not yet measured | 22 * files which is known to have changed, but for which we have not yet measured |
| 29 * the impact of the change. "pending files" is the subset of "added files" | 23 * the impact of the change. "pending files" is the subset of "added files" |
| 30 * which might have been impacted by a change, and thus need analysis. | 24 * which might have been impacted by a change, and thus need analysis. |
| 31 * | 25 * |
| 32 * Provides methods for updating the file system state in response to changes. | 26 * Provides methods for updating the file system state in response to changes. |
| 33 */ | 27 */ |
| 34 class FileTracker { | 28 class FileTracker { |
| 35 /** | 29 /** |
| 36 * Callback invoked whenever a change occurs that may require the client to | 30 * Callback invoked whenever a change occurs that may require the client to |
| 37 * perform analysis. | 31 * perform analysis. |
| 38 */ | 32 */ |
| 39 final FileTrackerChangeHook _changeHook; | 33 final FileTrackerChangeHook _changeHook; |
| 40 | 34 |
| 41 /** | 35 /** |
| 42 * The logger to write performed operations and performance to. | 36 * The logger to write performed operations and performance to. |
| 43 */ | 37 */ |
| 44 final PerformanceLog logger; | 38 final PerformanceLog _logger; |
| 45 | 39 |
| 46 /** | 40 /** |
| 47 * The current file system state. | 41 * The current file system state. |
| 48 */ | 42 */ |
| 49 final FileSystemState fsState; | 43 final FileSystemState _fsState; |
| 50 | 44 |
| 51 /** | 45 /** |
| 52 * The set of added files. | 46 * The set of added files. |
| 53 */ | 47 */ |
| 54 final addedFiles = new LinkedHashSet<String>(); | 48 final addedFiles = new LinkedHashSet<String>(); |
| 55 | 49 |
| 56 /** | 50 /** |
| 57 * The set of files were reported as changed through [changeFile] and not | 51 * The set of files were reported as changed through [changeFile] and not |
| 58 * checked for actual changes yet. | 52 * checked for actual changes yet. |
| 59 */ | 53 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 76 * error or a warning, which might be fixed by a changed file. | 70 * error or a warning, which might be fixed by a changed file. |
| 77 */ | 71 */ |
| 78 var _pendingErrorFiles = new LinkedHashSet<String>(); | 72 var _pendingErrorFiles = new LinkedHashSet<String>(); |
| 79 | 73 |
| 80 /** | 74 /** |
| 81 * The set of files that are currently scheduled for analysis, and don't | 75 * The set of files that are currently scheduled for analysis, and don't |
| 82 * have any special relation with changed files. | 76 * have any special relation with changed files. |
| 83 */ | 77 */ |
| 84 var _pendingFiles = new LinkedHashSet<String>(); | 78 var _pendingFiles = new LinkedHashSet<String>(); |
| 85 | 79 |
| 86 FileTracker( | 80 FileTracker(this._logger, this._fsState, this._changeHook); |
| 87 this.logger, | |
| 88 ByteStore byteStore, | |
| 89 FileContentOverlay contentOverlay, | |
| 90 ResourceProvider resourceProvider, | |
| 91 SourceFactory sourceFactory, | |
| 92 AnalysisOptions analysisOptions, | |
| 93 Uint32List salt, | |
| 94 SummaryDataStore externalSummaries, | |
| 95 this._changeHook) | |
| 96 : fsState = new FileSystemState(logger, byteStore, contentOverlay, | |
| 97 resourceProvider, sourceFactory, analysisOptions, salt, | |
| 98 externalSummaries: externalSummaries); | |
| 99 | 81 |
| 100 /** | 82 /** |
| 101 * Returns the path to exactly one that needs analysis. Throws a [StateError] | 83 * Returns the path to exactly one that needs analysis. Throws a [StateError] |
| 102 * if no files need analysis. | 84 * if no files need analysis. |
| 103 */ | 85 */ |
| 104 String get anyPendingFile { | 86 String get anyPendingFile { |
| 105 if (_pendingChangedFiles.isNotEmpty) { | 87 if (_pendingChangedFiles.isNotEmpty) { |
| 106 return _pendingChangedFiles.first; | 88 return _pendingChangedFiles.first; |
| 107 } | 89 } |
| 108 if (_pendingImportFiles.isNotEmpty) { | 90 if (_pendingImportFiles.isNotEmpty) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 * Removes the given [path] from the set of "added files". | 196 * Removes the given [path] from the set of "added files". |
| 215 */ | 197 */ |
| 216 void removeFile(String path) { | 198 void removeFile(String path) { |
| 217 addedFiles.remove(path); | 199 addedFiles.remove(path); |
| 218 _pendingChangedFiles.remove(path); | 200 _pendingChangedFiles.remove(path); |
| 219 _pendingImportFiles.remove(path); | 201 _pendingImportFiles.remove(path); |
| 220 _pendingErrorFiles.remove(path); | 202 _pendingErrorFiles.remove(path); |
| 221 _pendingFiles.remove(path); | 203 _pendingFiles.remove(path); |
| 222 // TODO(paulberry): removing the path from [fsState] and re-analyzing all | 204 // TODO(paulberry): removing the path from [fsState] and re-analyzing all |
| 223 // files seems extreme. | 205 // files seems extreme. |
| 224 fsState.removeFile(path); | 206 _fsState.removeFile(path); |
| 225 _pendingFiles.addAll(addedFiles); | 207 _pendingFiles.addAll(addedFiles); |
| 226 _changeHook(); | 208 _changeHook(); |
| 227 } | 209 } |
| 228 | 210 |
| 229 /** | 211 /** |
| 230 * Verify the API signature for the file with the given [path], and decide | 212 * Verify the API signature for the file with the given [path], and decide |
| 231 * which linked libraries should be invalidated, and files reanalyzed. | 213 * which linked libraries should be invalidated, and files reanalyzed. |
| 232 */ | 214 */ |
| 233 FileState verifyApiSignature(String path) { | 215 FileState verifyApiSignature(String path) { |
| 234 return logger.run('Verify API signature of $path', () { | 216 return _logger.run('Verify API signature of $path', () { |
| 235 bool anyApiChanged = false; | 217 bool anyApiChanged = false; |
| 236 List<FileState> files = fsState.getFilesForPath(path); | 218 List<FileState> files = _fsState.getFilesForPath(path); |
| 237 for (FileState file in files) { | 219 for (FileState file in files) { |
| 238 bool apiChanged = file.refresh(); | 220 bool apiChanged = file.refresh(); |
| 239 if (apiChanged) { | 221 if (apiChanged) { |
| 240 anyApiChanged = true; | 222 anyApiChanged = true; |
| 241 } | 223 } |
| 242 } | 224 } |
| 243 if (anyApiChanged) { | 225 if (anyApiChanged) { |
| 244 logger.writeln('API signatures mismatch found for $path'); | 226 _logger.writeln('API signatures mismatch found for $path'); |
| 245 // TODO(scheglov) schedule analysis of only affected files | 227 // TODO(scheglov) schedule analysis of only affected files |
| 246 var pendingChangedFiles = new LinkedHashSet<String>(); | 228 var pendingChangedFiles = new LinkedHashSet<String>(); |
| 247 var pendingImportFiles = new LinkedHashSet<String>(); | 229 var pendingImportFiles = new LinkedHashSet<String>(); |
| 248 var pendingErrorFiles = new LinkedHashSet<String>(); | 230 var pendingErrorFiles = new LinkedHashSet<String>(); |
| 249 var pendingFiles = new LinkedHashSet<String>(); | 231 var pendingFiles = new LinkedHashSet<String>(); |
| 250 | 232 |
| 251 // Add the changed file. | 233 // Add the changed file. |
| 252 if (addedFiles.contains(path)) { | 234 if (addedFiles.contains(path)) { |
| 253 pendingChangedFiles.add(path); | 235 pendingChangedFiles.add(path); |
| 254 } | 236 } |
| 255 | 237 |
| 256 // Add files that directly import the changed file. | 238 // Add files that directly import the changed file. |
| 257 for (String addedPath in addedFiles) { | 239 for (String addedPath in addedFiles) { |
| 258 FileState addedFile = fsState.getFileForPath(addedPath); | 240 FileState addedFile = _fsState.getFileForPath(addedPath); |
| 259 for (FileState changedFile in files) { | 241 for (FileState changedFile in files) { |
| 260 if (addedFile.importedFiles.contains(changedFile)) { | 242 if (addedFile.importedFiles.contains(changedFile)) { |
| 261 pendingImportFiles.add(addedPath); | 243 pendingImportFiles.add(addedPath); |
| 262 } | 244 } |
| 263 } | 245 } |
| 264 } | 246 } |
| 265 | 247 |
| 266 // Add files with errors or warnings that might be fixed. | 248 // Add files with errors or warnings that might be fixed. |
| 267 for (String addedPath in addedFiles) { | 249 for (String addedPath in addedFiles) { |
| 268 FileState addedFile = fsState.getFileForPath(addedPath); | 250 FileState addedFile = _fsState.getFileForPath(addedPath); |
| 269 if (addedFile.hasErrorOrWarning) { | 251 if (addedFile.hasErrorOrWarning) { |
| 270 pendingErrorFiles.add(addedPath); | 252 pendingErrorFiles.add(addedPath); |
| 271 } | 253 } |
| 272 } | 254 } |
| 273 | 255 |
| 274 // Add all previous pending files. | 256 // Add all previous pending files. |
| 275 pendingChangedFiles.addAll(_pendingChangedFiles); | 257 pendingChangedFiles.addAll(_pendingChangedFiles); |
| 276 pendingImportFiles.addAll(_pendingImportFiles); | 258 pendingImportFiles.addAll(_pendingImportFiles); |
| 277 pendingErrorFiles.addAll(_pendingErrorFiles); | 259 pendingErrorFiles.addAll(_pendingErrorFiles); |
| 278 pendingFiles.addAll(_pendingFiles); | 260 pendingFiles.addAll(_pendingFiles); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 296 * | 278 * |
| 297 * If no files are in the "changed files" set, returns `false`. | 279 * If no files are in the "changed files" set, returns `false`. |
| 298 */ | 280 */ |
| 299 bool verifyChangedFilesIfNeeded() { | 281 bool verifyChangedFilesIfNeeded() { |
| 300 // Verify all changed files one at a time. | 282 // Verify all changed files one at a time. |
| 301 if (_changedFiles.isNotEmpty) { | 283 if (_changedFiles.isNotEmpty) { |
| 302 String path = _changedFiles.first; | 284 String path = _changedFiles.first; |
| 303 _changedFiles.remove(path); | 285 _changedFiles.remove(path); |
| 304 // If the file has not been accessed yet, we either will eventually read | 286 // If the file has not been accessed yet, we either will eventually read |
| 305 // it later while analyzing one of the added files, or don't need it. | 287 // it later while analyzing one of the added files, or don't need it. |
| 306 if (fsState.knownFilePaths.contains(path)) { | 288 if (_fsState.knownFilePaths.contains(path)) { |
| 307 verifyApiSignature(path); | 289 verifyApiSignature(path); |
| 308 } | 290 } |
| 309 return true; | 291 return true; |
| 310 } | 292 } |
| 311 return false; | 293 return false; |
| 312 } | 294 } |
| 313 } | 295 } |
| OLD | NEW |