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

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

Issue 2757753002: Migrate DDC to the new analysis driver.
Patch Set: Created 3 years, 9 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 fd2e61b1011cac59cd8b34c933002ddaf1becf9b..c013c6f0f6a54848f496b0dc58b84c36ad6bb724 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -8,7 +8,8 @@ import 'dart:typed_data';
import 'package:analyzer/context/declared_variables.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement;
+import 'package:analyzer/dart/element/element.dart'
+ show CompilationUnitElement, LibraryElement;
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
@@ -29,6 +30,7 @@ import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/summary/api_signature.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:meta/meta.dart';
/**
@@ -109,6 +111,11 @@ class AnalysisDriver implements AnalysisDriverGeneric {
final ByteStore _byteStore;
/**
+ * TODO(scheglov) document
+ */
+ final SummaryDataStore externalSummaries;
+
+ /**
* This [ContentCache] is consulted for a file content before reading
* the content from the file.
*/
@@ -236,6 +243,8 @@ class AnalysisDriver implements AnalysisDriverGeneric {
*/
FileTracker _fileTracker;
+ final _cachedResults = {};
+
/**
* Create a new instance of [AnalysisDriver].
*
@@ -252,10 +261,12 @@ class AnalysisDriver implements AnalysisDriverGeneric {
SourceFactory sourceFactory,
this._analysisOptions,
{PackageBundle sdkBundle,
- this.analyzeWithoutTasks: true})
+ this.analyzeWithoutTasks: true,
+ SummaryDataStore externalSummaries})
: _logger = logger,
_sourceFactory = sourceFactory.clone(),
- _sdkBundle = sdkBundle {
+ _sdkBundle = sdkBundle,
+ externalSummaries = externalSummaries {
_testView = new AnalysisDriverTestView(this);
_createFileTracker(logger);
_scheduler.add(this);
@@ -544,6 +555,13 @@ class AnalysisDriver implements AnalysisDriverGeneric {
return completer.future;
}
+ ApiSignature getResolvedUnitKeyByPath(String path) {
+ ApiSignature signature = getUnitKeyByPath(path);
+ var file = fsState.getFileForPath(path);
+ signature.addString(file.contentHash);
+ return signature;
+ }
+
/**
* Return a [Future] that completes with a [AnalysisResult] for the Dart
* file with the given [path]. If the file is not a Dart file or cannot
@@ -647,6 +665,14 @@ class AnalysisDriver implements AnalysisDriverGeneric {
return completer.future;
}
+ ApiSignature getUnitKeyByPath(String path) {
+ var file = fsState.getFileForPath(path);
+ ApiSignature signature = new ApiSignature();
+ signature.addUint32List(_salt);
+ signature.addString(file.transitiveSignature);
+ return signature;
+ }
+
/**
* Return a [Future] that completes with a [ParseResult] for the file
* with the given [path].
@@ -668,6 +694,186 @@ class AnalysisDriver implements AnalysisDriverGeneric {
}
/**
+ * Perform a single chunk of work and produce [results].
+ */
+ Future<Null> performWork() async {
+ if (_fileTracker.verifyChangedFilesIfNeeded()) {
+ return;
+ }
+
+ // Analyze a requested file.
+ if (_requestedFiles.isNotEmpty) {
+ String path = _requestedFiles.keys.first;
+ try {
+ AnalysisResult result = _computeAnalysisResult(path, withUnit: true);
+ // If a part without a library, delay its analysis.
+ if (result == null) {
+ _requestedParts
+ .putIfAbsent(path, () => [])
+ .addAll(_requestedFiles.remove(path));
+ return;
+ }
+ // Notify the completers.
+ _requestedFiles.remove(path).forEach((completer) {
+ completer.complete(result);
+ });
+ // Remove from to be analyzed and produce it now.
+ _fileTracker.fileWasAnalyzed(path);
+ _resultController.add(result);
+ } catch (exception, stackTrace) {
+ _fileTracker.fileWasAnalyzed(path);
+ _requestedFiles.remove(path).forEach((completer) {
+ completer.completeError(exception, stackTrace);
+ });
+ }
+ return;
+ }
+
+ // Process an index request.
+ if (_indexRequestedFiles.isNotEmpty) {
+ String path = _indexRequestedFiles.keys.first;
+ AnalysisDriverUnitIndex index = _computeIndex(path);
+ _indexRequestedFiles.remove(path).forEach((completer) {
+ completer.complete(index);
+ });
+ return;
+ }
+
+ // Process a unit element key request.
+ if (_unitElementSignatureRequests.isNotEmpty) {
+ String path = _unitElementSignatureRequests.keys.first;
+ String signature = _computeUnitElementSignature(path);
+ _unitElementSignatureRequests.remove(path).forEach((completer) {
+ completer.complete(signature);
+ });
+ return;
+ }
+
+ // Process a unit element request.
+ if (_unitElementRequestedFiles.isNotEmpty) {
+ String path = _unitElementRequestedFiles.keys.first;
+ UnitElementResult result = _computeUnitElement(path);
+ _unitElementRequestedFiles.remove(path).forEach((completer) {
+ completer.complete(result);
+ });
+ return;
+ }
+
+ // Compute files defining a name.
+ if (_definingClassMemberNameTasks.isNotEmpty) {
+ _FilesDefiningClassMemberNameTask task =
+ _definingClassMemberNameTasks.first;
+ bool isDone = await task.perform();
+ if (isDone) {
+ _definingClassMemberNameTasks.remove(task);
+ }
+ return;
+ }
+
+ // Compute files referencing a name.
+ if (_referencingNameTasks.isNotEmpty) {
+ _FilesReferencingNameTask task = _referencingNameTasks.first;
+ bool isDone = await task.perform();
+ if (isDone) {
+ _referencingNameTasks.remove(task);
+ }
+ return;
+ }
+
+ // Compute top-level declarations.
+ if (_topLevelNameDeclarationsTasks.isNotEmpty) {
+ _TopLevelNameDeclarationsTask task = _topLevelNameDeclarationsTasks.first;
+ bool isDone = await task.perform();
+ if (isDone) {
+ _topLevelNameDeclarationsTasks.remove(task);
+ }
+ return;
+ }
+
+ // Analyze a priority file.
+ if (_priorityFiles.isNotEmpty) {
+ for (String path in _priorityFiles) {
+ if (_fileTracker.isFilePending(path)) {
+ try {
+ AnalysisResult result =
+ _computeAnalysisResult(path, withUnit: true);
+ if (result == null) {
+ _partsToAnalyze.add(path);
+ } else {
+ _resultController.add(result);
+ }
+ } catch (exception, stackTrace) {
+ _reportException(path, exception, stackTrace);
+ } finally {
+ _fileTracker.fileWasAnalyzed(path);
+ }
+ return;
+ }
+ }
+ }
+
+ // Analyze a general file.
+ if (_fileTracker.hasPendingFiles) {
+ String path = _fileTracker.anyPendingFile;
+ try {
+ AnalysisResult result = _computeAnalysisResult(path,
+ withUnit: false, skipIfSameSignature: true);
+ if (result == null) {
+ _partsToAnalyze.add(path);
+ } else if (result == AnalysisResult._UNCHANGED) {
+ // We found that the set of errors is the same as we produced the
+ // last time, so we don't need to produce it again now.
+ } else {
+ _resultController.add(result);
+ _lastProducedSignatures[result.path] = result._signature;
+ }
+ } catch (exception, stackTrace) {
+ _reportException(path, exception, stackTrace);
+ } finally {
+ _fileTracker.fileWasAnalyzed(path);
+ }
+ return;
+ }
+
+ // Analyze a requested part file.
+ if (_requestedParts.isNotEmpty) {
+ String path = _requestedParts.keys.first;
+ try {
+ AnalysisResult result = _computeAnalysisResult(path,
+ withUnit: true, asIsIfPartWithoutLibrary: true);
+ // Notify the completers.
+ _requestedParts.remove(path).forEach((completer) {
+ completer.complete(result);
+ });
+ // Remove from to be analyzed and produce it now.
+ _partsToAnalyze.remove(path);
+ _resultController.add(result);
+ } catch (exception, stackTrace) {
+ _partsToAnalyze.remove(path);
+ _requestedParts.remove(path).forEach((completer) {
+ completer.completeError(exception, stackTrace);
+ });
+ }
+ return;
+ }
+
+ // Analyze a general part.
+ if (_partsToAnalyze.isNotEmpty) {
+ String path = _partsToAnalyze.first;
+ _partsToAnalyze.remove(path);
+ try {
+ AnalysisResult result = _computeAnalysisResult(path,
+ withUnit: _priorityFiles.contains(path),
+ asIsIfPartWithoutLibrary: true);
+ _resultController.add(result);
+ } catch (exception, stackTrace) {
+ _reportException(path, exception, stackTrace);
+ }
+ return;
+ }
+ }
+
+ /**
* Remove the file with the given [path] from the list of files to analyze.
*
* The [path] must be absolute and normalized.
@@ -682,6 +888,19 @@ class AnalysisDriver implements AnalysisDriverGeneric {
}
/**
+ * TODO(scheglov) document
+ */
+ Future<LibraryElement> resynthesizeLibrary(String uri) async {
+ if (externalSummaries.hasUnlinkedUnit(uri)) {
+ return LibraryContext.resynthesizeLibrary(analysisOptions,
+ declaredVariables, sourceFactory, externalSummaries, uri);
+ }
+ Source source = sourceFactory.resolveUri(null, uri);
+ var unitResult = await getUnitElement(source.fullName);
+ return unitResult.element.library;
+ }
+
+ /**
* Handles a notification from the [FileTracker] that there has been a change
* of state.
*/
@@ -711,6 +930,25 @@ class AnalysisDriver implements AnalysisDriverGeneric {
bool skipIfSameSignature: false}) {
FileState file = _fileTracker.fsState.getFileForPath(path);
+ {
+ UnitAnalysisResult unitResult = _cachedResults[file];
+ if (unitResult != null) {
+ return new AnalysisResult(
+ this,
+ sourceFactory,
+ path,
+ file.uri,
+ file.exists,
+ file.content,
+ file.contentHash,
+ file.lineInfo,
+ null,
+ unitResult.unit,
+ unitResult.errors,
+ null);
+ }
+ }
+
// Prepare the library - the file itself, or the known library.
FileState library = file.isPart ? file.library : file;
if (library == null) {
@@ -757,6 +995,7 @@ class AnalysisDriver implements AnalysisDriverGeneric {
libraryContext.store,
library);
Map<FileState, UnitAnalysisResult> results = analyzer.analyze();
+ _cachedResults.addAll(results);
for (FileState unitFile in results.keys) {
UnitAnalysisResult unitResult = results[unitFile];
List<int> unitBytes =
@@ -810,6 +1049,9 @@ class AnalysisDriver implements AnalysisDriverGeneric {
UnitElementResult _computeUnitElement(String path) {
FileState file = _fileTracker.fsState.getFileForPath(path);
+ if (path.startsWith('dart:')) {
+ file = _fileTracker.fsState.getFileForUri(Uri.parse(path));
+ }
FileState library = file.library ?? file;
// Create the AnalysisContext to resynthesize elements in.
@@ -840,8 +1082,16 @@ class AnalysisDriver implements AnalysisDriverGeneric {
*/
void _createFileTracker(PerformanceLog logger) {
_fillSalt();
- _fileTracker = new FileTracker(logger, _byteStore, _contentOverlay,
- _resourceProvider, sourceFactory, _analysisOptions, _salt, _changeHook);
+ _fileTracker = new FileTracker(
+ logger,
+ _byteStore,
+ _contentOverlay,
+ _resourceProvider,
+ sourceFactory,
+ _analysisOptions,
+ _salt,
+ externalSummaries,
+ _changeHook);
}
/**
@@ -856,6 +1106,7 @@ class AnalysisDriver implements AnalysisDriverGeneric {
_analysisOptions,
declaredVariables,
_sourceFactory,
+ externalSummaries,
_fileTracker);
/**
@@ -933,21 +1184,6 @@ class AnalysisDriver implements AnalysisDriverGeneric {
return signature.toHex();
}
- ApiSignature getUnitKeyByPath(String path) {
- var file = fsState.getFileForPath(path);
- ApiSignature signature = new ApiSignature();
- signature.addUint32List(_salt);
- signature.addString(file.transitiveSignature);
- return signature;
- }
-
- ApiSignature getResolvedUnitKeyByPath(String path) {
- ApiSignature signature = getUnitKeyByPath(path);
- var file = fsState.getFileForPath(path);
- signature.addString(file.contentHash);
- return signature;
- }
-
/**
* Return the lint code with the given [errorName], or `null` if there is no
* lint registered with that name or the lint is not enabled in the analysis
@@ -966,186 +1202,6 @@ class AnalysisDriver implements AnalysisDriverGeneric {
return null;
}
- /**
- * Perform a single chunk of work and produce [results].
- */
- Future<Null> performWork() async {
- if (_fileTracker.verifyChangedFilesIfNeeded()) {
- return;
- }
-
- // Analyze a requested file.
- if (_requestedFiles.isNotEmpty) {
- String path = _requestedFiles.keys.first;
- try {
- AnalysisResult result = _computeAnalysisResult(path, withUnit: true);
- // If a part without a library, delay its analysis.
- if (result == null) {
- _requestedParts
- .putIfAbsent(path, () => [])
- .addAll(_requestedFiles.remove(path));
- return;
- }
- // Notify the completers.
- _requestedFiles.remove(path).forEach((completer) {
- completer.complete(result);
- });
- // Remove from to be analyzed and produce it now.
- _fileTracker.fileWasAnalyzed(path);
- _resultController.add(result);
- } catch (exception, stackTrace) {
- _fileTracker.fileWasAnalyzed(path);
- _requestedFiles.remove(path).forEach((completer) {
- completer.completeError(exception, stackTrace);
- });
- }
- return;
- }
-
- // Process an index request.
- if (_indexRequestedFiles.isNotEmpty) {
- String path = _indexRequestedFiles.keys.first;
- AnalysisDriverUnitIndex index = _computeIndex(path);
- _indexRequestedFiles.remove(path).forEach((completer) {
- completer.complete(index);
- });
- return;
- }
-
- // Process a unit element key request.
- if (_unitElementSignatureRequests.isNotEmpty) {
- String path = _unitElementSignatureRequests.keys.first;
- String signature = _computeUnitElementSignature(path);
- _unitElementSignatureRequests.remove(path).forEach((completer) {
- completer.complete(signature);
- });
- return;
- }
-
- // Process a unit element request.
- if (_unitElementRequestedFiles.isNotEmpty) {
- String path = _unitElementRequestedFiles.keys.first;
- UnitElementResult result = _computeUnitElement(path);
- _unitElementRequestedFiles.remove(path).forEach((completer) {
- completer.complete(result);
- });
- return;
- }
-
- // Compute files defining a name.
- if (_definingClassMemberNameTasks.isNotEmpty) {
- _FilesDefiningClassMemberNameTask task =
- _definingClassMemberNameTasks.first;
- bool isDone = await task.perform();
- if (isDone) {
- _definingClassMemberNameTasks.remove(task);
- }
- return;
- }
-
- // Compute files referencing a name.
- if (_referencingNameTasks.isNotEmpty) {
- _FilesReferencingNameTask task = _referencingNameTasks.first;
- bool isDone = await task.perform();
- if (isDone) {
- _referencingNameTasks.remove(task);
- }
- return;
- }
-
- // Compute top-level declarations.
- if (_topLevelNameDeclarationsTasks.isNotEmpty) {
- _TopLevelNameDeclarationsTask task = _topLevelNameDeclarationsTasks.first;
- bool isDone = await task.perform();
- if (isDone) {
- _topLevelNameDeclarationsTasks.remove(task);
- }
- return;
- }
-
- // Analyze a priority file.
- if (_priorityFiles.isNotEmpty) {
- for (String path in _priorityFiles) {
- if (_fileTracker.isFilePending(path)) {
- try {
- AnalysisResult result =
- _computeAnalysisResult(path, withUnit: true);
- if (result == null) {
- _partsToAnalyze.add(path);
- } else {
- _resultController.add(result);
- }
- } catch (exception, stackTrace) {
- _reportException(path, exception, stackTrace);
- } finally {
- _fileTracker.fileWasAnalyzed(path);
- }
- return;
- }
- }
- }
-
- // Analyze a general file.
- if (_fileTracker.hasPendingFiles) {
- String path = _fileTracker.anyPendingFile;
- try {
- AnalysisResult result = _computeAnalysisResult(path,
- withUnit: false, skipIfSameSignature: true);
- if (result == null) {
- _partsToAnalyze.add(path);
- } else if (result == AnalysisResult._UNCHANGED) {
- // We found that the set of errors is the same as we produced the
- // last time, so we don't need to produce it again now.
- } else {
- _resultController.add(result);
- _lastProducedSignatures[result.path] = result._signature;
- }
- } catch (exception, stackTrace) {
- _reportException(path, exception, stackTrace);
- } finally {
- _fileTracker.fileWasAnalyzed(path);
- }
- return;
- }
-
- // Analyze a requested part file.
- if (_requestedParts.isNotEmpty) {
- String path = _requestedParts.keys.first;
- try {
- AnalysisResult result = _computeAnalysisResult(path,
- withUnit: true, asIsIfPartWithoutLibrary: true);
- // Notify the completers.
- _requestedParts.remove(path).forEach((completer) {
- completer.complete(result);
- });
- // Remove from to be analyzed and produce it now.
- _partsToAnalyze.remove(path);
- _resultController.add(result);
- } catch (exception, stackTrace) {
- _partsToAnalyze.remove(path);
- _requestedParts.remove(path).forEach((completer) {
- completer.completeError(exception, stackTrace);
- });
- }
- return;
- }
-
- // Analyze a general part.
- if (_partsToAnalyze.isNotEmpty) {
- String path = _partsToAnalyze.first;
- _partsToAnalyze.remove(path);
- try {
- AnalysisResult result = _computeAnalysisResult(path,
- withUnit: _priorityFiles.contains(path),
- asIsIfPartWithoutLibrary: true);
- _resultController.add(result);
- } catch (exception, stackTrace) {
- _reportException(path, exception, stackTrace);
- }
- return;
- }
- }
-
void _reportException(String path, exception, StackTrace stackTrace) {
String contextKey = null;
if (exception is _ExceptionState) {
@@ -1304,6 +1360,14 @@ class AnalysisDriverScheduler {
}
/**
+ * Add the given [driver] and schedule it to perform its work.
+ */
+ void add(AnalysisDriverGeneric driver) {
+ _drivers.add(driver);
+ _hasWork.notify();
+ }
+
+ /**
* Notify that there is a change to the [driver], it it might need to
* perform some work.
*/
@@ -1333,14 +1397,6 @@ class AnalysisDriverScheduler {
Future<Null> waitForIdle() => _statusSupport.waitForIdle();
/**
- * Add the given [driver] and schedule it to perform its work.
- */
- void add(AnalysisDriverGeneric driver) {
- _drivers.add(driver);
- _hasWork.notify();
- }
-
- /**
* Remove the given [driver] from the scheduler, so that it will not be
* asked to perform any new work.
*/
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/analysis/file_state.dart » ('j') | pkg/dev_compiler/lib/src/compiler/compiler.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698