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 85d2b396364d69ed68c2b01e52a6b9f107509ceb..e009131b80dfd8d73e7e03b09bf11648019260ff 100644 |
| --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart |
| +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart |
| @@ -236,7 +236,8 @@ class AnalysisDriver { |
| for (String path in _priorityFiles) { |
| if (_filesToAnalyze.remove(path)) { |
| _File file = _fileForPath(path); |
| - AnalysisResult result = _computeAnalysisResult(file); |
| + AnalysisResult result = |
| + _computeAnalysisResult(file, withUnit: true); |
| yield result; |
| break; |
| } |
| @@ -252,7 +253,7 @@ class AnalysisDriver { |
| if (_filesToAnalyze.isNotEmpty) { |
| String path = _removeFirst(_filesToAnalyze); |
| _File file = _fileForPath(path); |
| - AnalysisResult result = _computeAnalysisResult(file); |
| + AnalysisResult result = _computeAnalysisResult(file, withUnit: false); |
| yield result; |
| // Repeat the processing loop. |
| _hasWork.notify(); |
| @@ -366,10 +367,32 @@ class AnalysisDriver { |
| /** |
| * Compute the [AnalysisResult] for the [file]. |
| + * |
| + * The result will have the fully resolved unit only if [withUnit] is `true`. |
| */ |
| - AnalysisResult _computeAnalysisResult(_File file) { |
| + AnalysisResult _computeAnalysisResult(_File file, {bool withUnit: false}) { |
| + // If we don't need to the fully resolved unit, check for a cached result. |
| + if (!withUnit) { |
| + AnalysisResult result = _getCachedAnalysisResult(file); |
| + if (result != null) { |
| + return result; |
| + } |
| + } |
| + |
| + // We need the fully resolved unit, or the result is not cached. |
| return _logger.run('Compute analysis result for $file', () { |
| _LibraryContext libraryContext = _createLibraryContext(file); |
| + |
| + // We recomputed the dependency hash, and we might have a cached result. |
| + if (!withUnit) { |
|
Paul Berry
2016/10/31 17:02:53
AFAICT this block will never execute, since the sa
scheglov
2016/10/31 17:07:06
Both this block and the block in lines 375-380 use
Paul Berry
2016/10/31 21:35:34
Ok, I understand now. Thanks.
|
| + AnalysisResult result = _getCachedAnalysisResult(file); |
| + if (result != null) { |
| + _logger.writeln('Return the cached analysis result.'); |
| + return result; |
| + } |
| + } |
| + |
| + // Still no result, compute and store it. |
| AnalysisContext analysisContext = _createAnalysisContext(libraryContext); |
| try { |
| analysisContext.setContents(file.source, file.content); |
| @@ -377,6 +400,25 @@ class AnalysisDriver { |
| CompilationUnit resolvedUnit = |
| analysisContext.resolveCompilationUnit2(file.source, file.source); |
| List<AnalysisError> errors = analysisContext.computeErrors(file.source); |
| + |
| + // Store the result into the cache. |
| + { |
| + List<int> bytes = new AnalysisDriverResolvedUnitBuilder( |
| + errors: errors |
| + .map((error) => new AnalysisDriverUnitErrorBuilder( |
| + offset: error.offset, |
| + length: error.length, |
| + uniqueName: error.errorCode.uniqueName, |
| + message: error.message, |
| + correction: error.correction)) |
| + .toList()) |
| + .toBuffer(); |
| + String key = _getResolvedUnitKey(file); |
| + _byteStore.put(key, bytes); |
| + } |
| + |
| + // Return the full result. |
| + _logger.writeln('Computed new analysis result.'); |
| return new AnalysisResult(file.path, file.uri, file.content, |
| file.contentHash, resolvedUnit, errors); |
| } finally { |
| @@ -527,6 +569,47 @@ class AnalysisDriver { |
| } |
| /** |
| + * If we know the dependency signature for the [file], try to load the |
| + * analysis result from the cache. Return `null` if not found. |
| + */ |
| + AnalysisResult _getCachedAnalysisResult(_File file) { |
| + String key = _getResolvedUnitKey(file); |
| + if (key != null) { |
| + List<int> bytes = _byteStore.get(key); |
| + if (bytes != null) { |
| + var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes); |
| + List<AnalysisError> errors = unit.errors |
| + .map((error) => new AnalysisError.forValues( |
| + file.source, |
| + error.offset, |
| + error.length, |
| + ErrorCode.byUniqueName(error.uniqueName), |
| + error.message, |
| + error.correction)) |
| + .toList(); |
| + return new AnalysisResult( |
| + file.path, file.uri, null, file.contentHash, null, errors); |
| + } |
| + } |
| + return null; |
| + } |
| + |
| + /** |
| + * Return the key to store fully resolved results for the [file] into the |
| + * cache. Return `null` if the dependency signature is not known yet. |
| + */ |
| + String _getResolvedUnitKey(_File file) { |
| + String dependencyHash = _dependencySignatureMap[file.uri]; |
| + if (dependencyHash != null) { |
| + ApiSignature signature = new ApiSignature(); |
| + signature.addString(dependencyHash); |
| + signature.addString(file.contentHash); |
| + return '${signature.toHex()}.resolved'; |
| + } |
| + return null; |
| + } |
| + |
| + /** |
| * Verify the API signature for the file with the given [path], and decide |
| * which linked libraries should be invalidated, and files reanalyzed. |
| * |