Skip to content
This repository was archived by the owner on Nov 20, 2024. It is now read-only.

Commit f6cf8e8

Browse files
authored
void_checks: Specify individual types which a FutureOr<void> target can accept (#2274)
* void_checks: Specify individual types which a FutureOr<void> target can accept
1 parent b9b523f commit f6cf8e8

File tree

3 files changed

+34
-15
lines changed

3 files changed

+34
-15
lines changed

lib/src/rules/void_checks.dart

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ class VoidChecks extends LintRule implements NodeLintRule {
4242
void registerNodeProcessors(
4343
NodeLintRegistry registry, LinterContext context) {
4444
final visitor = _Visitor(this, context);
45-
registry.addCompilationUnit(this, visitor);
4645
registry.addMethodInvocation(this, visitor);
4746
registry.addInstanceCreationExpression(this, visitor);
4847
registry.addAssignmentExpression(this, visitor);
@@ -56,34 +55,38 @@ class _Visitor extends SimpleAstVisitor<void> {
5655
final LinterContext context;
5756
final TypeSystem typeSystem;
5857

59-
InterfaceType _futureDynamicType;
60-
6158
_Visitor(this.rule, this.context) : typeSystem = context.typeSystem;
6259

6360
bool isTypeAcceptableWhenExpectingVoid(DartType type) {
6461
if (type.isVoid) return true;
6562
if (type.isDartCoreNull) return true;
6663
if (type.isDartAsyncFuture &&
6764
type is InterfaceType &&
68-
(type.typeArguments.first.isVoid ||
69-
type.typeArguments.first.isDartCoreNull)) {
65+
isTypeAcceptableWhenExpectingVoid(type.typeArguments.first)) {
7066
return true;
7167
}
7268
return false;
7369
}
7470

71+
bool isTypeAcceptableWhenExpectingFutureOrVoid(DartType type) {
72+
if (type.isDynamic) return true;
73+
if (isTypeAcceptableWhenExpectingVoid(type)) return true;
74+
if (type.isDartAsyncFutureOr &&
75+
type is InterfaceType &&
76+
isTypeAcceptableWhenExpectingFutureOrVoid(type.typeArguments.first)) {
77+
return true;
78+
}
79+
80+
return false;
81+
}
82+
7583
@override
7684
void visitAssignmentExpression(AssignmentExpression node) {
7785
final type = node.writeType;
7886
_check(type, node.rightHandSide?.staticType, node,
7987
checkedNode: node.rightHandSide);
8088
}
8189

82-
@override
83-
void visitCompilationUnit(CompilationUnit node) {
84-
_futureDynamicType = context.typeProvider.futureDynamicType;
85-
}
86-
8790
@override
8891
void visitInstanceCreationExpression(InstanceCreationExpression node) {
8992
final args = node.argumentList.arguments;
@@ -131,11 +134,12 @@ class _Visitor extends SimpleAstVisitor<void> {
131134
checkedNode ??= node;
132135
if (expectedType == null || type == null) {
133136
return;
134-
} else if (expectedType.isVoid &&
135-
!isTypeAcceptableWhenExpectingVoid(type) ||
136-
expectedType.isDartAsyncFutureOr &&
137-
(expectedType as InterfaceType).typeArguments.first.isVoid &&
138-
!typeSystem.isAssignableTo(type, _futureDynamicType)) {
137+
}
138+
if (expectedType.isVoid && !isTypeAcceptableWhenExpectingVoid(type)) {
139+
rule.reportLint(node);
140+
} else if (expectedType.isDartAsyncFutureOr &&
141+
(expectedType as InterfaceType).typeArguments.first.isVoid &&
142+
!isTypeAcceptableWhenExpectingFutureOrVoid(type)) {
139143
rule.reportLint(node);
140144
} else if (checkedNode is FunctionExpression &&
141145
checkedNode.body is! ExpressionFunctionBody &&
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// test w/ `pub run test -N void_checks`
6+
7+
import 'dart:async';
8+
9+
void emptyFunctionExpressionReturningFutureOrVoid(FutureOr<void> Function() f) {
10+
f = () {}; // OK
11+
}

test/rules/void_checks.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,7 @@ missing_parameter_for_argument() {
207207
void foo() {}
208208
foo(0);
209209
}
210+
211+
void emptyFunctionExpressionReturningFutureOrVoid(FutureOr<void> Function() f) {
212+
f = () {}; // OK
213+
}

0 commit comments

Comments
 (0)