Skip to content

Commit 223a2db

Browse files
parloughCommit Queue
authored andcommitted
[linter] Expand on migrated avoid_returning_null_for_void tests
Also adjusts the lint implementation to avoid a few nullable types and non-null assertions. Change-Id: I4199b8ebe94842613c7d8fb322c109c28f194f21 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388500 Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Phil Quitslund <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]> Auto-Submit: Parker Lougheed <[email protected]>
1 parent a17969b commit 223a2db

File tree

2 files changed

+111
-21
lines changed

2 files changed

+111
-21
lines changed

pkg/linter/lib/src/rules/avoid_returning_null_for_void.dart

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ class _Visitor extends SimpleAstVisitor<void> {
4545

4646
@override
4747
void visitReturnStatement(ReturnStatement node) {
48-
if (node.expression != null) {
49-
_visit(node, node.expression);
48+
if (node.expression case var nodeExpression?) {
49+
_visit(node, nodeExpression);
5050
}
5151
}
5252

53-
void _visit(AstNode node, Expression? expression) {
53+
void _visit(AstNode node, Expression expression) {
5454
if (expression is! NullLiteral) {
5555
return;
5656
}
@@ -59,20 +59,19 @@ class _Visitor extends SimpleAstVisitor<void> {
5959
(e) => e is FunctionExpression || e is MethodDeclaration);
6060
if (parent == null) return;
6161

62-
DartType? type;
63-
bool? isAsync;
64-
LintCode code;
65-
if (parent is FunctionExpression) {
66-
type = parent.declaredElement?.returnType;
67-
isAsync = parent.body.isAsynchronous;
68-
code = LinterLintCode.avoid_returning_null_for_void_from_function;
69-
} else if (parent is MethodDeclaration) {
70-
type = parent.declaredElement?.returnType;
71-
isAsync = parent.body.isAsynchronous;
72-
code = LinterLintCode.avoid_returning_null_for_void_from_method;
73-
} else {
74-
throw StateError('unexpected type');
75-
}
62+
var (type, isAsync, code) = switch (parent) {
63+
FunctionExpression() => (
64+
parent.declaredElement?.returnType,
65+
parent.body.isAsynchronous,
66+
LinterLintCode.avoid_returning_null_for_void_from_function,
67+
),
68+
MethodDeclaration() => (
69+
parent.declaredElement?.returnType,
70+
parent.body.isAsynchronous,
71+
LinterLintCode.avoid_returning_null_for_void_from_method,
72+
),
73+
_ => throw StateError('Unexpected type'),
74+
};
7675
if (type == null) return;
7776

7877
if (!isAsync && type is VoidType) {

pkg/linter/test/rules/avoid_returning_null_for_void_test.dart

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ Future<void> f3f() async {
3434
]);
3535
}
3636

37+
test_function_async_returnsFutureVoid_expressionBody_returnNothing() async {
38+
await assertNoDiagnostics(r'''
39+
Future<void> f() async => print('');
40+
''');
41+
}
42+
3743
test_function_async_returnsFutureVoid_expressionBody_returnNull() async {
3844
await assertDiagnostics(r'''
3945
Future<void> f() async => null;
@@ -42,6 +48,36 @@ Future<void> f() async => null;
4248
]);
4349
}
4450

51+
test_function_blockBody_conditional_returnNothing() async {
52+
await assertNoDiagnostics(r'''
53+
void f(bool b) {
54+
if (b) {
55+
return;
56+
}
57+
}
58+
''');
59+
}
60+
61+
test_function_blockBody_conditional_returnNull() async {
62+
await assertDiagnostics(r'''
63+
void f(bool b) {
64+
if (b) {
65+
return null;
66+
}
67+
}
68+
''', [
69+
lint(32, 12),
70+
]);
71+
}
72+
73+
test_function_blockBody_returnNothing() async {
74+
await assertNoDiagnostics(r'''
75+
void f() {
76+
return;
77+
}
78+
''');
79+
}
80+
4581
test_function_blockBody_returnNull() async {
4682
await assertDiagnostics(r'''
4783
void f() {
@@ -52,6 +88,12 @@ void f() {
5288
]);
5389
}
5490

91+
test_function_expressionBody_returnNothing() async {
92+
await assertNoDiagnostics(r'''
93+
void f() => print('');
94+
''');
95+
}
96+
5597
test_function_expressionBody_returnNull() async {
5698
await assertDiagnostics(r'''
5799
void f() => null;
@@ -60,6 +102,13 @@ void f() => null;
60102
]);
61103
}
62104

105+
test_function_expressionBody_returnNullExpressionResult() async {
106+
await assertNoDiagnostics(r'''
107+
Null get nullFromGetter => null;
108+
void f() => nullFromGetter;
109+
''');
110+
}
111+
63112
test_localFunction_async_returnsFutureVoid_blockBody_returnNull() async {
64113
await assertDiagnostics(r'''
65114
void f() {
@@ -94,7 +143,19 @@ void f() {
94143
]);
95144
}
96145

97-
test_method_blockBody_async_returnsFutureVoid_blockBody_returnNull() async {
146+
test_method_class_blockBody_returnNull() async {
147+
await assertDiagnostics(r'''
148+
class C {
149+
void m() {
150+
return null;
151+
}
152+
}
153+
''', [
154+
lint(27, 12),
155+
]);
156+
}
157+
158+
test_method_inClass_blockBody_async_returnsFutureVoid_blockBody_returnNull() async {
98159
await assertDiagnostics(r'''
99160
class C {
100161
Future<void> m() async {
@@ -106,15 +167,45 @@ class C {
106167
]);
107168
}
108169

109-
test_method_blockBody_returnNull() async {
170+
test_method_inExtension_blockBody_returnNull() async {
171+
await assertDiagnostics(r'''
172+
extension E on int {
173+
void f() {
174+
return null;
175+
}
176+
}
177+
''', [lint(38, 12)]);
178+
}
179+
180+
test_method_inExtensionType_blockBody_returnNull() async {
181+
await assertDiagnostics(r'''
182+
extension type E(int i) {
183+
void f() {
184+
return null;
185+
}
186+
}
187+
''', [lint(43, 12)]);
188+
}
189+
190+
test_method_inMixin_blockBody_returnNull() async {
191+
await assertDiagnostics(r'''
192+
mixin M {
193+
void f() {
194+
return null;
195+
}
196+
}
197+
''', [lint(27, 12)]);
198+
}
199+
200+
test_staticMethod_inClass_blockBody_returnNull() async {
110201
await assertDiagnostics(r'''
111202
class C {
112-
void m() {
203+
static void m() {
113204
return null;
114205
}
115206
}
116207
''', [
117-
lint(27, 12),
208+
lint(34, 12),
118209
]);
119210
}
120211
}

0 commit comments

Comments
 (0)