Skip to content

Commit f2b5ba8

Browse files
asashourCommit Bot
authored and
Commit Bot
committed
Add a hint for final FieldFormalParameter and SuperFormalParameter
Fixes #48699 Change-Id: Ieb16648a52884588e406931f830e4655b120cb0c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239640 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent dafe470 commit f2b5ba8

File tree

8 files changed

+104
-0
lines changed

8 files changed

+104
-0
lines changed

pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,8 @@ HintCode.UNIGNORABLE_IGNORE:
14171417
status: needsEvaluation
14181418
HintCode.UNNECESSARY_CAST:
14191419
status: hasFix
1420+
HintCode.UNNECESSARY_FINAL:
1421+
status: needsEvaluation
14201422
HintCode.UNNECESSARY_IGNORE:
14211423
status: needsEvaluation
14221424
HintCode.UNNECESSARY_IMPORT:

pkg/analyzer/lib/error/error.dart

+1
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ const List<ErrorCode> errorCodeValues = [
655655
HintCode.UNDEFINED_SHOWN_NAME,
656656
HintCode.UNIGNORABLE_IGNORE,
657657
HintCode.UNNECESSARY_CAST,
658+
HintCode.UNNECESSARY_FINAL,
658659
HintCode.UNNECESSARY_IGNORE,
659660
HintCode.UNNECESSARY_IMPORT,
660661
HintCode.UNNECESSARY_NO_SUCH_METHOD,

pkg/analyzer/lib/src/dart/error/hint_codes.g.dart

+10
Original file line numberDiff line numberDiff line change
@@ -3777,6 +3777,16 @@ class HintCode extends AnalyzerErrorCode {
37773777
hasPublishedDocs: true,
37783778
);
37793779

3780+
/**
3781+
* No parameters.
3782+
*/
3783+
static const HintCode UNNECESSARY_FINAL = HintCode(
3784+
'UNNECESSARY_FINAL',
3785+
"The keyword 'final' isn't necessary because the parameter is implicitly "
3786+
"'final'.",
3787+
correctionMessage: "Try removing the 'final'.",
3788+
);
3789+
37803790
/**
37813791
* Parameters:
37823792
* 0: the name of the diagnostic being ignored

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

+21
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,12 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
487487
}
488488
}
489489

490+
@override
491+
void visitFieldFormalParameter(FieldFormalParameter node) {
492+
_checkFinalParameter(node, node.keyword);
493+
super.visitFieldFormalParameter(node);
494+
}
495+
490496
@override
491497
void visitFormalParameterList(FormalParameterList node) {
492498
_checkRequiredParameter(node);
@@ -775,6 +781,12 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
775781
super.visitSuperConstructorInvocation(node);
776782
}
777783

784+
@override
785+
void visitSuperFormalParameter(SuperFormalParameter node) {
786+
_checkFinalParameter(node, node.keyword);
787+
super.visitSuperFormalParameter(node);
788+
}
789+
778790
@override
779791
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
780792
_deprecatedVerifier.pushInDeprecatedMetadata(node.metadata);
@@ -856,6 +868,15 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
856868
return false;
857869
}
858870

871+
void _checkFinalParameter(FormalParameter node, Token? keyword) {
872+
if (node.isFinal) {
873+
_errorReporter.reportErrorForToken(
874+
HintCode.UNNECESSARY_FINAL,
875+
keyword!,
876+
);
877+
}
878+
}
879+
859880
void _checkForAssignmentOfDoNotStore(Expression? expression) {
860881
var expressionMap = _getSubExpressionsMarkedDoNotStore(expression);
861882
for (var entry in expressionMap.entries) {

pkg/analyzer/messages.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -20414,6 +20414,11 @@ HintCode:
2041420414
}
2041520415
}
2041620416
```
20417+
UNNECESSARY_FINAL:
20418+
problemMessage: The keyword 'final' isn't necessary because the parameter is implicitly 'final'.
20419+
correctionMessage: Try removing the 'final'.
20420+
hasPublishedDocs: false
20421+
comment: No parameters.
2041720422
UNNECESSARY_IGNORE:
2041820423
problemMessage: "The diagnostic '{0}' isn't produced at this location so it doesn't need to be ignored."
2041920424
correctionMessage: Try removing the name from the list, or removing the whole comment if this is the only name in the list.

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

+2
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ import 'undefined_super_operator_test.dart' as undefined_super_operator;
751751
import 'undefined_super_setter_test.dart' as undefined_super_setter;
752752
import 'unignorable_ignore_test.dart' as unignorable_ignore;
753753
import 'unnecessary_cast_test.dart' as unnecessary_cast;
754+
import 'unnecessary_final_test.dart' as unnecessary_final;
754755
import 'unnecessary_ignore_test.dart' as unnecessary_ignore;
755756
import 'unnecessary_import_test.dart' as unnecessary_import;
756757
import 'unnecessary_no_such_method_test.dart' as unnecessary_no_such_method;
@@ -1294,6 +1295,7 @@ main() {
12941295
unignorable_ignore.main();
12951296
unnecessary_import.main();
12961297
unnecessary_cast.main();
1298+
unnecessary_final.main();
12971299
unnecessary_ignore.main();
12981300
unnecessary_no_such_method.main();
12991301
unnecessary_non_null_assertion.main();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (c) 2022, 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/error/codes.dart';
6+
import 'package:test_reflective_loader/test_reflective_loader.dart';
7+
8+
import '../dart/resolution/context_collection_resolution.dart';
9+
10+
main() {
11+
defineReflectiveSuite(() {
12+
defineReflectiveTests(UnnecessaryFinalTest);
13+
});
14+
}
15+
16+
@reflectiveTest
17+
class UnnecessaryFinalTest extends PubPackageResolutionTest {
18+
test_final() async {
19+
await assertNoErrorsInCode('''
20+
class C {
21+
C(final int value);
22+
}
23+
''');
24+
}
25+
26+
test_positional() async {
27+
await assertErrorsInCode('''
28+
class C {
29+
C([final this.value = 0]);
30+
int value;
31+
}
32+
''', [
33+
error(HintCode.UNNECESSARY_FINAL, 15, 5),
34+
]);
35+
}
36+
37+
test_super() async {
38+
await assertErrorsInCode('''
39+
class A {
40+
A(this.value);
41+
int value;
42+
}
43+
44+
class B extends A {
45+
B(final super.value);
46+
}
47+
''', [
48+
error(HintCode.UNNECESSARY_FINAL, 67, 5),
49+
]);
50+
}
51+
52+
test_this() async {
53+
await assertErrorsInCode('''
54+
class C {
55+
C(final this.value);
56+
int value;
57+
}
58+
''', [
59+
error(HintCode.UNNECESSARY_FINAL, 14, 5),
60+
]);
61+
}
62+
}

pkg/nnbd_migration/test/fix_aggregator_test.dart

+1
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,7 @@ class C {
14131413

14141414
Future<void>
14151415
test_parameter_field_formal_addExplicitType_declared_with_final() async {
1416+
verifyNoTestUnitErrors = false;
14161417
await analyze('''
14171418
class C {
14181419
int x;

0 commit comments

Comments
 (0)