Skip to content
This repository was archived by the owner on Jul 16, 2023. It is now read-only.

Commit 7b09a55

Browse files
fix: remove duplicated highlights and ignore void function calls (#829)
* fix: remove duplicated and ignore void function calls * chore: remove unused import * chore: remove unused ignore Co-authored-by: Dmitry Krutskikh <dmitry.krutskikh@gmail.com>
1 parent 20422aa commit 7b09a55

File tree

7 files changed

+270
-13
lines changed

7 files changed

+270
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
* fix: [`avoid-border-all`](https://dartcodemetrics.dev/docs/rules/flutter/avoid-border-all) is triggered even when it is not a const.
6+
* fix: remove duplicated and ignore void function calls for [`prefer-moving-to-variable`](https://dartcodemetrics.dev/docs/rules/common/prefer-moving-to-variable).
67

78
## 4.15.1
89

lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/visitor.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ class _Visitor extends RecursiveAstVisitor<void> {
77

88
@override
99
void visitBlockFunctionBody(BlockFunctionBody node) {
10-
super.visitBlockFunctionBody(node);
11-
1210
final visitor = _BlockVisitor();
1311
node.visitChildren(visitor);
1412

@@ -39,7 +37,8 @@ class _BlockVisitor extends RecursiveAstVisitor<void> {
3937

4038
@override
4139
void visitMethodInvocation(MethodInvocation node) {
42-
if (node.parent is CascadeExpression) {
40+
if (node.parent is CascadeExpression ||
41+
(node.staticType?.isVoid ?? false)) {
4342
return;
4443
}
4544

@@ -75,8 +74,7 @@ class _BlockVisitor extends RecursiveAstVisitor<void> {
7574
final visitedBlock = visitedInvocation.thisOrAncestorOfType<Block>();
7675
final parentBlock = node.thisOrAncestorOfType<Block>();
7776

78-
// ignore: avoid-late-keyword
79-
late final grandParentBlock = parentBlock?.thisOrAncestorMatching(
77+
final grandParentBlock = parentBlock?.thisOrAncestorMatching(
8078
(block) => block is Block && block != parentBlock,
8179
);
8280

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
void main() {
2+
final someValue = 'value';
3+
4+
methodWithArguments('hello');
5+
methodWithArguments('hello', 'world');
6+
7+
methodWithArguments('world'); // LINT
8+
methodWithArguments('world'); // LINT
9+
10+
methodWithArguments(someValue); // LINT
11+
methodWithArguments(someValue); // LINT
12+
13+
final someOtherValue = 'otherValue';
14+
methodWithArguments(someOtherValue);
15+
methodWithArguments(someValue); // LINT
16+
17+
methodWithNamedArguments(age: 1);
18+
methodWithNamedArguments(age: 1, firstName: '');
19+
20+
methodWithNamedArguments(firstName: 'hello'); // LINT
21+
methodWithNamedArguments(firstName: 'hello'); // LINT
22+
23+
methodWithNamedArguments(lastName: 'last'); // LINT
24+
25+
if (true) {
26+
methodWithNamedArguments(lastName: 'last'); // LINT
27+
}
28+
29+
methodWithMixedArguments(someValue);
30+
methodWithMixedArguments(someOtherValue);
31+
32+
methodWithMixedArguments(someValue, named: 'name'); // LINT
33+
methodWithMixedArguments(someValue, named: 'name'); // LINT
34+
}
35+
36+
String methodWithArguments(String firstRegular, String secondRegular) {
37+
return '';
38+
}
39+
40+
String methodWithNamedArguments({
41+
String firstName,
42+
String lastName,
43+
int age,
44+
}) {
45+
return '';
46+
}
47+
48+
String methodWithMixedArguments(String regular, {int? named}) {
49+
return '';
50+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
void main() {
2+
final state = State();
3+
4+
final someValue = 'value';
5+
6+
state.methodWithArguments('hello');
7+
state.methodWithArguments('hello', 'world');
8+
9+
state.methodWithArguments('world'); // LINT
10+
state.methodWithArguments('world'); // LINT
11+
12+
state.methodWithArguments(someValue); // LINT
13+
state.methodWithArguments(someValue); // LINT
14+
15+
final someOtherValue = 'otherValue';
16+
state.methodWithArguments(someOtherValue);
17+
state.methodWithArguments(someValue); // LINT
18+
19+
state.methodWithNamedArguments(age: 1);
20+
state.methodWithNamedArguments(age: 1, firstName: '');
21+
22+
state.methodWithNamedArguments(firstName: 'hello'); // LINT
23+
state.methodWithNamedArguments(firstName: 'hello'); // LINT
24+
25+
state.methodWithNamedArguments(lastName: 'last'); // LINT
26+
27+
if (true) {
28+
state.methodWithNamedArguments(lastName: 'last'); // LINT
29+
}
30+
31+
state.methodWithMixedArguments(someValue);
32+
state.methodWithMixedArguments(someOtherValue);
33+
34+
state.methodWithMixedArguments(someValue, named: 'name'); // LINT
35+
state.methodWithMixedArguments(someValue, named: 'name'); // LINT
36+
}
37+
38+
class State {
39+
String methodWithArguments(String firstRegular, String secondRegular) {
40+
return '';
41+
}
42+
43+
String methodWithNamedArguments({
44+
String firstName,
45+
String lastName,
46+
int age,
47+
}) {
48+
return '';
49+
}
50+
51+
String methodWithMixedArguments(String regular, {int? named}) {
52+
return '';
53+
}
54+
}

test/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/examples/example.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ void main() {
2222
Theme.from().value.runtimeType; // LINT
2323
Theme.from().value.length; // LINT
2424

25-
Theme.from().someMethod(); // LINT
26-
Theme.from().someMethod(); // LINT
25+
Theme.from().someMethod();
26+
Theme.from().someMethod();
27+
28+
Theme.from().notVoidMethod(); // LINT
29+
Theme.from().notVoidMethod(); // LINT
2730

2831
getValue(); // LINT
2932
getValue(); // LINT
@@ -44,6 +47,12 @@ class Theme {
4447
string.indexOf('').sign.bitLength.isEven; // LINT
4548
string.indexOf('').sign.isOdd; // LINT
4649
}
50+
51+
String notVoidMethod() {
52+
final string = 'str';
53+
54+
return string;
55+
}
4756
}
4857

4958
String getValue() => 'hello';
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
class BlocTest {
2+
final state = State();
3+
4+
FutureOr<void> mapEvent(
5+
TestEvent event,
6+
Emitter<TestState> emit,
7+
) {
8+
return event.map<FutureOr<void>>(
9+
init: (_) async {
10+
emit(state.copyWith(isLoading: true)); // LINT
11+
12+
const result = [];
13+
14+
var newState = state.copyWith(dataList: result); // LINT
15+
16+
if (result.isEmpty) {
17+
newState = newState.copyWith(dataList: [], isLoading: false);
18+
} else {
19+
newState = newState.copyWith(dataList: result, isLoading: false);
20+
}
21+
22+
emit(state);
23+
},
24+
checkProviders: (_) async {
25+
emit(state.copyWith(isLoading: true)); // LINT
26+
27+
const result = [];
28+
29+
if (result.isEmpty) {
30+
emit(state.copyWith(dataList: [])); // LINT
31+
} else {
32+
emit(state.copyWith(dataList: result));
33+
}
34+
},
35+
);
36+
}
37+
38+
void emit(Object value) {}
39+
}
40+
41+
class TestEvent {
42+
FutureOr<void> map<T>({Function init, Function checkProviders}) {}
43+
}
44+
45+
class State {
46+
State copyWith({List<Object> dataList, bool isLoading}) {
47+
return State();
48+
}
49+
}

test/src/analyzers/lint_analyzer/rules/rules_list/prefer_moving_to_variable/prefer_moving_to_variable_rule_test.dart

Lines changed: 102 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ import 'package:test/test.dart';
55
import '../../../../../helpers/rule_test_helper.dart';
66

77
const _examplePath = 'prefer_moving_to_variable/examples/example.dart';
8+
const _argumentsExamplePath =
9+
'prefer_moving_to_variable/examples/arguments_example.dart';
10+
const _argumentsWithObjectExamplePath =
11+
'prefer_moving_to_variable/examples/arguments_with_object_example.dart';
12+
const _scopeExamplePath =
13+
'prefer_moving_to_variable/examples/scope_example.dart';
814
const _cascadeExamplePath =
915
'prefer_moving_to_variable/examples/cascade_example.dart';
1016

@@ -40,12 +46,12 @@ void main() {
4046
20,
4147
22,
4248
23,
43-
25,
44-
26,
4549
28,
4650
29,
47-
44,
48-
45,
51+
31,
52+
32,
53+
47,
54+
48,
4955
],
5056
startColumns: [
5157
19,
@@ -80,8 +86,8 @@ void main() {
8086
'Theme.after().value',
8187
'Theme.from().value',
8288
'Theme.from().value',
83-
'Theme.from().someMethod()',
84-
'Theme.from().someMethod()',
89+
'Theme.from().notVoidMethod()',
90+
'Theme.from().notVoidMethod()',
8591
'getValue()',
8692
'getValue()',
8793
"string.indexOf('').sign",
@@ -110,6 +116,96 @@ void main() {
110116
);
111117
});
112118

119+
test(
120+
'reports about found issues for invocations with arguments example',
121+
() async {
122+
final unit =
123+
await RuleTestHelper.resolveFromFile(_argumentsExamplePath);
124+
final issues = PreferMovingToVariableRule().check(unit);
125+
126+
RuleTestHelper.verifyIssues(
127+
issues: issues,
128+
startLines: [7, 8, 10, 11, 15, 20, 21, 23, 26, 32, 33],
129+
startColumns: [3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3],
130+
locationTexts: [
131+
"methodWithArguments('world')",
132+
"methodWithArguments('world')",
133+
'methodWithArguments(someValue)',
134+
'methodWithArguments(someValue)',
135+
'methodWithArguments(someValue)',
136+
"methodWithNamedArguments(firstName: 'hello')",
137+
"methodWithNamedArguments(firstName: 'hello')",
138+
"methodWithNamedArguments(lastName: 'last')",
139+
"methodWithNamedArguments(lastName: 'last')",
140+
"methodWithMixedArguments(someValue, named: 'name')",
141+
"methodWithMixedArguments(someValue, named: 'name')",
142+
],
143+
messages: [
144+
'Prefer moving repeated invocations to variable and use it instead.',
145+
'Prefer moving repeated invocations to variable and use it instead.',
146+
'Prefer moving repeated invocations to variable and use it instead.',
147+
'Prefer moving repeated invocations to variable and use it instead.',
148+
'Prefer moving repeated invocations to variable and use it instead.',
149+
'Prefer moving repeated invocations to variable and use it instead.',
150+
'Prefer moving repeated invocations to variable and use it instead.',
151+
'Prefer moving repeated invocations to variable and use it instead.',
152+
'Prefer moving repeated invocations to variable and use it instead.',
153+
'Prefer moving repeated invocations to variable and use it instead.',
154+
'Prefer moving repeated invocations to variable and use it instead.',
155+
],
156+
);
157+
},
158+
);
159+
160+
test(
161+
'reports about found issues for invocations on object with arguments example',
162+
() async {
163+
final unit = await RuleTestHelper.resolveFromFile(
164+
_argumentsWithObjectExamplePath,
165+
);
166+
final issues = PreferMovingToVariableRule().check(unit);
167+
168+
RuleTestHelper.verifyIssues(
169+
issues: issues,
170+
startLines: [9, 10, 12, 13, 17, 22, 23, 25, 28, 34, 35],
171+
startColumns: [3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3],
172+
locationTexts: [
173+
"state.methodWithArguments('world')",
174+
"state.methodWithArguments('world')",
175+
'state.methodWithArguments(someValue)',
176+
'state.methodWithArguments(someValue)',
177+
'state.methodWithArguments(someValue)',
178+
"state.methodWithNamedArguments(firstName: 'hello')",
179+
"state.methodWithNamedArguments(firstName: 'hello')",
180+
"state.methodWithNamedArguments(lastName: 'last')",
181+
"state.methodWithNamedArguments(lastName: 'last')",
182+
"state.methodWithMixedArguments(someValue, named: 'name')",
183+
"state.methodWithMixedArguments(someValue, named: 'name')",
184+
],
185+
messages: [
186+
'Prefer moving repeated invocations to variable and use it instead.',
187+
'Prefer moving repeated invocations to variable and use it instead.',
188+
'Prefer moving repeated invocations to variable and use it instead.',
189+
'Prefer moving repeated invocations to variable and use it instead.',
190+
'Prefer moving repeated invocations to variable and use it instead.',
191+
'Prefer moving repeated invocations to variable and use it instead.',
192+
'Prefer moving repeated invocations to variable and use it instead.',
193+
'Prefer moving repeated invocations to variable and use it instead.',
194+
'Prefer moving repeated invocations to variable and use it instead.',
195+
'Prefer moving repeated invocations to variable and use it instead.',
196+
'Prefer moving repeated invocations to variable and use it instead.',
197+
],
198+
);
199+
},
200+
);
201+
202+
test('reports no issues for scope', () async {
203+
final unit = await RuleTestHelper.resolveFromFile(_scopeExamplePath);
204+
final issues = PreferMovingToVariableRule().check(unit);
205+
206+
RuleTestHelper.verifyNoIssues(issues);
207+
});
208+
113209
test('reports no issues for cascade', () async {
114210
final unit = await RuleTestHelper.resolveFromFile(_cascadeExamplePath);
115211
final issues = PreferMovingToVariableRule().check(unit);

0 commit comments

Comments
 (0)