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

Commit 07c4d17

Browse files
authored
declared variable pattern support for unnecessary_final (#4152)
1 parent 61818a5 commit 07c4d17

File tree

3 files changed

+94
-13
lines changed

3 files changed

+94
-13
lines changed

lib/src/rules/unnecessary_final.dart

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class UnnecessaryFinal extends LintRule {
7171
registry
7272
..addFormalParameterList(this, visitor)
7373
..addForStatement(this, visitor)
74+
..addDeclaredVariablePattern(this, visitor)
7475
..addVariableDeclarationStatement(this, visitor);
7576
}
7677
}
@@ -80,18 +81,29 @@ class _Visitor extends SimpleAstVisitor<void> {
8081

8182
_Visitor(this.rule);
8283

84+
LintCode getErrorCode(Object? type) =>
85+
type == null ? UnnecessaryFinal.withoutType : UnnecessaryFinal.withType;
86+
87+
@override
88+
void visitDeclaredVariablePattern(DeclaredVariablePattern node) {
89+
var keyword = node.keyword;
90+
keyword ??=
91+
node.thisOrAncestorOfType<PatternVariableDeclaration>()?.keyword;
92+
if (keyword == null) return;
93+
94+
var errorCode = getErrorCode(node.matchedValueType);
95+
rule.reportLintForToken(keyword, errorCode: errorCode);
96+
}
97+
8398
@override
8499
void visitFormalParameterList(FormalParameterList parameterList) {
85100
for (var node in parameterList.parameters) {
86101
if (node.isFinal) {
87102
var keyword = _getFinal(node);
88-
if (keyword == null) {
89-
continue;
90-
}
103+
if (keyword == null) continue;
104+
91105
var type = _getType(node);
92-
var errorCode = type == null
93-
? UnnecessaryFinal.withoutType
94-
: UnnecessaryFinal.withType;
106+
var errorCode = getErrorCode(type);
95107
rule.reportLintForToken(keyword, errorCode: errorCode);
96108
}
97109
}
@@ -106,11 +118,8 @@ class _Visitor extends SimpleAstVisitor<void> {
106118
// loop. `a` is a variable declared outside the loop.
107119
if (forLoopParts is ForEachPartsWithDeclaration) {
108120
var loopVariable = forLoopParts.loopVariable;
109-
110121
if (loopVariable.isFinal) {
111-
var errorCode = loopVariable.type == null
112-
? UnnecessaryFinal.withoutType
113-
: UnnecessaryFinal.withType;
122+
var errorCode = getErrorCode(loopVariable.type);
114123
rule.reportLintForToken(loopVariable.keyword, errorCode: errorCode);
115124
}
116125
}
@@ -119,9 +128,7 @@ class _Visitor extends SimpleAstVisitor<void> {
119128
@override
120129
void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
121130
if (node.variables.isFinal) {
122-
var errorCode = node.variables.type == null
123-
? UnnecessaryFinal.withoutType
124-
: UnnecessaryFinal.withType;
131+
var errorCode = getErrorCode(node.variables.type);
125132
rule.reportLintForToken(node.variables.keyword, errorCode: errorCode);
126133
}
127134
}

test/rules/all.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ import 'unnecessary_brace_in_string_interps_test.dart'
101101
as unnecessary_brace_in_string_interps;
102102
import 'unnecessary_breaks_test.dart' as unnecessary_breaks;
103103
import 'unnecessary_const_test.dart' as unnecessary_const;
104+
import 'unnecessary_final_test.dart' as unnecessary_final;
104105
import 'unnecessary_lambdas_test.dart' as unnecessary_lambdas;
105106
import 'unnecessary_library_directive_test.dart'
106107
as unnecessary_library_directive;
@@ -194,6 +195,7 @@ void main() {
194195
unnecessary_brace_in_string_interps.main();
195196
unnecessary_breaks.main();
196197
unnecessary_const.main();
198+
unnecessary_final.main();
197199
unnecessary_lambdas.main();
198200
unnecessary_library_directive.main();
199201
unnecessary_null_checks.main();
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright (c) 2023, 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:test_reflective_loader/test_reflective_loader.dart';
6+
7+
import '../rule_test_support.dart';
8+
9+
main() {
10+
defineReflectiveSuite(() {
11+
defineReflectiveTests(UnnecessaryFinalTestLanguage300);
12+
});
13+
}
14+
15+
@reflectiveTest
16+
class UnnecessaryFinalTestLanguage300 extends LintRuleTest
17+
with LanguageVersion300Mixin {
18+
@override
19+
String get lintRule => 'unnecessary_final';
20+
21+
test_listPattern_destructured() async {
22+
await assertDiagnostics(r'''
23+
f() {
24+
final [a] = [1];
25+
print('$a');
26+
}
27+
''', [
28+
lint(8, 5),
29+
]);
30+
}
31+
32+
test_mapPattern_destructured() async {
33+
await assertDiagnostics(r'''
34+
f() {
35+
final {'a': a} = {'a': 1};
36+
print('$a');
37+
}
38+
''', [
39+
lint(8, 5),
40+
]);
41+
}
42+
43+
test_objectPattern_switch() async {
44+
await assertDiagnostics(r'''
45+
class A {
46+
int a;
47+
A(this.a);
48+
}
49+
50+
f() {
51+
switch (A(1)) {
52+
case A(a: >0 && final b): print('$b');
53+
}
54+
}
55+
''', [
56+
lint(79, 5),
57+
]);
58+
}
59+
60+
test_recordPattern_switch() async {
61+
await assertDiagnostics(r'''
62+
f() {
63+
switch ((1, 2)) {
64+
case (final a, final b): print('$a$b');
65+
}
66+
}
67+
''', [
68+
lint(36, 5),
69+
lint(45, 5),
70+
]);
71+
}
72+
}

0 commit comments

Comments
 (0)