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

Commit 8891764

Browse files
authored
pattern assignment support for parameter_assignments (#4212)
1 parent 9430584 commit 8891764

File tree

2 files changed

+115
-6
lines changed

2 files changed

+115
-6
lines changed

lib/src/rules/parameter_assignments.dart

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:analyzer/dart/ast/ast.dart';
66
import 'package:analyzer/dart/ast/visitor.dart';
7+
import 'package:analyzer/dart/element/element.dart';
78

89
import '../analyzer.dart';
910

@@ -125,16 +126,48 @@ class _DeclarationVisitor extends RecursiveAstVisitor {
125126
{required this.paramIsNotNullByDefault,
126127
required this.paramDefaultsToNull});
127128

129+
Element? get parameterElement => parameter.declaredElement;
130+
131+
void checkPatternElements(DartPattern node) {
132+
NodeList<PatternField>? fields;
133+
if (node is RecordPattern) fields = node.fields;
134+
if (node is ObjectPattern) fields = node.fields;
135+
if (fields != null) {
136+
for (var field in fields) {
137+
if (field.pattern.element == parameterElement) {
138+
reportLint(node);
139+
}
140+
}
141+
} else {
142+
List<AstNode>? elements;
143+
if (node is ListPattern) elements = node.elements;
144+
if (node is MapPattern) elements = node.elements;
145+
if (elements == null) return;
146+
for (var element in elements) {
147+
if (element is MapPatternEntry) {
148+
element = element.value;
149+
}
150+
if (element.element == parameterElement) {
151+
reportLint(node);
152+
}
153+
}
154+
}
155+
}
156+
157+
void reportLint(AstNode node) {
158+
rule.reportLint(node, arguments: [parameter.name!.lexeme]);
159+
}
160+
128161
@override
129162
visitAssignmentExpression(AssignmentExpression node) {
130163
if (paramIsNotNullByDefault) {
131164
if (_isFormalParameterReassigned(parameter, node)) {
132-
rule.reportLint(node, arguments: [parameter.name!.lexeme]);
165+
reportLint(node);
133166
}
134167
} else if (paramDefaultsToNull) {
135168
if (_isFormalParameterReassigned(parameter, node)) {
136169
if (hasBeenAssigned) {
137-
rule.reportLint(node, arguments: [parameter.name!.lexeme]);
170+
reportLint(node);
138171
}
139172
hasBeenAssigned = true;
140173
}
@@ -143,13 +176,20 @@ class _DeclarationVisitor extends RecursiveAstVisitor {
143176
super.visitAssignmentExpression(node);
144177
}
145178

179+
@override
180+
visitPatternAssignment(PatternAssignment node) {
181+
checkPatternElements(node.pattern);
182+
183+
super.visitPatternAssignment(node);
184+
}
185+
146186
@override
147187
visitPostfixExpression(PostfixExpression node) {
148188
if (paramIsNotNullByDefault) {
149189
var operand = node.operand;
150190
if (operand is SimpleIdentifier &&
151-
operand.staticElement == parameter.declaredElement) {
152-
rule.reportLint(node, arguments: [parameter.name!.lexeme]);
191+
operand.staticElement == parameterElement) {
192+
reportLint(node);
153193
}
154194
}
155195

@@ -161,8 +201,8 @@ class _DeclarationVisitor extends RecursiveAstVisitor {
161201
if (paramIsNotNullByDefault) {
162202
var operand = node.operand;
163203
if (operand is SimpleIdentifier &&
164-
operand.staticElement == parameter.declaredElement) {
165-
rule.reportLint(node, arguments: [parameter.name!.lexeme]);
204+
operand.staticElement == parameterElement) {
205+
reportLint(node);
166206
}
167207
}
168208

@@ -206,3 +246,11 @@ class _Visitor extends SimpleAstVisitor<void> {
206246
}
207247
}
208248
}
249+
250+
extension on AstNode {
251+
Element? get element {
252+
var self = this;
253+
if (self is AssignedVariablePattern) return self.element;
254+
return null;
255+
}
256+
}

test/rules/parameter_assignments_test.dart

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import '../rule_test_support.dart';
99
main() {
1010
defineReflectiveSuite(() {
1111
defineReflectiveTests(ParameterAssignmentsTest);
12+
defineReflectiveTests(ParameterAssignmentsTestLanguage300);
1213
});
1314
}
1415

@@ -177,3 +178,63 @@ class A {
177178
]);
178179
}
179180
}
181+
182+
@reflectiveTest
183+
class ParameterAssignmentsTestLanguage300 extends LintRuleTest
184+
with LanguageVersion300Mixin {
185+
@override
186+
String get lintRule => 'parameter_assignments';
187+
188+
// If and switch cases don't need verification since params aren't valid
189+
// constant pattern expressions.
190+
191+
test_listAssignment() async {
192+
await assertDiagnostics(r'''
193+
f(var b) {
194+
[b] = [1];
195+
print('$b');
196+
}
197+
''', [
198+
lint(13, 3),
199+
]);
200+
}
201+
202+
test_mapAssignment() async {
203+
await assertDiagnostics(r'''
204+
f(var a) {
205+
{'a': a} = {'a': 1};
206+
print('$a');
207+
}
208+
''', [
209+
lint(13, 8),
210+
]);
211+
}
212+
213+
test_objectAssignment() async {
214+
await assertDiagnostics(r'''
215+
class A {
216+
int a;
217+
A(this.a);
218+
}
219+
220+
f(var b) {
221+
A(a: b) = A(1);
222+
print('$b');
223+
}
224+
''', [
225+
lint(48, 7),
226+
]);
227+
}
228+
229+
test_recordAssignment() async {
230+
await assertDiagnostics(r'''
231+
void f(var a) {
232+
var b = 0;
233+
(a, b) = (1, 2);
234+
print(b);
235+
}
236+
''', [
237+
lint(31, 6),
238+
]);
239+
}
240+
}

0 commit comments

Comments
 (0)