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

Unified Diff: pkg/analyzer/lib/src/dart/analysis/driver.dart

Issue 2673683003: Split core file tracking functionality from AnalysisDriver. (Closed)
Patch Set: Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/dart/analysis/driver.dart
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 4ea1d04f724271cbeafea9afc977bb30a6157cde..18149589a98050f3f2cf5e869b84caa33eebdd01 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -15,6 +15,7 @@ import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/file_tracker.dart';
import 'package:analyzer/src/dart/analysis/index.dart';
import 'package:analyzer/src/dart/analysis/library_context.dart';
import 'package:analyzer/src/dart/analysis/search.dart';
@@ -90,11 +91,6 @@ class AnalysisDriver {
final AnalysisDriverScheduler _scheduler;
/**
- * The logger to write performed operations and performance to.
- */
- final PerformanceLog _logger;
-
- /**
* The resource provider for working with files.
*/
final ResourceProvider _resourceProvider;
@@ -139,16 +135,6 @@ class AnalysisDriver {
final Uint32List _salt = new Uint32List(1 + AnalysisOptions.signatureLength);
/**
- * The current file system state.
- */
- FileSystemState _fsState;
-
- /**
- * The set of added files.
- */
- final _addedFiles = new LinkedHashSet<String>();
-
- /**
* The set of priority files, that should be analyzed sooner.
*/
final _priorityFiles = new LinkedHashSet<String>();
@@ -189,17 +175,6 @@ class AnalysisDriver {
<String, List<Completer<CompilationUnitElement>>>{};
/**
- * The set of files were reported as changed through [changeFile] and not
- * checked for actual changes yet.
- */
- final _changedFiles = new LinkedHashSet<String>();
-
- /**
- * The set of files that are currently scheduled for analysis.
- */
- final _filesToAnalyze = new LinkedHashSet<String>();
-
- /**
* The mapping from the files for which analysis was requested using
* [getResult], and which were found to be parts without known libraries,
* to the [Completer]s to report the result.
@@ -235,6 +210,11 @@ class AnalysisDriver {
AnalysisDriverTestView _testView;
/**
+ * The [FileTracker] used by this driver.
+ */
+ FileTracker _fileTracker;
+
+ /**
* Create a new instance of [AnalysisDriver].
*
* The given [SourceFactory] is cloned to ensure that it does not contain a
@@ -242,7 +222,7 @@ class AnalysisDriver {
*/
AnalysisDriver(
this._scheduler,
- this._logger,
+ PerformanceLog logger,
this._resourceProvider,
this._byteStore,
this._contentOverlay,
@@ -253,9 +233,7 @@ class AnalysisDriver {
: _sourceFactory = sourceFactory.clone(),
_sdkBundle = sdkBundle {
_testView = new AnalysisDriverTestView(this);
- _fillSalt();
- _fsState = new FileSystemState(_logger, _byteStore, _contentOverlay,
- _resourceProvider, sourceFactory, _analysisOptions, _salt);
+ _createFileTracker(logger);
_scheduler._add(this);
_search = new Search(this);
}
@@ -263,7 +241,7 @@ class AnalysisDriver {
/**
* Return the set of files explicitly added to analysis using [addFile].
*/
- Set<String> get addedFiles => _addedFiles;
+ Set<String> get addedFiles => _fileTracker.addedFiles;
/**
* Return the analysis options used to control analysis.
@@ -278,16 +256,16 @@ class AnalysisDriver {
/**
* The current file system state.
*/
- FileSystemState get fsState => _fsState;
+ FileSystemState get fsState => _fileTracker.fsState;
/**
* Return `true` if the driver has a file to analyze.
*/
bool get hasFilesToAnalyze {
- return _changedFiles.isNotEmpty ||
+ return _fileTracker.hasChangedFiles ||
_requestedFiles.isNotEmpty ||
_requestedParts.isNotEmpty ||
- _filesToAnalyze.isNotEmpty ||
+ _fileTracker.hasPendingFiles ||
_partsToAnalyze.isNotEmpty;
}
@@ -296,12 +274,12 @@ class AnalysisDriver {
* always include all added files or all implicitly used file. If a file has
* not been processed yet, it might be missing.
*/
- Set<String> get knownFiles => _fsState.knownFilePaths;
+ Set<String> get knownFiles => _fileTracker.fsState.knownFilePaths;
/**
* Return the number of files scheduled for analysis.
*/
- int get numberOfFilesToAnalyze => _filesToAnalyze.length;
+ int get numberOfFilesToAnalyze => _fileTracker.numberOfPendingFiles;
/**
* Return the list of files that the driver should try to analyze sooner.
@@ -324,7 +302,7 @@ class AnalysisDriver {
.forEach(_priorityResults.remove);
_priorityFiles.clear();
_priorityFiles.addAll(priorityPaths);
- _scheduler._notify(this);
+ _scheduler.notify(this);
}
/**
@@ -387,15 +365,15 @@ class AnalysisDriver {
}
if (_priorityFiles.isNotEmpty) {
for (String path in _priorityFiles) {
- if (_filesToAnalyze.contains(path)) {
+ if (_fileTracker.isFilePending(path)) {
return AnalysisDriverPriority.priority;
}
}
}
- if (_filesToAnalyze.isNotEmpty) {
+ if (_fileTracker.hasPendingFiles) {
return AnalysisDriverPriority.general;
}
- if (_changedFiles.isNotEmpty) {
+ if (_fileTracker.hasChangedFiles) {
return AnalysisDriverPriority.general;
}
if (_requestedParts.isNotEmpty || _partsToAnalyze.isNotEmpty) {
@@ -412,15 +390,12 @@ class AnalysisDriver {
* The results of analysis are eventually produced by the [results] stream.
*/
void addFile(String path) {
- if (!_fsState.hasUri(path)) {
+ if (!_fileTracker.fsState.hasUri(path)) {
return;
}
if (AnalysisEngine.isDartFileName(path)) {
- _addedFiles.add(path);
- _filesToAnalyze.add(path);
- _priorityResults.clear();
+ _fileTracker.addFile(path);
}
- _scheduler._notify(this);
}
/**
@@ -442,12 +417,8 @@ class AnalysisDriver {
* [changeFile] invocation.
*/
void changeFile(String path) {
- _changedFiles.add(path);
- if (_addedFiles.contains(path)) {
- _filesToAnalyze.add(path);
- }
+ _fileTracker.changeFile(path);
_priorityResults.clear();
- _scheduler._notify(this);
}
/**
@@ -465,11 +436,9 @@ class AnalysisDriver {
if (sourceFactory != null) {
_sourceFactory = sourceFactory;
}
- _fillSalt();
- _fsState = new FileSystemState(_logger, _byteStore, _contentOverlay,
- _resourceProvider, _sourceFactory, _analysisOptions, _salt);
- _filesToAnalyze.addAll(_addedFiles);
- _scheduler._notify(this);
+ var addedFiles = _fileTracker.addedFiles;
scheglov 2017/02/02 21:52:17 Type?
Paul Berry 2017/02/02 22:22:19 Done.
+ _createFileTracker(_fileTracker.logger);
+ _fileTracker.addFiles(addedFiles);
}
/**
@@ -516,7 +485,7 @@ class AnalysisDriver {
Future<List<String>> getFilesDefiningClassMemberName(String name) {
var task = new _FilesDefiningClassMemberNameTask(this, name);
_definingClassMemberNameTasks.add(task);
- _scheduler._notify(this);
+ _scheduler.notify(this);
return task.completer.future;
}
@@ -527,7 +496,7 @@ class AnalysisDriver {
Future<List<String>> getFilesReferencingName(String name) {
var task = new _FilesReferencingNameTask(this, name);
_referencingNameTasks.add(task);
- _scheduler._notify(this);
+ _scheduler.notify(this);
return task.completer.future;
}
@@ -537,14 +506,14 @@ class AnalysisDriver {
* analyzed.
*/
Future<AnalysisDriverUnitIndex> getIndex(String path) {
- if (!_fsState.hasUri(path)) {
+ if (!_fileTracker.fsState.hasUri(path)) {
return new Future.value();
}
var completer = new Completer<AnalysisDriverUnitIndex>();
_indexRequestedFiles
.putIfAbsent(path, () => <Completer<AnalysisDriverUnitIndex>>[])
.add(completer);
- _scheduler._notify(this);
+ _scheduler.notify(this);
return completer.future;
}
@@ -566,7 +535,7 @@ class AnalysisDriver {
* state transitions to "idle".
*/
Future<AnalysisResult> getResult(String path) {
- if (!_fsState.hasUri(path)) {
+ if (!_fileTracker.fsState.hasUri(path)) {
return new Future.value();
}
@@ -583,7 +552,7 @@ class AnalysisDriver {
_requestedFiles
.putIfAbsent(path, () => <Completer<AnalysisResult>>[])
.add(completer);
- _scheduler._notify(this);
+ _scheduler.notify(this);
return completer.future;
}
@@ -596,7 +565,7 @@ class AnalysisDriver {
*/
Future<SourceKind> getSourceKind(String path) async {
if (AnalysisEngine.isDartFileName(path)) {
- FileState file = _fsState.getFileForPath(path);
+ FileState file = _fileTracker.fsState.getFileForPath(path);
return file.isPart ? SourceKind.PART : SourceKind.LIBRARY;
}
return null;
@@ -610,7 +579,7 @@ class AnalysisDriver {
String name) {
var task = new _TopLevelNameDeclarationsTask(this, name);
_topLevelNameDeclarationsTasks.add(task);
- _scheduler._notify(this);
+ _scheduler.notify(this);
return task.completer.future;
}
@@ -619,14 +588,14 @@ class AnalysisDriver {
* file with the given [path], or with `null` if the file cannot be analyzed.
*/
Future<CompilationUnitElement> getUnitElement(String path) {
- if (!_fsState.hasUri(path)) {
+ if (!_fileTracker.fsState.hasUri(path)) {
return new Future.value();
}
var completer = new Completer<CompilationUnitElement>();
_unitElementRequestedFiles
.putIfAbsent(path, () => <Completer<CompilationUnitElement>>[])
.add(completer);
- _scheduler._notify(this);
+ _scheduler.notify(this);
return completer.future;
}
@@ -643,7 +612,7 @@ class AnalysisDriver {
* resolved unit).
*/
Future<ParseResult> parseFile(String path) async {
- FileState file = _verifyApiSignature(path);
+ FileState file = _fileTracker.verifyApiSignature(path);
RecordingErrorListener listener = new RecordingErrorListener();
CompilationUnit unit = file.parse(listener);
return new ParseResult(file.path, file.uri, file.content, file.contentHash,
@@ -660,12 +629,17 @@ class AnalysisDriver {
* but does not guarantee this.
*/
void removeFile(String path) {
- _addedFiles.remove(path);
- _filesToAnalyze.remove(path);
- _fsState.removeFile(path);
- _filesToAnalyze.addAll(_addedFiles);
+ _fileTracker.removeFile(path);
+ _priorityResults.clear();
+ }
+
+ /**
+ * Handles a notification from the [FileTracker] that there has been a change
+ * of state.
+ */
+ void _changeHook() {
_priorityResults.clear();
- _scheduler._notify(this);
+ _scheduler.notify(this);
}
/**
@@ -696,7 +670,7 @@ class AnalysisDriver {
// If we don't need the fully resolved unit, check for the cached result.
if (!withUnit) {
- FileState file = _fsState.getFileForPath(path);
+ FileState file = _fileTracker.fsState.getFileForPath(path);
// Prepare the library file - the file itself, or the known library.
FileState libraryFile = getLibraryFile(file);
@@ -713,8 +687,8 @@ class AnalysisDriver {
}
// We need the fully resolved unit, or the result is not cached.
- return _logger.run('Compute analysis result for $path', () {
- FileState file = _verifyApiSignature(path);
+ return _fileTracker.logger.run('Compute analysis result for $path', () {
scheglov 2017/02/02 21:52:17 Accessing logger from _fileTracker seems a bit cum
Paul Berry 2017/02/02 22:22:19 Done.
+ FileState file = _fileTracker.verifyApiSignature(path);
// Prepare the library file - the file itself, or the known library.
FileState libraryFile = getLibraryFile(file);
@@ -750,10 +724,10 @@ class AnalysisDriver {
}
// Return the result, full or partial.
- _logger.writeln('Computed new analysis result.');
+ _fileTracker.logger.writeln('Computed new analysis result.');
AnalysisResult result = _getAnalysisResultFromBytes(file, bytes,
content: withUnit ? file.content : null,
- withErrors: _addedFiles.contains(path),
+ withErrors: _fileTracker.addedFiles.contains(path),
resolvedUnit: withUnit ? resolvedUnit : null);
if (withUnit && _priorityFiles.contains(path)) {
_priorityResults[path] = result;
@@ -777,7 +751,7 @@ class AnalysisDriver {
}
CompilationUnitElement _computeUnitElement(String path) {
- FileState file = _fsState.getFileForPath(path);
+ FileState file = _fileTracker.fsState.getFileForPath(path);
FileState libraryFile = file.library ?? file;
// Create the AnalysisContext to resynthesize elements in.
@@ -792,18 +766,30 @@ class AnalysisDriver {
}
/**
+ * Creates a new [FileTracker] object and stores it in [_fileTracker].
+ *
+ * This is used both on initial construction and whenever the configuration
+ * changes.
+ */
+ void _createFileTracker(PerformanceLog logger) {
+ _fillSalt();
+ _fileTracker = new FileTracker(logger, _byteStore, _contentOverlay,
+ _resourceProvider, sourceFactory, _analysisOptions, _salt, _changeHook);
+ }
+
+ /**
* Return the context in which the [library] should be analyzed.
*/
LibraryContext _createLibraryContext(FileState library) =>
new LibraryContext.forSingleLibrary(
library,
- _logger,
+ _fileTracker.logger,
_sdkBundle,
_byteStore,
_analysisOptions,
declaredVariables,
_sourceFactory,
- _fsState);
+ _fileTracker);
/**
* Fill [_salt] with data.
@@ -896,14 +882,7 @@ class AnalysisDriver {
* Perform a single chunk of work and produce [results].
*/
Future<Null> _performWork() async {
- // Verify all changed files one at a time.
- if (_changedFiles.isNotEmpty) {
- String path = _removeFirst(_changedFiles);
- // If the file has not been accessed yet, we either will eventually read
- // it later while analyzing one of the added files, or don't need it.
- if (_fsState.knownFilePaths.contains(path)) {
- _verifyApiSignature(path);
- }
+ if (_fileTracker.verifyChangedFilesIfNeeded()) {
return;
}
@@ -924,13 +903,13 @@ class AnalysisDriver {
completer.complete(result);
});
// Remove from to be analyzed and produce it now.
- _filesToAnalyze.remove(path);
_resultController.add(result);
} catch (exception, stackTrace) {
- _filesToAnalyze.remove(path);
_requestedFiles.remove(path).forEach((completer) {
completer.completeError(exception, stackTrace);
});
+ } finally {
+ _fileTracker.fileWasAnalyzed(path);
scheglov 2017/02/02 21:52:17 This code will be executed even if result == null,
Paul Berry 2017/02/02 22:22:19 Ah, I see. Good catch. Fixed.
}
return;
}
@@ -989,7 +968,7 @@ class AnalysisDriver {
// Analyze a priority file.
if (_priorityFiles.isNotEmpty) {
for (String path in _priorityFiles) {
- if (_filesToAnalyze.remove(path)) {
+ if (_fileTracker.isFilePending(path)) {
try {
AnalysisResult result =
_computeAnalysisResult(path, withUnit: true);
@@ -1000,15 +979,17 @@ class AnalysisDriver {
}
} catch (exception, stackTrace) {
_reportException(path, exception, stackTrace);
+ } finally {
+ _fileTracker.fileWasAnalyzed(path);
}
return;
}
}
}
- // Analyze a general file.
- if (_filesToAnalyze.isNotEmpty) {
- String path = _removeFirst(_filesToAnalyze);
+ if (_fileTracker.hasPendingFiles) {
+ // Analyze a general file.
+ String path = _fileTracker.anyPendingFile;
try {
AnalysisResult result = _computeAnalysisResult(path, withUnit: false);
if (result == null) {
@@ -1018,6 +999,8 @@ class AnalysisDriver {
}
} catch (exception, stackTrace) {
_reportException(path, exception, stackTrace);
+ } finally {
+ _fileTracker.fileWasAnalyzed(path);
}
return;
}
@@ -1046,7 +1029,8 @@ class AnalysisDriver {
// Analyze a general part.
if (_partsToAnalyze.isNotEmpty) {
- String path = _removeFirst(_partsToAnalyze);
+ String path = _partsToAnalyze.first;
+ _partsToAnalyze.remove(path);
try {
AnalysisResult result = _computeAnalysisResult(path,
withUnit: _priorityFiles.contains(path),
@@ -1119,38 +1103,6 @@ class AnalysisDriver {
return null;
}
}
-
- /**
- * Verify the API signature for the file with the given [path], and decide
- * which linked libraries should be invalidated, and files reanalyzed.
- */
- FileState _verifyApiSignature(String path) {
- return _logger.run('Verify API signature of $path', () {
- bool anyApiChanged = false;
- List<FileState> files = _fsState.getFilesForPath(path);
- for (FileState file in files) {
- bool apiChanged = file.refresh();
- if (apiChanged) {
- anyApiChanged = true;
- }
- }
- if (anyApiChanged) {
- _logger.writeln('API signatures mismatch found for $path');
- // TODO(scheglov) schedule analysis of only affected files
- _filesToAnalyze.addAll(_addedFiles);
- }
- return files[0];
- });
- }
-
- /**
- * Remove and return the first item in the given [set].
- */
- static Object/*=T*/ _removeFirst/*<T>*/(LinkedHashSet<Object/*=T*/ > set) {
- Object/*=T*/ element = set.first;
- set.remove(element);
- return element;
- }
}
/**
@@ -1218,6 +1170,15 @@ class AnalysisDriverScheduler {
}
/**
+ * Notify that there is a change to the [driver], it it might need to
+ * perform some work.
+ */
+ void notify(AnalysisDriver driver) {
+ _hasWork.notify();
+ _statusSupport.preTransitionToAnalyzing();
+ }
+
+ /**
* Start the scheduler, so that any [AnalysisDriver] created before or
* after will be asked to perform work.
*/
@@ -1246,15 +1207,6 @@ class AnalysisDriverScheduler {
}
/**
- * Notify that there is a change to the [driver], it it might need to
- * perform some work.
- */
- void _notify(AnalysisDriver driver) {
- _hasWork.notify();
- _statusSupport.preTransitionToAnalyzing();
- }
-
- /**
* Remove the given [driver] from the scheduler, so that it will not be
* asked to perform any new work.
*/
@@ -1334,7 +1286,7 @@ class AnalysisDriverTestView {
AnalysisDriverTestView(this.driver);
- Set<String> get filesToAnalyze => driver._filesToAnalyze;
+ FileTracker get fileTracker => driver._fileTracker;
Map<String, AnalysisResult> get priorityResults => driver._priorityResults;
}
@@ -1672,7 +1624,7 @@ class _FilesDefiningClassMemberNameTask {
// Check the next file.
String path = filesToCheck.removeLast();
- FileState file = driver._fsState.getFileForPath(path);
+ FileState file = driver._fileTracker.fsState.getFileForPath(path);
if (file.definedClassMemberNames.contains(name)) {
definingFiles.add(path);
}
@@ -1729,7 +1681,7 @@ class _FilesReferencingNameTask {
// Check the next file.
String path = filesToCheck.removeLast();
- FileState file = driver._fsState.getFileForPath(path);
+ FileState file = driver._fileTracker.fsState.getFileForPath(path);
if (file.referencedNames.contains(name)) {
referencingFiles.add(path);
}
@@ -1779,7 +1731,7 @@ class _TopLevelNameDeclarationsTask {
// Check the next file.
String path = filesToCheck.removeLast();
if (checkedFiles.add(path)) {
- FileState file = driver._fsState.getFileForPath(path);
+ FileState file = driver._fileTracker.fsState.getFileForPath(path);
if (!file.isPart) {
bool isExported = false;
TopLevelDeclaration declaration = file.topLevelDeclarations[name];

Powered by Google App Engine
This is Rietveld 408576698