Add AnalysisDriver.getFile(), deprecate getFileSync()
Change-Id: I2881c03813740c421f1b4a4be96549e4a91be519
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/235741
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index d1aa079..aac32ba 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -2,6 +2,7 @@
* Deprecated synchronous `getFile`, `getParsedLibrary`, `getParsedLibraryByElement`,
`getParsedUnit` from `AnalysisSession`. Use corresponding `getXyz2` asynchronous
methods instead. This change is necessary for the future work on macros.
+* Deprecated synchronous `getFileSync` from `AnalysisDriver`, use `getFile` instead.
## 3.3.1
* Report HintCode.OVERRIDE_ON_NON_OVERRIDING_xyz on enum.
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 84644e4..7a3b593 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -588,6 +588,19 @@
return getErrors(path);
}
+ /// Return the [FileResult] for the Dart file with the given [path].
+ ///
+ /// The [path] must be absolute and normalized.
+ Future<SomeFileResult> getFile(String path) async {
+ if (!_isAbsolutePath(path)) {
+ return InvalidPathResult();
+ }
+
+ FileState file = _fileTracker.getFile(path);
+ return FileResultImpl(
+ currentSession, path, file.uri, file.lineInfo, file.isPart);
+ }
+
/// Return a [Future] that completes with the list of added files that
/// define a class member with the given [name].
Future<List<String>> getFilesDefiningClassMemberName(String name) {
@@ -611,6 +624,7 @@
/// Return the [FileResult] for the Dart file with the given [path].
///
/// The [path] must be absolute and normalized.
+ @Deprecated('Use getFile() instead')
SomeFileResult getFileSync(String path) {
if (!_isAbsolutePath(path)) {
return InvalidPathResult();
@@ -624,7 +638,7 @@
/// Return the [FileResult] for the Dart file with the given [path].
///
/// The [path] must be absolute and normalized.
- @Deprecated('Use getFileSync() instead')
+ @Deprecated('Use getFile() instead')
SomeFileResult getFileSync2(String path) {
return getFileSync(path);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 97c98ca..47df470 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -70,7 +70,7 @@
@override
Future<SomeFileResult> getFile2(String path) async {
_checkConsistency();
- return _driver.getFileSync(path);
+ return _driver.getFile(path);
}
@override
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index afefd83..67951ae 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1380,6 +1380,66 @@
expect(result, isA<InvalidPathResult>());
}
+ test_getFile_changedFile() async {
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+
+ newFile(a, content: '');
+ newFile(b, content: r'''
+import 'a.dart';
+
+void f(A a) {}
+''');
+
+ // Ensure that [a.dart] library cycle is loaded.
+ // So, `a.dart` is in the library context.
+ await driver.getResultValid(a);
+
+ // Update the file, changing its API signature.
+ // Note that we don't call `changeFile`.
+ newFile(a, content: 'class A {}\n');
+
+ // Get the file.
+ // We have not called `changeFile(a)`, so we should not read the file.
+ // Moreover, doing this will create a new library cycle [a.dart].
+ // Library cycles are compared by their identity, so we would try to
+ // reload linked summary for [a.dart], and crash.
+ expect((await driver.getFileValid(a)).lineInfo.lineCount, 1);
+
+ // We have not read `a.dart`, so `A` is still not declared.
+ expect((await driver.getResultValid(b)).errors, isNotEmpty);
+
+ // Notify the driver that the file was changed.
+ driver.changeFile(a);
+
+ // So, `class A {}` is declared now.
+ expect((await driver.getFileValid(a)).lineInfo.lineCount, 2);
+ expect((await driver.getResultValid(b)).errors, isEmpty);
+ }
+
+ test_getFile_library() async {
+ var path = convertPath('/test/lib/a.dart');
+ newFile(path);
+ var file = await driver.getFileValid(path);
+ expect(file.path, path);
+ expect(file.uri.toString(), 'package:test/a.dart');
+ expect(file.isPart, isFalse);
+ }
+
+ test_getFile_notAbsolutePath() async {
+ var result = await driver.getFile('not_absolute.dart');
+ expect(result, isA<InvalidPathResult>());
+ }
+
+ test_getFile_part() async {
+ var path = convertPath('/test/lib/a.dart');
+ newFile(path, content: 'part of lib;');
+ var file = await driver.getFileValid(path);
+ expect(file.path, path);
+ expect(file.uri.toString(), 'package:test/a.dart');
+ expect(file.isPart, isTrue);
+ }
+
test_getFilesDefiningClassMemberName_class() async {
var a = convertPath('/test/bin/a.dart');
var b = convertPath('/test/bin/b.dart');
@@ -1483,6 +1543,7 @@
expect(files, isNot(contains(c)));
}
+ @deprecated
test_getFileSync_changedFile() async {
var a = convertPath('/test/lib/a.dart');
var b = convertPath('/test/lib/b.dart');
@@ -1520,6 +1581,7 @@
expect((await driver.getResultValid(b)).errors, isEmpty);
}
+ @deprecated
test_getFileSync_library() async {
var path = convertPath('/test/lib/a.dart');
newFile(path);
@@ -1529,11 +1591,13 @@
expect(file.isPart, isFalse);
}
+ @deprecated
test_getFileSync_notAbsolutePath() async {
var result = driver.getFileSync('not_absolute.dart');
expect(result, isA<InvalidPathResult>());
}
+ @deprecated
test_getFileSync_part() async {
var path = convertPath('/test/lib/a.dart');
newFile(path, content: 'part of lib;');
@@ -3451,10 +3515,15 @@
}
}
+ @deprecated
FileResult getFileSyncValid(String path) {
return getFileSync(path) as FileResult;
}
+ Future<FileResult> getFileValid(String path) async {
+ return await getFile(path) as FileResult;
+ }
+
Future<LibraryElementResult> getLibraryByUriValid(String uriStr) async {
return await getLibraryByUri(uriStr) as LibraryElementResult;
}
diff --git a/pkg/analyzer/test/src/dart/analysis/resolve_for_completion_test.dart b/pkg/analyzer/test/src/dart/analysis/resolve_for_completion_test.dart
index d570325..b1a26bd 100644
--- a/pkg/analyzer/test/src/dart/analysis/resolve_for_completion_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/resolve_for_completion_test.dart
@@ -461,7 +461,7 @@
newFile(testFilePath, content: 'class A {}');
// Read the file.
- testDriver.getFileSync(testFilePathPlatform);
+ await testDriver.getFile(testFilePathPlatform);
// Should call `changeFile()`, and the driver must re-read the file.
var result = _resolveTestCode(r'''
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index fff1252..7e40fff 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -148,7 +148,7 @@
// Print errors and performance numbers.
if (printMode == 1) {
- formatter.formatErrors(errorsResults);
+ await formatter.formatErrors(errorsResults);
} else if (printMode == 2) {
_printColdPerf();
}
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index de1d3c0..6c75fd3 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -248,7 +248,7 @@
analysisDriver.sourceFactory,
analysisDriver.currentSession.analysisContext.contextRoot.root.path,
);
- formatter.formatErrors([
+ await formatter.formatErrors([
ErrorsResultImpl(analysisDriver.currentSession, path,
pathContext.toUri(path), lineInfo, false, errors)
]);
@@ -304,7 +304,7 @@
allResult = allResult.max(severity);
}
var lineInfo = LineInfo.fromContent(content);
- formatter.formatErrors([
+ await formatter.formatErrors([
ErrorsResultImpl(analysisDriver.currentSession, path,
pathContext.toUri(path), lineInfo, false, errors)
]);
@@ -320,7 +320,7 @@
var lineInfo = LineInfo.fromContent(content);
var errors = validator.validate(
content, analysisDriver.analysisOptions.chromeOsManifestChecks);
- formatter.formatErrors([
+ await formatter.formatErrors([
ErrorsResultImpl(analysisDriver.currentSession, path,
pathContext.toUri(path), lineInfo, false, errors)
]);
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index 51c7002..88147da 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -189,10 +189,10 @@
/// Call to write any batched up errors from [formatErrors].
void flush();
- void formatError(
+ Future<void> formatError(
Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error);
- void formatErrors(List<ErrorsResult> results) {
+ Future<void> formatErrors(List<ErrorsResult> results) async {
stats.unfilteredCount += results.length;
var errors = <AnalysisError>[];
@@ -207,7 +207,7 @@
}
for (var error in errors) {
- formatError(errorToLine, error);
+ await formatError(errorToLine, error);
}
}
@@ -276,8 +276,8 @@
}
@override
- void formatError(
- Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
+ Future<void> formatError(
+ Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) async {
var source = error.source;
var result = errorToLine[error]!;
var location = result.lineInfo.getLocation(error.offset);
@@ -308,9 +308,10 @@
}
var contextMessages = <ContextMessage>[];
for (var message in error.contextMessages) {
+ // TODO(scheglov) We should add `LineInfo` to `DiagnosticMessage`.
var session = result.session.analysisContext;
if (session is DriverBasedAnalysisContext) {
- var fileResult = session.driver.getFileSync(message.filePath);
+ var fileResult = await session.driver.getFile(message.filePath);
if (fileResult is FileResult) {
var lineInfo = fileResult.lineInfo;
var location = lineInfo.getLocation(message.offset);
@@ -348,13 +349,13 @@
void flush() {}
@override
- void formatError(
- Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
+ Future<void> formatError(
+ Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) async {
throw UnsupportedError('Cannot format a single error');
}
@override
- void formatErrors(List<ErrorsResult> results) {
+ Future<void> formatErrors(List<ErrorsResult> results) async {
Map<String, dynamic> range(
Map<String, dynamic> start, Map<String, dynamic> end) =>
{
@@ -435,8 +436,8 @@
void flush() {}
@override
- void formatError(
- Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
+ Future<void> formatError(
+ Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) async {
// Ensure we don't over-report (#36062).
if (!_seenErrors.add(error)) {
return;
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index 781d1e5..54a2964 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -44,27 +44,27 @@
reporter = HumanErrorFormatter(out, options, stats);
});
- test('error', () {
+ test('error', () async {
var error = mockResult(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
- reporter.formatErrors([error]);
+ await reporter.formatErrors([error]);
reporter.flush();
expect(out.toString().trim(),
'error • MSG • /foo/bar/baz.dart:3:3 • mock_code');
});
- test('hint', () {
+ test('hint', () async {
var error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
- reporter.formatErrors([error]);
+ await reporter.formatErrors([error]);
reporter.flush();
expect(out.toString().trim(),
'hint • MSG • /foo/bar/baz.dart:3:3 • mock_code');
});
- test('stats', () {
+ test('stats', () async {
var error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
- reporter.formatErrors([error]);
+ await reporter.formatErrors([error]);
reporter.flush();
stats.print(out);
expect(
@@ -79,9 +79,9 @@
reporter = JsonErrorFormatter(out, options, stats);
});
- test('error', () {
+ test('error', () async {
var error = mockResult(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
- reporter.formatErrors([error]);
+ await reporter.formatErrors([error]);
reporter.flush();
expect(