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 f25ac4a2a7c2d0da0ad8a5aaec856483db413e1b..e5eb257bcbf3c6486aad7bd2f43b5320f533670e 100644 |
| --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart |
| +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart |
| @@ -7,6 +7,7 @@ import 'dart:collection'; |
| import 'dart:typed_data'; |
| import 'package:analyzer/dart/ast/ast.dart'; |
| +import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/error/error.dart'; |
| import 'package:analyzer/error/listener.dart'; |
| import 'package:analyzer/file_system/file_system.dart'; |
| @@ -25,6 +26,8 @@ import 'package:analyzer/src/summary/idl.dart'; |
| import 'package:analyzer/src/summary/link.dart'; |
| import 'package:analyzer/src/summary/package_bundle_reader.dart'; |
| import 'package:analyzer/src/summary/summarize_elements.dart'; |
| +import 'package:analyzer/src/task/dart.dart' show COMPILATION_UNIT_ELEMENT; |
| +import 'package:analyzer/task/dart.dart' show LibrarySpecificUnit; |
| /** |
| * This class computes [AnalysisResult]s for Dart files. |
| @@ -155,6 +158,12 @@ class AnalysisDriver { |
| final _referencingNameTasks = <_FilesReferencingNameTask>[]; |
| /** |
| + * The mapping from the files for which index was requested using |
| + * [getIndex] to the [Completer] to report the result. |
|
Brian Wilkerson
2016/11/28 16:59:21
"which index" --> "which an index" or "which the i
|
| + */ |
| + final _indexRequestedFiles = <String, List<Completer<IndexResult>>>{}; |
| + |
| + /** |
| * The set of files were reported as changed through [changeFile] and not |
| * checked for actual changes yet. |
| */ |
| @@ -292,6 +301,9 @@ class AnalysisDriver { |
| if (_referencingNameTasks.isNotEmpty) { |
| return AnalysisDriverPriority.referencingName; |
| } |
| + if (_indexRequestedFiles.isNotEmpty) { |
| + return AnalysisDriverPriority.getIndex; |
| + } |
| if (_priorityFiles.isNotEmpty) { |
| for (String path in _priorityFiles) { |
| if (_filesToAnalyze.contains(path)) { |
| @@ -377,6 +389,23 @@ class AnalysisDriver { |
| } |
| /** |
| + * Return a [Future] that completes with the [IndexResult] for the file with |
| + * the given [path]. |
| + */ |
| + Future<IndexResult> getIndex(String path) { |
| + if (AnalysisEngine.isDartFileName(path)) { |
| + var completer = new Completer<IndexResult>(); |
| + _indexRequestedFiles |
| + .putIfAbsent(path, () => <Completer<IndexResult>>[]) |
| + .add(completer); |
| + _statusSupport.transitionToAnalyzing(); |
| + _scheduler._notify(this); |
| + return completer.future; |
| + } |
| + return new Future.value(); |
| + } |
| + |
| + /** |
| * Return a [Future] that completes with a [AnalysisResult] for the Dart |
| * file with the given [path]. If the file is not a Dart file, the [Future] |
| * completes with `null`. |
| @@ -501,7 +530,7 @@ class AnalysisDriver { |
| String key = _getResolvedUnitKey(libraryFile, file); |
| List<int> bytes = _byteStore.get(key); |
| if (bytes != null) { |
| - return _getAnalysisResultFromBytes(file, bytes); |
| + return _getAnalysisResultFromBytes(libraryFile, file, bytes); |
| } |
| } |
| @@ -544,7 +573,7 @@ class AnalysisDriver { |
| // Return the result, full or partial. |
| _logger.writeln('Computed new analysis result.'); |
| - return _getAnalysisResultFromBytes(file, bytes, |
| + return _getAnalysisResultFromBytes(libraryFile, file, bytes, |
| content: withUnit ? file.content : null, |
| resolvedUnit: withUnit ? resolvedUnit : null); |
| } finally { |
| @@ -553,6 +582,28 @@ class AnalysisDriver { |
| }); |
| } |
| + /** |
| + * TODO(scheglov) document |
|
Paul Berry
2016/11/25 15:08:51
Would you mind adding documentation before committ
scheglov
2016/11/25 17:48:14
Done.
|
| + */ |
| + IndexResult _computeIndexResult(String path) { |
| + AnalysisResult analysisResult = _computeAnalysisResult(path, |
| + withUnit: false, asIsIfPartWithoutLibrary: true); |
| + FileState libraryFile = analysisResult._libraryFile; |
| + FileState file = analysisResult._file; |
| + |
| + // Create the AnalysisContext to resynthesize elements in. |
| + _LibraryContext libraryContext = _createLibraryContext(libraryFile); |
| + AnalysisContext analysisContext = _createAnalysisContext(libraryContext); |
| + |
| + // Resynthesize the CompilationUnitElement in the context. |
| + CompilationUnitElement unitElement = analysisContext.computeResult( |
| + new LibrarySpecificUnit(libraryFile.source, file.source), |
| + COMPILATION_UNIT_ELEMENT); |
| + |
| + // Return as IndexResult. |
| + return new IndexResult(unitElement, analysisResult._index); |
| + } |
| + |
| AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) { |
| AnalysisContextImpl analysisContext = |
| AnalysisEngine.instance.createAnalysisContext(); |
| @@ -674,7 +725,8 @@ class AnalysisDriver { |
| * Load the [AnalysisResult] for the given [file] from the [bytes]. Set |
| * optional [content] and [resolvedUnit]. |
| */ |
| - AnalysisResult _getAnalysisResultFromBytes(FileState file, List<int> bytes, |
| + AnalysisResult _getAnalysisResultFromBytes( |
| + FileState libraryFile, FileState file, List<int> bytes, |
| {String content, CompilationUnit resolvedUnit}) { |
| var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes); |
| List<AnalysisError> errors = unit.errors |
| @@ -686,8 +738,18 @@ class AnalysisDriver { |
| error.message, |
| error.correction)) |
| .toList(); |
| - return new AnalysisResult(_sourceFactory, file.path, file.uri, content, |
| - file.contentHash, file.lineInfo, resolvedUnit, errors, unit.index); |
| + return new AnalysisResult( |
| + libraryFile, |
| + file, |
| + _sourceFactory, |
| + file.path, |
| + file.uri, |
| + content, |
| + file.contentHash, |
| + file.lineInfo, |
| + resolvedUnit, |
| + errors, |
| + unit.index); |
| } |
| /** |
| @@ -735,6 +797,16 @@ class AnalysisDriver { |
| return; |
| } |
| + // Process an index request. |
| + if (_indexRequestedFiles.isNotEmpty) { |
| + String path = _indexRequestedFiles.keys.first; |
| + IndexResult result = _computeIndexResult(path); |
| + _indexRequestedFiles.remove(path).forEach((completer) { |
| + completer.complete(result); |
| + }); |
| + return; |
| + } |
| + |
| // Compute files referencing a name. |
| if (_referencingNameTasks.isNotEmpty) { |
| _FilesReferencingNameTask task = _referencingNameTasks.first; |
| @@ -841,6 +913,7 @@ enum AnalysisDriverPriority { |
| general, |
| priority, |
| referencingName, |
| + getIndex, |
| interactive |
| } |
| @@ -978,6 +1051,9 @@ class AnalysisDriverScheduler { |
| * any previously returned result, even inside of the same library. |
| */ |
| class AnalysisResult { |
| + final FileState _libraryFile; |
| + final FileState _file; |
| + |
| /** |
| * The [SourceFactory] with which the file was analyzed. |
| */ |
| @@ -1023,10 +1099,37 @@ class AnalysisResult { |
| /** |
| * The index of the unit. |
| */ |
| + final AnalysisDriverUnitIndex _index; |
| + |
| + AnalysisResult( |
| + this._libraryFile, |
| + this._file, |
| + this.sourceFactory, |
| + this.path, |
| + this.uri, |
| + this.content, |
| + this.contentHash, |
| + this.lineInfo, |
| + this.unit, |
| + this.errors, |
| + this._index); |
| +} |
| + |
| +/** |
| + * The result of indexing of a single file. |
| + */ |
| +class IndexResult { |
| + /** |
| + * The element of the file. |
| + */ |
| + final CompilationUnitElement unitElement; |
| + |
| + /** |
| + * The index of the file. |
| + */ |
| final AnalysisDriverUnitIndex index; |
| - AnalysisResult(this.sourceFactory, this.path, this.uri, this.content, |
| - this.contentHash, this.lineInfo, this.unit, this.errors, this.index); |
| + IndexResult(this.unitElement, this.index); |
| } |
| /** |