Skip to content

Commit db25ef8

Browse files
Report unnecessary !
Change-Id: Ie5fbe1e7697c2911eb9ff931bcf5d2e1cef9d171 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108944 Auto-Submit: Mike Fairhurst <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent ac45f46 commit db25ef8

File tree

7 files changed

+76
-13
lines changed

7 files changed

+76
-13
lines changed

pkg/analyzer/lib/error/error.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,7 @@ const List<ErrorCode> errorCodeValues = const [
703703
StaticWarningCode.UNDEFINED_IDENTIFIER,
704704
StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT,
705705
StaticWarningCode.UNDEFINED_NAMED_PARAMETER,
706+
StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION,
706707
StaticWarningCode.UNNECESSARY_NULL_AWARE_CALL,
707708
StaticWarningCode.UNNECESSARY_NULL_AWARE_SPREAD,
708709
StaticWarningCode.USE_OF_VOID_RESULT,

pkg/analyzer/lib/src/error/codes.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5480,6 +5480,17 @@ class StaticWarningCode extends ErrorCode {
54805480
correction:
54815481
"Try casting or check the value is not null before using it.");
54825482

5483+
/**
5484+
* When the '!' operator is used on a value that we know to be non-null,
5485+
* it is unnecessary.
5486+
*/
5487+
static const StaticWarningCode UNNECESSARY_NON_NULL_ASSERTION =
5488+
const StaticWarningCode(
5489+
'UNNECESSARY_NON_NULL_ASSERTION',
5490+
"The '!' will have no effect because the target expression cannot be"
5491+
" null.",
5492+
correction: "Try removing the '!' operator here.");
5493+
54835494
/**
54845495
* When the '...?' operator is used on a value that we know to be non-null,
54855496
* it is unnecessary.

pkg/analyzer/lib/src/generated/error_verifier.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,12 +1167,13 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
11671167

11681168
@override
11691169
void visitPostfixExpression(PostfixExpression node) {
1170-
if (node.operator.type != TokenType.BANG) {
1170+
if (node.operator.type == TokenType.BANG) {
1171+
_checkForUseOfVoidResult(node);
1172+
_checkForUnnecessaryNullAware(node.operand, node.operator);
1173+
} else {
11711174
_checkForAssignmentToFinal(node.operand);
11721175
_checkForIntNotAssignable(node.operand);
11731176
_checkForNullableDereference(node.operand);
1174-
} else {
1175-
_checkForUseOfVoidResult(node);
11761177
}
11771178
super.visitPostfixExpression(node);
11781179
}
@@ -5655,6 +5656,8 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
56555656
errorCode = StaticWarningCode.UNNECESSARY_NULL_AWARE_CALL;
56565657
} else if (operator.type == TokenType.PERIOD_PERIOD_PERIOD_QUESTION) {
56575658
errorCode = StaticWarningCode.UNNECESSARY_NULL_AWARE_SPREAD;
5659+
} else if (operator.type == TokenType.BANG) {
5660+
errorCode = StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION;
56585661
} else {
56595662
return;
56605663
}

pkg/analyzer/test/src/diagnostics/test_all.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ import 'undefined_setter_test.dart' as undefined_setter;
203203
import 'undefined_shown_name_test.dart' as undefined_shown_name;
204204
import 'unnecessary_cast_test.dart' as unnecessary_cast;
205205
import 'unnecessary_no_such_method_test.dart' as unnecessary_no_such_method;
206+
import 'unnecessary_non_null_assertion_test.dart'
207+
as unnecessary_non_null_assertion;
206208
import 'unnecessary_null_aware_call_test.dart' as unnecessary_null_aware_call;
207209
import 'unnecessary_null_aware_spread_test.dart'
208210
as unnecessary_null_aware_spread;
@@ -368,6 +370,7 @@ main() {
368370
undefined_shown_name.main();
369371
unnecessary_cast.main();
370372
unnecessary_no_such_method.main();
373+
unnecessary_non_null_assertion.main();
371374
unnecessary_null_aware_call.main();
372375
unnecessary_null_aware_spread.main();
373376
unnecessary_type_check_false.main();
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2019, 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+
import 'package:analyzer/src/dart/analysis/experiments.dart';
6+
import 'package:analyzer/src/error/codes.dart';
7+
import 'package:analyzer/src/generated/engine.dart';
8+
import 'package:test_reflective_loader/test_reflective_loader.dart';
9+
10+
import '../dart/resolution/driver_resolution.dart';
11+
12+
main() {
13+
defineReflectiveSuite(() {
14+
defineReflectiveTests(UnnecessaryNonNullAssertionTest);
15+
});
16+
}
17+
18+
@reflectiveTest
19+
class UnnecessaryNonNullAssertionTest extends DriverResolutionTest {
20+
@override
21+
AnalysisOptionsImpl get analysisOptions =>
22+
AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
23+
24+
test_parameter_nonNull() async {
25+
await assertErrorsInCode('''
26+
f(int x) {
27+
x!;
28+
}
29+
''', [
30+
error(StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION, 14, 1),
31+
]);
32+
}
33+
34+
test_parameter_nullable() async {
35+
await assertNoErrorsInCode('''
36+
f(int? x) {
37+
x!;
38+
}
39+
''');
40+
}
41+
}

tests/language_2/nnbd/static_errors/bang_test.dart renamed to tests/language_2/nnbd/static_errors/non_null_assertion_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@
55
// SharedOptions=--enable-experiment=non-nullable
66
void main() {
77
void x;
8+
int i;
9+
int? iq;
810
x!; //# 00: compile-time error
11+
i!; //# 01: compile-time error
12+
iq!; //# 02: ok
913
}

tests/language_2/nnbd/syntax/null_assertion_test.dart renamed to tests/language_2/nnbd/syntax/non_null_assertion_test.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,31 @@ Object? f() => null;
2525
main() {
2626
List<Object> listOfObject = [];
2727

28-
var x1 = [0!];
28+
var x1 = [0!]; // ignore: unnecessary_non_null_assertion
2929
listOfObject = x1;
3030

31-
var x2 = [true!];
31+
var x2 = [true!]; // ignore: unnecessary_non_null_assertion
3232
listOfObject = x2;
3333

34-
var x3 = ["foo"!];
34+
var x3 = ["foo"!]; // ignore: unnecessary_non_null_assertion
3535
listOfObject = x3;
3636

37-
var x4 = [#foo!];
37+
var x4 = [#foo!]; // ignore: unnecessary_non_null_assertion
3838
listOfObject = x4;
3939

40-
var x5 = [[1]!];
40+
var x5 = [[1]!]; // ignore: unnecessary_non_null_assertion
4141
listOfObject = x5;
4242

43-
var x6 = [{1:2}!];
43+
var x6 = [{1:2}!]; // ignore: unnecessary_non_null_assertion
4444
listOfObject = x6;
4545

46-
var x7 = [{1}!];
46+
var x7 = [{1}!]; // ignore: unnecessary_non_null_assertion
4747
listOfObject = x7;
4848

49-
var x8 = [new C()!];
49+
var x8 = [new C()!]; // ignore: unnecessary_non_null_assertion
5050
listOfObject = x8;
5151

52-
var x9 = [const C()!];
52+
var x9 = [const C()!]; // ignore: unnecessary_non_null_assertion
5353
listOfObject = x9;
5454

5555
Expect.throws(() {
@@ -70,6 +70,6 @@ main() {
7070
});
7171

7272
int i = 0;
73-
var x13 = [i++!];
73+
var x13 = [i++!]; // ignore: unnecessary_non_null_assertion
7474
listOfObject = x13;
7575
}

0 commit comments

Comments
 (0)