Skip to content

Commit c148469

Browse files
joke1196sonartech
authored andcommitted
SONARPY-2980: Create QuickFix for Rule S7504 (#317)
GitOrigin-RevId: 6d1bb481a199fde32cfd7c564fa1ca284dce751c
1 parent ab9864d commit c148469

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

python-checks/src/main/java/org/sonar/python/checks/UnnecessaryListCastCheck.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@
2121
import org.sonar.check.Rule;
2222
import org.sonar.plugins.python.api.PythonSubscriptionCheck;
2323
import org.sonar.plugins.python.api.SubscriptionContext;
24+
import org.sonar.plugins.python.api.quickfix.PythonQuickFix;
2425
import org.sonar.plugins.python.api.tree.CallExpression;
2526
import org.sonar.plugins.python.api.tree.ComprehensionFor;
2627
import org.sonar.plugins.python.api.tree.Expression;
2728
import org.sonar.plugins.python.api.tree.ForStatement;
2829
import org.sonar.plugins.python.api.tree.RegularArgument;
2930
import org.sonar.plugins.python.api.tree.Tree;
3031
import org.sonar.plugins.python.api.types.v2.TriBool;
32+
import org.sonar.python.quickfix.TextEditUtils;
33+
import org.sonar.python.tree.TreeUtils;
3134
import org.sonar.python.types.v2.TypeCheckBuilder;
3235

3336
@Rule(key = "S7504")
@@ -57,7 +60,13 @@ private void checkComprehensions(SubscriptionContext ctx) {
5760

5861
private void checkListCastCheck(List<Expression> expressions, SubscriptionContext ctx) {
5962
hasListCallOnIterable(expressions)
60-
.ifPresent(listCall -> ctx.addIssue(listCall.callee(), "Remove this unnecessary `list()` call on an already iterable object."));
63+
.ifPresent(listCall -> {
64+
PreciseIssue issue = ctx.addIssue(listCall.callee(), "Remove this unnecessary `list()` call on an already iterable object.");
65+
Optional.ofNullable(TreeUtils.treeToString(listCall.argumentList(), false))
66+
.map(replacementText -> TextEditUtils.replace(listCall, replacementText))
67+
.map(textEdit -> PythonQuickFix.newQuickFix("Remove the \"list\" call", textEdit))
68+
.ifPresent(issue::addQuickFix);
69+
});
6170
}
6271

6372
private Optional<CallExpression> hasListCallOnIterable(List<Expression> testExpressions) {

python-checks/src/test/java/org/sonar/python/checks/UnnecessaryListCastCheckTest.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,52 @@
1717
package org.sonar.python.checks;
1818

1919
import org.junit.jupiter.api.Test;
20+
import org.sonar.python.checks.quickfix.PythonQuickFixVerifier;
2021
import org.sonar.python.checks.utils.PythonCheckVerifier;
2122

2223
class UnnecessaryListCastCheckTest {
2324

25+
private static final UnnecessaryListCastCheck check = new UnnecessaryListCastCheck();
26+
2427
@Test
2528
void test() {
26-
PythonCheckVerifier.verify("src/test/resources/checks/unnecessaryListCast.py", new UnnecessaryListCastCheck());
29+
PythonCheckVerifier.verify("src/test/resources/checks/unnecessaryListCast.py", check);
30+
}
31+
32+
@Test
33+
void test_quick_fix() {
34+
String codeWithIssue = """
35+
for x in list([1,2,5]):
36+
...
37+
""";
38+
PythonQuickFixVerifier.verifyQuickFixMessages(check, codeWithIssue, "Remove the \"list\" call");
39+
40+
String correctCode = """
41+
for x in [1,2,5]:
42+
...
43+
""";
44+
45+
PythonQuickFixVerifier.verify(check, codeWithIssue, correctCode);
2746
}
2847

48+
@Test
49+
void test_quick_fix_comprehension() {
50+
String codeWithIssue = "{i for i in list([1,2,3])}";
51+
String correctCode = "{i for i in [1,2,3]}";
52+
53+
PythonQuickFixVerifier.verify(check, codeWithIssue, correctCode);
54+
}
55+
56+
@Test
57+
void test_no_quick_fix_on_multiline() {
58+
String codeWithIssue = """
59+
for x in list(
60+
[
61+
1,
62+
2,
63+
5]):
64+
...
65+
""";
66+
PythonQuickFixVerifier.verifyNoQuickFixes(check, codeWithIssue);
67+
}
2968
}

0 commit comments

Comments
 (0)