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 ae45c70c09cccf861605f9a200ff9f5f2266d356..23036cbfbfdac4b4b18244af976cba1d633b49fb 100644 |
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart |
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart |
@@ -568,7 +568,13 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
Future<ErrorsResult> getErrors(String path) async { |
// Ask the analysis result without unit, so return cached errors. |
// If no cached analysis result, it will be computed. |
- AnalysisResult analysisResult = _computeAnalysisResult(path); |
+ AnalysisResult analysisResult = await _computeAnalysisResult(path); |
+ |
+ // Check for asynchronous changes during computing the result. |
+ _runTestAsyncWorkDuringAnalysis(path); |
Brian Wilkerson
2017/08/25 19:44:12
Missing await?
Also, could we document when we ne
|
+ if (_fileTracker.hasChangedFiles) { |
+ analysisResult = null; |
+ } |
Brian Wilkerson
2017/08/25 19:44:12
And when do we need to check for changed files, an
scheglov
2017/08/25 19:51:56
I added comments to `_runTestAsyncWorkDuringAnalys
|
// If not computed yet, because a part file without a known library, |
// we have to compute the full analysis result, with the unit. |
@@ -806,7 +812,13 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
if (_requestedFiles.isNotEmpty) { |
String path = _requestedFiles.keys.first; |
try { |
- AnalysisResult result = _computeAnalysisResult(path, withUnit: true); |
+ AnalysisResult result = |
+ await _computeAnalysisResult(path, withUnit: true); |
+ // Check for asynchronous changes during computing the result. |
+ await _runTestAsyncWorkDuringAnalysis(path); |
+ if (_fileTracker.hasChangedFiles) { |
+ return; |
+ } |
// If a part without a library, delay its analysis. |
if (result == null) { |
_requestedParts |
@@ -833,7 +845,7 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
// Process an index request. |
if (_indexRequestedFiles.isNotEmpty) { |
String path = _indexRequestedFiles.keys.first; |
- AnalysisDriverUnitIndex index = _computeIndex(path); |
+ AnalysisDriverUnitIndex index = await _computeIndex(path); |
_indexRequestedFiles.remove(path).forEach((completer) { |
completer.complete(index); |
}); |
@@ -853,7 +865,7 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
// Process a unit element request. |
if (_unitElementRequestedFiles.isNotEmpty) { |
String path = _unitElementRequestedFiles.keys.first; |
- UnitElementResult result = _computeUnitElement(path); |
+ UnitElementResult result = await _computeUnitElement(path); |
_unitElementRequestedFiles.remove(path).forEach((completer) { |
completer.complete(result); |
}); |
@@ -897,7 +909,8 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
if (_fileTracker.isFilePending(path)) { |
try { |
AnalysisResult result = |
- _computeAnalysisResult(path, withUnit: true); |
+ await _computeAnalysisResult(path, withUnit: true); |
+ await _runTestAsyncWorkDuringAnalysis(path); |
if (result == null) { |
_partsToAnalyze.add(path); |
} else { |
@@ -917,8 +930,9 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
if (_fileTracker.hasPendingFiles) { |
String path = _fileTracker.anyPendingFile; |
try { |
- AnalysisResult result = _computeAnalysisResult(path, |
+ AnalysisResult result = await _computeAnalysisResult(path, |
withUnit: false, skipIfSameSignature: true); |
+ await _runTestAsyncWorkDuringAnalysis(path); |
if (result == null) { |
_partsToAnalyze.add(path); |
} else if (result == AnalysisResult._UNCHANGED) { |
@@ -940,8 +954,12 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
if (_requestedParts.isNotEmpty) { |
String path = _requestedParts.keys.first; |
try { |
- AnalysisResult result = _computeAnalysisResult(path, |
+ AnalysisResult result = await _computeAnalysisResult(path, |
withUnit: true, asIsIfPartWithoutLibrary: true); |
+ // Check for asynchronous changes during computing the result. |
+ if (_fileTracker.hasChangedFiles) { |
+ return; |
+ } |
// Notify the completers. |
_requestedParts.remove(path).forEach((completer) { |
completer.complete(result); |
@@ -963,7 +981,7 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
String path = _partsToAnalyze.first; |
_partsToAnalyze.remove(path); |
try { |
- AnalysisResult result = _computeAnalysisResult(path, |
+ AnalysisResult result = await _computeAnalysisResult(path, |
withUnit: _priorityFiles.contains(path), |
asIsIfPartWithoutLibrary: true); |
_resultController.add(result); |
@@ -1021,10 +1039,10 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
* the resolved signature of the file in its library is the same as the one |
* that was the most recently produced to the client. |
*/ |
- AnalysisResult _computeAnalysisResult(String path, |
+ Future<AnalysisResult> _computeAnalysisResult(String path, |
{bool withUnit: false, |
bool asIsIfPartWithoutLibrary: false, |
- bool skipIfSameSignature: false}) { |
+ bool skipIfSameSignature: false}) async { |
FileState file = _fsState.getFileForPath(path); |
// Prepare the library - the file itself, or the known library. |
@@ -1060,9 +1078,9 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
} |
// We need the fully resolved unit, or the result is not cached. |
- return _logger.run('Compute analysis result for $path', () { |
+ return _logger.runAsync('Compute analysis result for $path', () async { |
try { |
- LibraryContext libraryContext = _createLibraryContext(library); |
+ LibraryContext libraryContext = await _createLibraryContext(library); |
try { |
_testView.numOfAnalyzedLibraries++; |
LibraryAnalyzer analyzer = new LibraryAnalyzer( |
@@ -1116,18 +1134,18 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
}); |
} |
- AnalysisDriverUnitIndex _computeIndex(String path) { |
- AnalysisResult analysisResult = _computeAnalysisResult(path, |
+ Future<AnalysisDriverUnitIndex> _computeIndex(String path) async { |
+ AnalysisResult analysisResult = await _computeAnalysisResult(path, |
withUnit: false, asIsIfPartWithoutLibrary: true); |
return analysisResult._index; |
} |
- UnitElementResult _computeUnitElement(String path) { |
+ Future<UnitElementResult> _computeUnitElement(String path) async { |
FileState file = _fsState.getFileForPath(path); |
FileState library = file.library ?? file; |
// Create the AnalysisContext to resynthesize elements in. |
- LibraryContext libraryContext = _createLibraryContext(library); |
+ LibraryContext libraryContext = await _createLibraryContext(library); |
// Resynthesize the CompilationUnitElement in the context. |
try { |
@@ -1164,7 +1182,7 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
/** |
* Return the context in which the [library] should be analyzed. |
*/ |
- LibraryContext _createLibraryContext(FileState library) { |
+ Future<LibraryContext> _createLibraryContext(FileState library) async { |
_testView.numOfCreatedLibraryContexts++; |
return new LibraryContext.forSingleLibrary( |
library, |
@@ -1294,6 +1312,15 @@ class AnalysisDriver implements AnalysisDriverGeneric { |
_exceptionController.add(new ExceptionResult(path, caught, contextKey)); |
} |
+ /** |
+ * Tests need a reliable way to simulate work during analysis. |
+ */ |
+ Future _runTestAsyncWorkDuringAnalysis(String path) { |
+ var work = _testView.workToWaitAfterComputingResult; |
+ _testView.workToWaitAfterComputingResult = null; |
+ return work != null ? work(path) : null; |
Paul Berry
2017/08/25 20:01:55
I get scared when I see a method with a return typ
scheglov
2017/08/25 20:30:46
Done.
|
+ } |
+ |
/** |
* Serialize the given [resolvedUnit] errors and index into bytes. |
*/ |
@@ -1643,15 +1670,17 @@ class AnalysisDriverTestView { |
int numOfAnalyzedLibraries = 0; |
+ Future<Null> Function(String path) workToWaitAfterComputingResult; |
Paul Berry
2017/08/25 20:01:55
Would you mind adding a doc comment for this? It'
scheglov
2017/08/25 20:30:46
Done.
|
+ |
AnalysisDriverTestView(this.driver); |
FileTracker get fileTracker => driver._fileTracker; |
Map<String, AnalysisResult> get priorityResults => driver._priorityResults; |
- SummaryDataStore getSummaryStore(String libraryPath) { |
+ Future<SummaryDataStore> getSummaryStore(String libraryPath) async { |
FileState library = driver.fsState.getFileForPath(libraryPath); |
- LibraryContext libraryContext = driver._createLibraryContext(library); |
+ LibraryContext libraryContext = await driver._createLibraryContext(library); |
try { |
return libraryContext.store; |
} finally { |