Skip to content

Commit b285aaf

Browse files
authored
Added support for static enums getting fixed from Sonar (#244)
This was quite fast to add, and it looks like one that might be quite to do without Sonar, but it is help proving the concept regardless.
1 parent bd23faf commit b285aaf

File tree

7 files changed

+177
-0
lines changed

7 files changed

+177
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.codemodder.codemods;
2+
3+
import com.github.javaparser.ast.CompilationUnit;
4+
import com.github.javaparser.ast.body.EnumDeclaration;
5+
import io.codemodder.*;
6+
import io.codemodder.providers.sonar.ProvidedSonarScan;
7+
import io.codemodder.providers.sonar.RuleIssues;
8+
import io.codemodder.providers.sonar.SonarPluginJavaParserChanger;
9+
import io.codemodder.providers.sonar.api.Issue;
10+
import javax.inject.Inject;
11+
12+
/** A codemod for automatically removing redundant static flags on nested enums. */
13+
@Codemod(
14+
id = "sonar:java/remove-redundant-static-s2786",
15+
reviewGuidance = ReviewGuidance.MERGE_WITHOUT_REVIEW,
16+
executionPriority = CodemodExecutionPriority.HIGH)
17+
public final class FixRedundantStaticOnEnumCodemod
18+
extends SonarPluginJavaParserChanger<EnumDeclaration> {
19+
20+
@Inject
21+
public FixRedundantStaticOnEnumCodemod(
22+
@ProvidedSonarScan(ruleId = "java:S2786") final RuleIssues issues) {
23+
super(issues, EnumDeclaration.class, RegionNodeMatcher.MATCHES_START);
24+
}
25+
26+
@Override
27+
public boolean onIssueFound(
28+
final CodemodInvocationContext context,
29+
final CompilationUnit cu,
30+
final EnumDeclaration enumDecl,
31+
final Issue issue) {
32+
if (enumDecl.isStatic()) {
33+
enumDecl.setStatic(false);
34+
return true;
35+
}
36+
return false;
37+
}
38+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
This change removes redundant (and possibly misleading) `static` keywords on `enum` types defined within classes. All `enum` types that are nested within another type are automatically `static`, and so listing the flag this clutters the code, and may cause confusion when reasoning about it.
2+
3+
Our changes look something like this:
4+
5+
```diff
6+
@RestController
7+
final class CheckStatusController {
8+
9+
- static enum ResponseType {
10+
+ enum ResponseType {
11+
SUCCESS,
12+
FAILURE,
13+
ERROR
14+
}
15+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"summary" : "Removed redundant static flag on enum (Sonar)",
3+
"change" : "Removed redundant static flag on enum",
4+
"references" : [
5+
"https://sonarsource.github.io/rspec/#/rspec/S2786/java"
6+
]
7+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.codemodder.codemods;
2+
3+
import io.codemodder.testutils.CodemodTestMixin;
4+
import io.codemodder.testutils.Metadata;
5+
6+
@Metadata(
7+
codemodType = FixRedundantStaticOnEnumCodemod.class,
8+
testResourceDir = "remove-redundant-static-s2786",
9+
dependencies = {})
10+
final class FixRedundantStaticOnEnumCodemodTest implements CodemodTestMixin {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package acme.test;
2+
3+
public class Response {
4+
enum Status {
5+
SUCCESS, FAILURE, ERROR
6+
}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package acme.test;
2+
3+
public class Response {
4+
static enum Status {
5+
SUCCESS, FAILURE, ERROR
6+
}
7+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"total": 1,
3+
"p": 1,
4+
"ps": 500,
5+
"paging": {
6+
"pageIndex": 1,
7+
"pageSize": 500,
8+
"total": 1
9+
},
10+
"effortTotal": 2,
11+
"debtTotal": 2,
12+
"issues": [
13+
{
14+
"key": "AYv0acY3pMuQdcUNcsKX",
15+
"rule": "java:S2786",
16+
"severity": "MINOR",
17+
"component": "nahsra_WebGoat_10_23:Test.java",
18+
"project": "nahsra_WebGoat_10_23",
19+
"line": 4,
20+
"hash": "f7cdce57b37926f1061e0ab664b60dbd",
21+
"textRange": {
22+
"startLine": 4,
23+
"endLine": 4,
24+
"startOffset": 2,
25+
"endOffset": 8
26+
},
27+
"flows": [
28+
{
29+
"locations": [
30+
{
31+
"component": "nahsra_WebGoat_10_23:Test.java",
32+
"textRange": {
33+
"startLine": 4,
34+
"endLine": 4,
35+
"startOffset": 9,
36+
"endOffset": 13
37+
}
38+
}
39+
]
40+
}
41+
],
42+
"status": "OPEN",
43+
"message": "Remove this redundant \"static\" qualifier; nested enum types are implicitly static.",
44+
"effort": "2min",
45+
"debt": "2min",
46+
"assignee": "nahsra@github",
47+
"author": "[email protected]",
48+
"tags": [
49+
"redundant"
50+
],
51+
"creationDate": "2023-11-22T01:21:06+0100",
52+
"updateDate": "2023-11-22T01:21:29+0100",
53+
"type": "CODE_SMELL",
54+
"organization": "nahsra",
55+
"cleanCodeAttribute": "CLEAR",
56+
"cleanCodeAttributeCategory": "INTENTIONAL",
57+
"impacts": [
58+
{
59+
"softwareQuality": "MAINTAINABILITY",
60+
"severity": "LOW"
61+
}
62+
]
63+
}
64+
],
65+
"components": [
66+
{
67+
"organization": "nahsra",
68+
"key": "nahsra_WebGoat_10_23",
69+
"uuid": "AYvtqxxxzY4Rr5NHn4Om",
70+
"enabled": true,
71+
"qualifier": "TRK",
72+
"name": "WebGoat_10_23",
73+
"longName": "WebGoat_10_23"
74+
},
75+
{
76+
"organization": "nahsra",
77+
"key": "nahsra_WebGoat_10_23:webgoat-lessons/vulnerable-components/src/main/java/org/owasp/webgoat/vulnerable_components/EnumThing.java",
78+
"uuid": "AYv0abClpMuQdcUNcsKV",
79+
"enabled": true,
80+
"qualifier": "FIL",
81+
"name": "EnumThing.java",
82+
"longName": "webgoat-lessons/vulnerable-components/src/main/java/org/owasp/webgoat/vulnerable_components/EnumThing.java",
83+
"path": "webgoat-lessons/vulnerable-components/src/main/java/org/owasp/webgoat/vulnerable_components/EnumThing.java"
84+
}
85+
],
86+
"organizations": [
87+
{
88+
"key": "nahsra",
89+
"name": "Arshan Dabirsiaghi"
90+
}
91+
],
92+
"facets": []
93+
}

0 commit comments

Comments
 (0)