Skip to content

Commit 5794e71

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Make AnalysisSession.getErrors() non-nullable.
Change-Id: Ib5971e4c7327d96bf7a08b576b487833615d4ae6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/189622 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 1601f6f commit 5794e71

File tree

11 files changed

+113
-17
lines changed

11 files changed

+113
-17
lines changed

pkg/analyzer/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## 1.2.0
1+
## 1.2.0-dev
22
* Deprecated all setters in API of AST. Use `parseString()` instead.
3+
* `AnalysisSession.getErrors()` does not return `null`, check its `state`.
34

45
## 1.1.0
56
* Deprecated `TypeProvider.futureType2()`, `iterableType2()`, etc.

pkg/analyzer/example/analyze.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void main(List<String> args) async {
3131
continue;
3232
}
3333

34-
final errorsResult = (await context.currentSession.getErrors(filePath))!;
34+
final errorsResult = await context.currentSession.getErrors(filePath);
3535
for (final error in errorsResult.errors) {
3636
if (error.errorCode.type != ErrorType.TODO) {
3737
print(

pkg/analyzer/lib/dart/analysis/results.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,20 @@ import 'package:analyzer/src/generated/source.dart';
1616
/// Clients may not extend, implement or mix-in this class.
1717
abstract class AnalysisResult {
1818
/// The absolute and normalized path of the file that was analyzed.
19+
/// If [state] is not [ResultState.VALID], throws [StateError].
1920
///
2021
/// TODO(migration): should not be nullable
2122
String? get path;
2223

2324
/// Return the session used to compute this result.
25+
/// If [state] is not [ResultState.VALID], throws [StateError].
2426
AnalysisSession get session;
2527

2628
/// The state of the results.
2729
ResultState get state;
2830

2931
/// The absolute URI of the file that was analyzed.
32+
/// If [state] is not [ResultState.VALID], throws [StateError].
3033
Uri get uri;
3134
}
3235

@@ -35,6 +38,7 @@ abstract class AnalysisResult {
3538
/// Clients may not extend, implement or mix-in this class.
3639
abstract class AnalysisResultWithErrors implements FileResult {
3740
/// The analysis errors that were computed during analysis.
41+
/// If [state] is not [ResultState.VALID], throws [StateError].
3842
List<AnalysisError> get errors;
3943
}
4044

@@ -69,9 +73,11 @@ abstract class ErrorsResult implements AnalysisResultWithErrors {}
6973
/// Clients may not extend, implement or mix-in this class.
7074
abstract class FileResult implements AnalysisResult {
7175
/// Whether the file is a part.
76+
/// If [state] is not [ResultState.VALID], throws [StateError].
7277
bool get isPart;
7378

7479
/// Information about lines in the content.
80+
/// If [state] is not [ResultState.VALID], throws [StateError].
7581
LineInfo get lineInfo;
7682
}
7783

@@ -174,6 +180,14 @@ enum ResultState {
174180
/// directory, or it might not represent anything.
175181
NOT_A_FILE,
176182

183+
/// An indication that analysis could not be performed because the path does
184+
/// not represent the corresponding URI.
185+
///
186+
/// This usually happens in Bazel workspaces, when a URI is resolved to
187+
/// a generated file, but there is also a writable file to which this URI
188+
/// would be resolved, if there were no generated file.
189+
NOT_FILE_OF_URI,
190+
177191
/// An indication that analysis completed normally and the results are valid.
178192
VALID
179193
}

pkg/analyzer/lib/dart/analysis/session.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ abstract class AnalysisSession {
3636
///
3737
/// If the file cannot be analyzed by this session, then the result will have
3838
/// a result state indicating the nature of the problem.
39-
///
40-
/// TODO(migration): should not be nullable
41-
Future<ErrorsResult?> getErrors(String path);
39+
Future<ErrorsResult> getErrors(String path);
4240

4341
/// Return information about the file at the given absolute, normalized
4442
/// [path].

pkg/analyzer/lib/src/dart/analysis/driver.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,10 +556,10 @@ class AnalysisDriver implements AnalysisDriverGeneric {
556556
///
557557
/// This method does not use analysis priorities, and must not be used in
558558
/// interactive analysis, such as Analysis Server or its plugins.
559-
Future<ErrorsResult?> getErrors(String path) async {
559+
Future<ErrorsResult> getErrors(String path) async {
560560
_throwIfNotAbsolutePath(path);
561561
if (!_fsState.hasUri(path)) {
562-
return null;
562+
return NotValidErrorsResultImpl(ResultState.NOT_FILE_OF_URI);
563563
}
564564

565565
var completer = Completer<ErrorsResult>();

pkg/analyzer/lib/src/dart/analysis/results.dart

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,56 @@ class FileResultImpl extends AnalysisResultImpl implements FileResult {
6666
ResultState get state => ResultState.VALID;
6767
}
6868

69+
/// The implementation of [AnalysisResult] when not [ResultState.VALID].
70+
class NotValidAnalysisResultImpl implements AnalysisResult {
71+
@override
72+
final ResultState state;
73+
74+
NotValidAnalysisResultImpl(this.state);
75+
76+
@override
77+
String? get path {
78+
throw StateError('This result is not valid');
79+
}
80+
81+
@override
82+
AnalysisSession get session {
83+
throw StateError('This result is not valid');
84+
}
85+
86+
@override
87+
Uri get uri {
88+
throw StateError('This result is not valid');
89+
}
90+
}
91+
92+
/// The implementation of [ErrorsResult] when not [ResultState.VALID].
93+
class NotValidErrorsResultImpl extends NotValidFileResultImpl
94+
implements ErrorsResult {
95+
NotValidErrorsResultImpl(ResultState state) : super(state);
96+
97+
@override
98+
List<AnalysisError> get errors {
99+
throw StateError('This result is not valid');
100+
}
101+
}
102+
103+
/// The implementation of [FileResult] when not [ResultState.VALID].
104+
class NotValidFileResultImpl extends NotValidAnalysisResultImpl
105+
implements FileResult {
106+
NotValidFileResultImpl(ResultState state) : super(state);
107+
108+
@override
109+
bool get isPart {
110+
throw StateError('This result is not valid');
111+
}
112+
113+
@override
114+
LineInfo get lineInfo {
115+
throw StateError('This result is not valid');
116+
}
117+
}
118+
69119
class ParsedLibraryResultImpl extends AnalysisResultImpl
70120
implements ParsedLibraryResult {
71121
@override

pkg/analyzer/lib/src/dart/analysis/session.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class AnalysisSessionImpl implements AnalysisSession {
5959
driver.AnalysisDriver getDriver() => _driver;
6060

6161
@override
62-
Future<ErrorsResult?> getErrors(String path) {
62+
Future<ErrorsResult> getErrors(String path) {
6363
_checkConsistency();
6464
return _driver.getErrors(path);
6565
}

pkg/analyzer/lib/src/lint/analysis.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ class LintDriver {
201201

202202
List<AnalysisErrorInfo> errors = [];
203203
for (Source source in sources) {
204-
var errorsResult = (await analysisDriver.getErrors(source.fullName))!;
204+
var errorsResult = await analysisDriver.getErrors(source.fullName);
205205
errors.add(
206206
AnalysisErrorInfoImpl(errorsResult.errors, errorsResult.lineInfo));
207207
_sourcesAnalyzed.add(source);

pkg/analyzer/test/src/dart/analysis/driver_test.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ bbb() {}
11561156
String content = 'int f() => 42 + bar();';
11571157
addTestFile(content, priority: true);
11581158

1159-
var result = (await driver.getErrors(testFile))!;
1159+
var result = await driver.getErrors(testFile);
11601160
expect(result.path, testFile);
11611161
expect(result.uri.toString(), 'package:test/test.dart');
11621162
expect(result.errors, hasLength(1));
@@ -2212,7 +2212,7 @@ import 'b.dart';
22122212
getFile(asyncPath).delete();
22132213
addTestFile('class C {}');
22142214

2215-
ErrorsResult result = (await driver.getErrors(testFile))!;
2215+
ErrorsResult result = await driver.getErrors(testFile);
22162216
expect(result.errors, hasLength(1));
22172217

22182218
AnalysisError error = result.errors[0];
@@ -2224,7 +2224,7 @@ import 'b.dart';
22242224
getFile(corePath).delete();
22252225
addTestFile('class C {}');
22262226

2227-
ErrorsResult result = (await driver.getErrors(testFile))!;
2227+
ErrorsResult result = await driver.getErrors(testFile);
22282228
expect(result.errors, hasLength(1));
22292229

22302230
AnalysisError error = result.errors[0];
@@ -2452,13 +2452,13 @@ var b = new B();
24522452

24532453
// Process a.dart so that we know that it's a library for c.dart later.
24542454
{
2455-
ErrorsResult result = (await driver.getErrors(a))!;
2455+
ErrorsResult result = await driver.getErrors(a);
24562456
expect(result.errors, isEmpty);
24572457
}
24582458

24592459
// c.dart does not have errors in the context of a.dart
24602460
{
2461-
ErrorsResult result = (await driver.getErrors(c))!;
2461+
ErrorsResult result = await driver.getErrors(c);
24622462
expect(result.errors, isEmpty);
24632463
}
24642464
}
@@ -2488,7 +2488,7 @@ var b = new B();
24882488

24892489
// c.dart is resolve in the context of a.dart, so have no errors
24902490
{
2491-
ErrorsResult result = (await driver.getErrors(c))!;
2491+
ErrorsResult result = await driver.getErrors(c);
24922492
expect(result.errors, isEmpty);
24932493
}
24942494
}

pkg/analyzer/test/src/dart/analysis/session_test.dart

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:analyzer/dart/analysis/analysis_context.dart';
66
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
7+
import 'package:analyzer/dart/analysis/results.dart';
78
import 'package:analyzer/dart/ast/ast.dart';
89
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
910
import 'package:analyzer/src/dart/analysis/session.dart';
@@ -13,12 +14,44 @@ import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
1314
import 'package:test/test.dart';
1415
import 'package:test_reflective_loader/test_reflective_loader.dart';
1516

17+
import '../resolution/context_collection_resolution.dart';
18+
1619
main() {
1720
defineReflectiveSuite(() {
1821
defineReflectiveTests(AnalysisSessionImplTest);
22+
defineReflectiveTests(AnalysisSessionImpl_BazelWorkspaceTest);
1923
});
2024
}
2125

26+
@reflectiveTest
27+
class AnalysisSessionImpl_BazelWorkspaceTest
28+
extends BazelWorkspaceResolutionTest {
29+
void test_getErrors_notFileOfUri() async {
30+
var relPath = 'dart/my/lib/a.dart';
31+
newFile('$workspaceRootPath/bazel-bin/$relPath');
32+
33+
var path = '$workspaceRootPath/$relPath';
34+
var session = contextFor(path).currentSession;
35+
var result = await session.getErrors(path);
36+
expect(result.state, ResultState.NOT_FILE_OF_URI);
37+
expect(() => result.errors, throwsStateError);
38+
}
39+
40+
void test_getErrors_valid() async {
41+
var file = newFile(
42+
'$workspaceRootPath/dart/my/lib/a.dart',
43+
content: 'var x = 0',
44+
);
45+
46+
var session = contextFor(file.path).currentSession;
47+
var result = await session.getErrors(file.path);
48+
expect(result.state, ResultState.VALID);
49+
expect(result.path, file.path);
50+
expect(result.errors, hasLength(1));
51+
expect(result.uri.toString(), 'package:dart.my/a.dart');
52+
}
53+
}
54+
2255
@reflectiveTest
2356
class AnalysisSessionImplTest with ResourceProviderMixin {
2457
late final AnalysisContextCollection contextCollection;
@@ -55,7 +88,7 @@ test:lib/
5588

5689
test_getErrors() async {
5790
newFile(testPath, content: 'class C {');
58-
var errorsResult = (await session.getErrors(testPath))!;
91+
var errorsResult = await session.getErrors(testPath);
5992
expect(errorsResult.session, session);
6093
expect(errorsResult.path, testPath);
6194
expect(errorsResult.errors, isNotEmpty);

0 commit comments

Comments
 (0)