1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-08 12:06:26 +00:00

AnalysisDriver. Produce results for all files of a library.

Change-Id: I0118ccdbd4a9059eb3809cb3b6a694731621d809
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/345363
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Konstantin Shcheglov 2024-01-11 03:53:48 +00:00 committed by Commit Queue
parent 19546dd720
commit 89bd370e95
6 changed files with 1434 additions and 690 deletions

View File

@ -28,8 +28,15 @@ void f() {
await sendServerSetSubscriptions([ServerService.STATUS]);
await sendAnalysisUpdateContent({filePath: AddContentOverlay(content)});
await sendAnalysisSetAnalysisRoots([packagePath], []);
await analysisFinished;
// TODO(scheglov): https://github.com/dart-lang/sdk/issues/54577
// `await analysisFinished` should be enough, but was not promised.
while (currentAnalysisErrors[filePath] == null) {
await pumpEventQueue();
}
expect(currentAnalysisErrors[filePath], isList);
var errors = existingErrorsForFile(filePath);
expect(errors, hasLength(1));

View File

@ -54,12 +54,12 @@ import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/utilities/extensions/collection.dart';
import 'package:analyzer/src/utilities/uri_cache.dart';
/// This class computes [AnalysisResult]s for Dart files.
/// This class computes analysis results for Dart files.
///
/// Let the set of "explicitly analyzed files" denote the set of paths that have
/// been passed to [addFile] but not subsequently passed to [removeFile]. Let
/// the "current analysis results" denote the map from the set of explicitly
/// analyzed files to the most recent [AnalysisResult] delivered to [results]
/// analyzed files to the most recent analysis result delivered to [results]
/// for each file. Let the "current file state" represent a map from file path
/// to the file contents most recently read from that file, or fetched from the
/// content cache (considering all possible file paths, regardless of
@ -90,7 +90,7 @@ import 'package:analyzer/src/utilities/uri_cache.dart';
// TODO(scheglov): Clean up the list of implicitly analyzed files.
class AnalysisDriver {
/// The version of data format, should be incremented on every format change.
static const int DATA_VERSION = 326;
static const int DATA_VERSION = 327;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.
@ -427,7 +427,8 @@ class AnalysisDriver {
/// Return the [ResourceProvider] that is used to access the file system.
ResourceProvider get resourceProvider => _resourceProvider;
/// Return the [Stream] that produces [AnalysisResult]s for added files.
/// Return the [Stream] that produces [ErrorsResult]s and
/// [ResolvedUnitResult]s for added files.
///
/// Note that the stream supports only one single subscriber.
///
@ -1164,7 +1165,7 @@ class AnalysisDriver {
final result = await _resolveForCompletion(request);
request.completer.complete(result);
} catch (exception, stackTrace) {
_reportException(request.path, exception, stackTrace);
_reportException(request.path, exception, stackTrace, null);
request.completer.completeError(exception, stackTrace);
_clearLibraryContextAfterException();
}
@ -1174,61 +1175,28 @@ class AnalysisDriver {
// Analyze a requested file.
if (_requestedFiles.isNotEmpty) {
final path = _requestedFiles.keys.first;
final completers = _requestedFiles.remove(path)!;
_fileTracker.fileWasAnalyzed(path);
try {
final result = await _computeAnalysisResult(path, withUnit: true);
final unitResult = result.unitResult!;
for (final completer in completers) {
completer.complete(unitResult);
}
_resultController.add(unitResult);
} catch (exception, stackTrace) {
_reportException(path, exception, stackTrace);
for (final completer in completers) {
completer.completeError(exception, stackTrace);
}
_clearLibraryContextAfterException();
}
await _analyzeFile(path);
return;
}
// Analyze a requested library.
if (_requestedLibraries.isNotEmpty) {
final library = _requestedLibraries.keys.first;
try {
var result = await _computeResolvedLibrary(library);
for (var completer in _requestedLibraries.remove(library)!) {
completer.complete(result);
}
} catch (exception, stackTrace) {
for (var completer in _requestedLibraries.remove(library)!) {
completer.completeError(exception, stackTrace);
}
_clearLibraryContextAfterException();
}
await _getResolvedLibrary(library);
return;
}
// Process an error request.
if (_errorsRequestedFiles.isNotEmpty) {
var path = _errorsRequestedFiles.keys.first;
var completers = _errorsRequestedFiles.remove(path)!;
var analysisResult = await _computeAnalysisResult(path, withUnit: false);
var result = analysisResult.errorsResult!;
for (var completer in completers) {
completer.complete(result);
}
final path = _errorsRequestedFiles.keys.first;
await _getErrors(path);
return;
}
// Process an index request.
if (_indexRequestedFiles.isNotEmpty) {
String path = _indexRequestedFiles.keys.first;
final index = await _computeIndex(path);
for (var completer in _indexRequestedFiles.remove(path)!) {
completer.complete(index);
}
final path = _indexRequestedFiles.keys.first;
await _getIndex(path);
return;
}
@ -1275,15 +1243,7 @@ class AnalysisDriver {
if (_priorityFiles.isNotEmpty) {
for (String path in _priorityFiles) {
if (_fileTracker.isFilePending(path)) {
try {
var result = await _computeAnalysisResult(path, withUnit: true);
_resultController.add(result.unitResult!);
} catch (exception, stackTrace) {
_reportException(path, exception, stackTrace);
_clearLibraryContextAfterException();
} finally {
_fileTracker.fileWasAnalyzed(path);
}
await _analyzeFile(path);
return;
}
}
@ -1292,22 +1252,7 @@ class AnalysisDriver {
// Analyze a general file.
if (_fileTracker.hasPendingFiles) {
String path = _fileTracker.anyPendingFile;
try {
var result = await _computeAnalysisResult(path,
withUnit: false, skipIfSameSignature: true);
if (result.isUnchangedErrors) {
// 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.errorsResult!);
_lastProducedSignatures[path] = result._signature;
}
} catch (exception, stackTrace) {
_reportException(path, exception, stackTrace);
_clearLibraryContextAfterException();
} finally {
_fileTracker.fileWasAnalyzed(path);
}
await _produceErrors(path);
return;
}
}
@ -1366,6 +1311,174 @@ class AnalysisDriver {
}
}
Future<void> _analyzeFile(String path) async {
// We will produce the result for this file, at least.
// And for any other files of the same library.
_fileTracker.fileWasAnalyzed(path);
final file = _fsState.getFileForPath(path);
// Prepare the library - the file itself, or the known library.
final kind = file.kind;
final library = kind.library ?? kind.asLibrary;
// We need the fully resolved unit, or the result is not cached.
return _logger.runAsync('Compute analysis result for $path', () async {
_logger.writeln('Work in $name');
try {
testView?.numOfAnalyzedLibraries++;
_resultController.add(
events.AnalyzeFile(
file: file,
library: library,
),
);
if (!_hasLibraryByUri('dart:core')) {
_errorsRequestedFiles.completeAll(
path,
_newMissingDartLibraryResult(file, 'dart:core'),
);
return;
}
if (!_hasLibraryByUri('dart:async')) {
_errorsRequestedFiles.completeAll(
path,
_newMissingDartLibraryResult(file, 'dart:async'),
);
return;
}
await libraryContext.load(
targetLibrary: library,
performance: OperationPerformanceImpl('<root>'),
);
var options = libraryContext.analysisContext
.getAnalysisOptionsForFile(file.resource);
var results = LibraryAnalyzer(
options,
declaredVariables,
libraryContext.elementFactory.libraryOfUri2(library.file.uri),
libraryContext.elementFactory.analysisSession.inheritanceManager,
library,
resourceProvider.pathContext,
testingData: testingData,
).analyze();
final isLibraryWithPriorityFile = _isLibraryWithPriorityFile(library);
final resolvedUnits = <ResolvedUnitResultImpl>[];
for (var unitResult in results) {
var unitFile = unitResult.file;
final index = enableIndex
? indexUnit(unitResult.unit)
: AnalysisDriverUnitIndexBuilder();
final resolvedUnit = _createResolvedUnitImpl(
file: unitFile,
unitResult: unitResult,
);
resolvedUnits.add(resolvedUnit);
// getResolvedUnit()
_requestedFiles.completeAll(unitFile.path, resolvedUnit);
// getErrors()
_errorsRequestedFiles.completeAll(
unitFile.path,
_createErrorsResultImpl(
file: file,
errors: unitResult.errors,
),
);
// getIndex()
_indexRequestedFiles.completeAll(unitFile.path, index);
final unitSignature = _getResolvedUnitSignature(library, unitFile);
{
final unitKey = _getResolvedUnitKey(unitSignature);
final unitBytes = AnalysisDriverResolvedUnitBuilder(
errors: unitResult.errors.map((error) {
return ErrorEncoding.encode(error);
}).toList(),
index: index,
).toBuffer();
_byteStore.putGet(unitKey, unitBytes);
}
_fileTracker.fileWasAnalyzed(unitFile.path);
_lastProducedSignatures[path] = unitSignature;
_resultController.add(resolvedUnit);
if (isLibraryWithPriorityFile) {
_priorityResults[unitFile.path] = resolvedUnit;
}
_updateHasErrorOrWarningFlag(file, resolvedUnit.errors);
}
final libraryResult = ResolvedLibraryResultImpl(
session: currentSession,
element: resolvedUnits.first.libraryElement,
units: resolvedUnits,
);
if (isLibraryWithPriorityFile) {
_resolvedLibraryCache[library] = libraryResult;
}
// getResolvedLibrary()
{
final completers = _requestedLibraries.remove(library);
if (completers != null) {
for (final completer in completers) {
completer.complete(libraryResult);
}
}
}
// Return the result, full or partial.
_logger.writeln('Computed new analysis result.');
// return result;
} catch (exception, stackTrace) {
final contextKey =
_storeExceptionContext(path, library, exception, stackTrace);
_reportException(path, exception, stackTrace, contextKey);
// Complete all related requests with an error.
void completeWithError<T>(List<Completer<T>>? completers) {
if (completers != null) {
for (final completer in completers) {
completer.completeError(exception, stackTrace);
}
}
}
// TODO(scheglov): write tests
for (final file in library.files) {
// getResolvedUnit()
completeWithError(
_requestedFiles.remove(file.path),
);
// getErrors()
completeWithError(
_errorsRequestedFiles.remove(file.path),
);
}
// getResolvedLibrary()
completeWithError(
_requestedLibraries.remove(library),
);
_clearLibraryContextAfterException();
}
});
}
void _applyPendingFileChanges() {
var accumulatedAffected = <String>{};
for (var fileChange in _pendingFileChanges) {
@ -1409,230 +1522,6 @@ class AnalysisDriver {
_resolvedLibraryCache.clear();
}
/// Return the cached or newly computed analysis result of the file with the
/// given [path].
///
/// The [withUnit] flag control which result will be returned.
/// When `true`, [AnalysisResult.unitResult] will be set.
/// Otherwise [AnalysisResult.errorsResult] will be set.
///
/// Return [AnalysisResult._UNCHANGED] if [skipIfSameSignature] is `true` and
/// the resolved signature of the file in its library is the same as the one
/// that was the most recently produced to the client.
Future<AnalysisResult> _computeAnalysisResult(String path,
{required bool withUnit, bool skipIfSameSignature = false}) async {
FileState file = _fsState.getFileForPath(path);
// Prepare the library - the file itself, or the known library.
final kind = file.kind;
final library = kind.library ?? kind.asLibrary;
// Prepare the signature and key.
String signature = _getResolvedUnitSignature(library, file);
String key = _getResolvedUnitKey(signature);
// Skip reading if the signature, so errors, are the same as the last time.
if (skipIfSameSignature) {
assert(!withUnit);
if (_lastProducedSignatures[path] == signature) {
return AnalysisResult.unchangedErrors(signature);
}
}
// If we don't need the fully resolved unit, check for the cached result.
if (!withUnit) {
var bytes = _byteStore.get(key);
if (bytes != null) {
final unit = AnalysisDriverResolvedUnit.fromBuffer(bytes);
final errors = _getErrorsFromSerialized(file, unit.errors);
_updateHasErrorOrWarningFlag(file, errors);
final index = unit.index!;
final errorsResult = _createErrorsResultImpl(
file: file,
errors: errors,
);
return AnalysisResult.errors(signature, errorsResult, index);
}
}
// We need the fully resolved unit, or the result is not cached.
return _logger.runAsync('Compute analysis result for $path', () async {
_logger.writeln('Work in $name');
try {
testView?.numOfAnalyzedLibraries++;
_resultController.add(
events.ComputeAnalysis(
file: file,
library: library,
),
);
if (!_hasLibraryByUri('dart:core')) {
return _newMissingDartLibraryResult(file, 'dart:core');
}
if (!_hasLibraryByUri('dart:async')) {
return _newMissingDartLibraryResult(file, 'dart:async');
}
await libraryContext.load(
targetLibrary: library,
performance: OperationPerformanceImpl('<root>'),
);
var options = libraryContext.analysisContext
.getAnalysisOptionsForFile(file.resource);
var results = LibraryAnalyzer(
options,
declaredVariables,
libraryContext.elementFactory.libraryOfUri2(library.file.uri),
libraryContext.elementFactory.analysisSession.inheritanceManager,
library,
resourceProvider.pathContext,
testingData: testingData,
).analyze();
final isLibraryWithPriorityFile = _isLibraryWithPriorityFile(library);
late AnalysisResult result;
final resolvedUnits = <ResolvedUnitResultImpl>[];
for (var unitResult in results) {
var unitFile = unitResult.file;
final index = enableIndex
? indexUnit(unitResult.unit)
: AnalysisDriverUnitIndexBuilder();
final unitBytes = AnalysisDriverResolvedUnitBuilder(
errors: unitResult.errors.map((error) {
return ErrorEncoding.encode(error);
}).toList(),
index: index,
).toBuffer();
final resolvedUnit = _createResolvedUnitImpl(
file: unitFile,
unitResult: unitResult,
);
resolvedUnits.add(resolvedUnit);
if (isLibraryWithPriorityFile) {
_priorityResults[unitFile.path] = resolvedUnit;
}
String unitSignature = _getResolvedUnitSignature(library, unitFile);
String unitKey = _getResolvedUnitKey(unitSignature);
_byteStore.putGet(unitKey, unitBytes);
_updateHasErrorOrWarningFlag(file, resolvedUnit.errors);
if (unitFile == file) {
if (withUnit) {
result = AnalysisResult.unit(signature, resolvedUnit, index);
} else {
result = AnalysisResult.errors(
signature,
_createErrorsResultImpl(
file: unitFile,
errors: unitResult.errors,
),
index,
);
}
}
}
if (isLibraryWithPriorityFile) {
final libraryResult = ResolvedLibraryResultImpl(
session: currentSession,
element: resolvedUnits.first.libraryElement,
units: resolvedUnits,
);
_resolvedLibraryCache[library] = libraryResult;
}
// Return the result, full or partial.
_logger.writeln('Computed new analysis result.');
return result;
} catch (exception, stackTrace) {
String? contextKey =
_storeExceptionContext(path, library, exception, stackTrace);
throw _ExceptionState(exception, stackTrace, contextKey);
}
});
}
Future<AnalysisDriverUnitIndex> _computeIndex(String path) async {
var analysisResult = await _computeAnalysisResult(path, withUnit: false);
return analysisResult._index!;
}
/// Return the newly computed resolution result of the library with the
/// given [path].
Future<ResolvedLibraryResultImpl> _computeResolvedLibrary(
LibraryFileKind library,
) async {
final cached = _resolvedLibraryCache[library];
if (cached != null) {
return cached;
}
final path = library.file.path;
return _logger.runAsync('Compute resolved library $path', () async {
testView?.numOfAnalyzedLibraries++;
await libraryContext.load(
targetLibrary: library,
performance: OperationPerformanceImpl('<root>'),
);
_resultController.add(
events.ComputeResolvedLibrary(
library: library,
),
);
var analysisOptions = libraryContext.analysisContext
.getAnalysisOptionsForFile(library.file.resource);
var unitResults = LibraryAnalyzer(
analysisOptions,
declaredVariables,
libraryContext.elementFactory.libraryOfUri2(library.file.uri),
libraryContext.elementFactory.analysisSession.inheritanceManager,
library,
resourceProvider.pathContext,
testingData: testingData)
.analyze();
var resolvedUnits = <ResolvedUnitResult>[];
final isLibraryWithPriorityFile = _isLibraryWithPriorityFile(library);
for (final unitResult in unitResults) {
final unitFile = unitResult.file;
final resolvedUnit = _createResolvedUnitImpl(
file: unitFile,
unitResult: unitResult,
);
resolvedUnits.add(resolvedUnit);
if (isLibraryWithPriorityFile) {
_priorityResults[unitFile.path] = resolvedUnit;
}
}
final result = ResolvedLibraryResultImpl(
session: currentSession,
element: resolvedUnits.first.libraryElement,
units: resolvedUnits,
);
if (isLibraryWithPriorityFile) {
_resolvedLibraryCache[library] = result;
}
return result;
});
}
Future<UnitElementResult?> _computeUnitElement(String path) async {
FileState file = _fsState.getFileForPath(path);
@ -1805,6 +1694,39 @@ class AnalysisDriver {
_saltForUnlinked = buffer.toUint32List();
}
Future<void> _getErrors(String path) async {
final file = _fsState.getFileForPath(path);
// Prepare the library - the file itself, or the known library.
final kind = file.kind;
final library = kind.library ?? kind.asLibrary;
// Prepare the signature and key.
final signature = _getResolvedUnitSignature(library, file);
final key = _getResolvedUnitKey(signature);
final bytes = _byteStore.get(key);
if (bytes != null) {
_resultController.add(
events.GetErrorsFromBytes(
file: file,
library: library,
),
);
final unit = AnalysisDriverResolvedUnit.fromBuffer(bytes);
final errors = _getErrorsFromSerialized(file, unit.errors);
_updateHasErrorOrWarningFlag(file, errors);
final result = _createErrorsResultImpl(
file: file,
errors: errors,
);
_errorsRequestedFiles.completeAll(path, result);
return;
}
await _analyzeFile(path);
}
/// Return [AnalysisError]s for the given [serialized] errors.
List<AnalysisError> _getErrorsFromSerialized(
FileState file, List<AnalysisDriverUnitError> serialized) {
@ -1818,6 +1740,38 @@ class AnalysisDriver {
return errors;
}
Future<void> _getIndex(String path) async {
final file = _fsState.getFileForPath(path);
// Prepare the library - the file itself, or the known library.
final kind = file.kind;
final library = kind.library ?? kind.asLibrary;
// Prepare the signature and key.
final signature = _getResolvedUnitSignature(library, file);
final key = _getResolvedUnitKey(signature);
final bytes = _byteStore.get(key);
if (bytes != null) {
final unit = AnalysisDriverResolvedUnit.fromBuffer(bytes);
_indexRequestedFiles.completeAll(path, unit.index!);
return;
}
await _analyzeFile(path);
}
/// Completes the [getResolvedLibrary] request.
Future<void> _getResolvedLibrary(LibraryFileKind library) async {
final cached = _resolvedLibraryCache[library];
if (cached != null) {
_requestedLibraries.completeAll(library, cached);
return;
}
await _analyzeFile(library.file.path);
}
/// Return the key to store fully resolved results for the [signature].
String _getResolvedUnitKey(String signature) {
return '$signature.resolved';
@ -1871,10 +1825,10 @@ class AnalysisDriver {
/// We detected that one of the required `dart` libraries is missing.
/// Return the empty analysis result with the error.
AnalysisResult _newMissingDartLibraryResult(
ErrorsResultImpl _newMissingDartLibraryResult(
FileState file, String missingUri) {
// TODO(scheglov): Find a better way to report this.
var errorsResult = ErrorsResultImpl(
return ErrorsResultImpl(
session: currentSession,
file: file.resource,
lineInfo: file.lineInfo,
@ -1893,8 +1847,6 @@ class AnalysisDriver {
),
],
);
return AnalysisResult.errors(
'missing', errorsResult, AnalysisDriverUnitIndexBuilder());
}
void _onNewFile(FileState file) {
@ -1908,6 +1860,24 @@ class AnalysisDriver {
}
}
Future<void> _produceErrors(String path) async {
final file = _fsState.getFileForPath(path);
// Prepare the library - the file itself, or the known library.
final kind = file.kind;
final library = kind.library ?? kind.asLibrary;
// Don't produce errors if the signature is the same.
final signature = _getResolvedUnitSignature(library, file);
if (_lastProducedSignatures[path] == signature) {
_fileTracker.fileWasAnalyzed(path);
return;
}
// Analyze, will produce a result into the stream.
await _analyzeFile(path);
}
void _removePotentiallyAffectedLibraries(
Set<String> accumulatedAffected,
String path,
@ -1932,15 +1902,8 @@ class AnalysisDriver {
);
}
void _reportException(String path, Object exception, StackTrace stackTrace) {
String? contextKey;
if (exception is _ExceptionState) {
var state = exception;
exception = exception.exception;
stackTrace = state.stackTrace;
contextKey = state.contextKey;
}
void _reportException(String path, Object exception, StackTrace stackTrace,
String? contextKey) {
CaughtException caught = CaughtException(exception, stackTrace);
var fileContentMap = <String, String>{};
@ -2339,53 +2302,6 @@ class AnalysisDriverTestView {
}
}
/// The result of analyzing of a single file.
///
/// These results are self-consistent, i.e. the file content, line info, the
/// resolved unit correspond to each other. All referenced elements, even
/// external ones, are also self-consistent. But none of the results is
/// guaranteed to be consistent with the state of the files.
///
/// Every result is independent, and is not guaranteed to be consistent with
/// any previously returned result, even inside of the same library.
class AnalysisResult {
/// The signature of the result based on the content of the file, and the
/// transitive closure of files imported and exported by the library of
/// the requested file.
final String _signature;
final bool isUnchangedErrors;
/// Is not `null` if this result is a result with errors.
/// Otherwise is `null`, and usually [unitResult] is set.
final ErrorsResultImpl? errorsResult;
/// Is not `null` if this result is a result with a resolved unit.
/// Otherwise is `null`, and usually [errorsResult] is set.
final ResolvedUnitResultImpl? unitResult;
/// The index of the unit.
final AnalysisDriverUnitIndex? _index;
AnalysisResult.errors(
this._signature, this.errorsResult, AnalysisDriverUnitIndex index)
: isUnchangedErrors = false,
unitResult = null,
_index = index;
AnalysisResult.unchangedErrors(this._signature)
: isUnchangedErrors = true,
errorsResult = null,
unitResult = null,
_index = null;
AnalysisResult.unit(
this._signature, this.unitResult, AnalysisDriverUnitIndex index)
: isUnchangedErrors = false,
errorsResult = null,
_index = index;
}
/// An object that watches for the creation and removal of analysis drivers.
///
/// Clients may not extend, implement or mix-in this class.
@ -2619,21 +2535,6 @@ class _DiscoverAvailableFilesTask {
}
}
/// Information about an exception and its context.
class _ExceptionState {
final Object exception;
final StackTrace stackTrace;
/// The key under which the context of the exception was stored, or `null`
/// if unknown, the maximum number of context to store was reached, etc.
final String? contextKey;
_ExceptionState(this.exception, this.stackTrace, this.contextKey);
@override
String toString() => '$exception\n$stackTrace';
}
class _FileChange {
final String path;
final _FileChangeKind kind;
@ -2770,3 +2671,14 @@ class _ResolveForCompletionRequest {
required this.performance,
});
}
extension<K, V> on Map<K, List<Completer<V>>> {
void completeAll(K key, V value) {
final completers = remove(key);
if (completers != null) {
for (final completer in completers) {
completer.complete(value);
}
}
}
}

View File

@ -8,20 +8,22 @@ import 'package:analyzer/src/dart/analysis/file_state.dart';
/// An event that happened inside the [AnalysisDriver].
sealed class AnalysisDriverEvent {}
final class ComputeAnalysis extends AnalysisDriverEvent {
final class AnalyzeFile extends AnalysisDriverEvent {
final FileState file;
final LibraryFileKind library;
ComputeAnalysis({
AnalyzeFile({
required this.file,
required this.library,
});
}
final class ComputeResolvedLibrary extends AnalysisDriverEvent {
final class GetErrorsFromBytes extends AnalysisDriverEvent {
final FileState file;
final LibraryFileKind library;
ComputeResolvedLibrary({
GetErrorsFromBytes({
required this.file,
required this.library,
});
}

View File

@ -449,7 +449,7 @@ void f(MacroA a) {}
var analysisDriver = driverFor(a);
var userErrors = analysisDriver.results
.whereType<ErrorsResult>()
.whereType<ResolvedUnitResult>()
.where((event) => event.path == user.path);
// We get errors when the file is added.
@ -507,7 +507,7 @@ void f(MacroA a) {}
var analysisDriver = driverFor(a);
var userErrors = analysisDriver.results
.whereType<ErrorsResult>()
.whereType<ResolvedUnitResult>()
.where((event) => event.path == user.path);
// We get errors when the file is added.
@ -546,7 +546,7 @@ void f(MacroA a) {}
var analysisDriver = driverFor(user);
var userErrors = analysisDriver.results
.whereType<ErrorsResult>()
.whereType<ResolvedUnitResult>()
.where((event) => event.path == user.path);
// We get errors when the file is added.

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/analysis/driver_event.dart' as events;
import 'package:analyzer/src/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/status.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/utilities/extensions/file_system.dart';
import 'package:test/test.dart';
@ -82,6 +83,8 @@ class DriverEventsPrinter {
_writeGetCachedResolvedUnit(event);
case GetErrorsEvent():
_writeErrorsEvent(event);
case GetIndexEvent():
_writeIndexEvent(event);
case GetLibraryByUriEvent():
_writeGetLibraryByUriEvent(event);
case GetResolvedLibraryEvent():
@ -158,6 +161,13 @@ class DriverEventsPrinter {
});
}
void _writeIndexEvent(GetIndexEvent event) {
sink.writelnWithIndent('[future] getIndex');
sink.withIndent(() {
sink.writelnWithIndent('name: ${event.name}');
});
}
void _writeLibraryElementResult(SomeLibraryElementResult result) {
switch (result) {
case CannotResolveUriResult():
@ -208,32 +218,27 @@ class DriverEventsPrinter {
void _writeResultStreamEvent(ResultStreamEvent event) {
final object = event.object;
switch (object) {
case events.ComputeAnalysis():
if (!configuration.withOperations) {
return;
}
sink.writelnWithIndent('[operation] computeAnalysisResult');
case events.AnalyzeFile():
sink.writelnWithIndent('[operation] AnalyzeFile');
sink.withIndent(() {
final file = object.file.resource;
sink.writelnWithIndent('file: ${file.posixPath}');
final libraryFile = object.library.file.resource;
sink.writelnWithIndent('library: ${libraryFile.posixPath}');
});
case events.ComputeResolvedLibrary():
if (!configuration.withOperations) {
return;
}
sink.writelnWithIndent('[operation] computeResolvedLibrary');
sink.withIndent(() {
final fileState = object.library.file;
final file = fileState.resource;
sink.writelnWithIndent('library: ${file.posixPath}');
});
case ErrorsResult():
sink.writelnWithIndent('[stream]');
sink.withIndent(() {
_writeErrorsResult(object);
});
case events.GetErrorsFromBytes():
sink.writelnWithIndent('[operation] GetErrorsFromBytes');
sink.withIndent(() {
final file = object.file.resource;
sink.writelnWithIndent('file: ${file.posixPath}');
final libraryFile = object.library.file.resource;
sink.writelnWithIndent('library: ${libraryFile.posixPath}');
});
case ResolvedUnitResult():
sink.writelnWithIndent('[stream]');
sink.withIndent(() {
@ -283,7 +288,6 @@ class DriverEventsPrinter {
}
class DriverEventsPrinterConfiguration {
var withOperations = false;
var libraryConfiguration = ResolvedLibraryResultPrinterConfiguration();
var unitElementConfiguration = UnitElementPrinterConfiguration();
}
@ -310,6 +314,17 @@ final class GetErrorsEvent extends DriverEvent {
});
}
/// The result of `getIndex`.
final class GetIndexEvent extends DriverEvent {
final String name;
final AnalysisDriverUnitIndex? result;
GetIndexEvent({
required this.name,
required this.result,
});
}
/// The result of `getLibraryByUri`.
final class GetLibraryByUriEvent extends DriverEvent {
final String name;