Chromium Code Reviews| 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 { |