Skip to content

Commit ad3a82a

Browse files
committed
Implemented Violations to upperEll recipe
1 parent 76f932b commit ad3a82a

File tree

9 files changed

+267
-32
lines changed

9 files changed

+267
-32
lines changed

config/import-control-test.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
<allow pkg="java.util"/>
1212
<allow pkg="java.nio"/>
1313
<allow pkg="java.lang"/>
14+
<allow pkg="javax.xml.stream"/>
1415
</import-control>

src/main/java/org/checkstyle/autofix/recipe/UpperEllRecipe.java

Lines changed: 117 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,20 @@
1717

1818
package org.checkstyle.autofix.recipe;
1919

20+
import java.nio.file.Path;
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
import java.util.Objects;
24+
import java.util.concurrent.CancellationException;
25+
import java.util.function.Function;
26+
27+
import org.checkstyle.autofix.parser.CheckstyleViolation;
28+
import org.openrewrite.Cursor;
2029
import org.openrewrite.ExecutionContext;
30+
import org.openrewrite.PrintOutputCapture;
2131
import org.openrewrite.Recipe;
2232
import org.openrewrite.TreeVisitor;
33+
import org.openrewrite.internal.RecipeRunException;
2334
import org.openrewrite.java.JavaIsoVisitor;
2435
import org.openrewrite.java.tree.J;
2536
import org.openrewrite.java.tree.JavaType;
@@ -30,6 +41,16 @@
3041
*/
3142
public class UpperEllRecipe extends Recipe {
3243

44+
private List<CheckstyleViolation> violations;
45+
46+
public UpperEllRecipe() {
47+
this.violations = new ArrayList<>();
48+
}
49+
50+
public UpperEllRecipe(List<CheckstyleViolation> violations) {
51+
this.violations = violations;
52+
}
53+
3354
@Override
3455
public String getDisplayName() {
3556
return "UpperEll recipe";
@@ -43,23 +64,112 @@ public String getDescription() {
4364

4465
@Override
4566
public TreeVisitor<?, ExecutionContext> getVisitor() {
46-
return new UpperEllVisitor();
67+
return new UpperEllVisitor(violations);
4768
}
4869

49-
/**
50-
* Visitor that replaces lowercase 'l' suffixes in long literals with uppercase 'L'.
51-
*/
5270
private static final class UpperEllVisitor extends JavaIsoVisitor<ExecutionContext> {
71+
72+
private final List<CheckstyleViolation> violations;
73+
private String currentFileName;
74+
75+
UpperEllVisitor(List<CheckstyleViolation> violations) {
76+
this.violations = violations;
77+
}
78+
79+
@Override
80+
public J.CompilationUnit visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) {
81+
this.currentFileName = cu.getSourcePath().toString();
82+
return super.visitCompilationUnit(cu, ctx);
83+
}
84+
5385
@Override
5486
public J.Literal visitLiteral(J.Literal literal, ExecutionContext ctx) {
5587
J.Literal result = super.visitLiteral(literal, ctx);
5688
final String valueSource = result.getValueSource();
5789

5890
if (valueSource != null && valueSource.endsWith("l")
59-
&& result.getType() == JavaType.Primitive.Long) {
91+
&& result.getType() == JavaType.Primitive.Long
92+
&& isAtViolationLocation(result)) {
93+
6094
final String numericPart = valueSource.substring(0, valueSource.length() - 1);
61-
final String newValueSource = numericPart + "L";
62-
result = result.withValueSource(newValueSource);
95+
result = result.withValueSource(numericPart + "L");
96+
}
97+
98+
return result;
99+
}
100+
101+
private boolean isAtViolationLocation(J.Literal literal) {
102+
final J.CompilationUnit cursor = Objects.requireNonNull(getCursor()
103+
.firstEnclosing(J.CompilationUnit.class));
104+
105+
final int line = computeLinePosition(cursor, literal, getCursor());
106+
final int column = computeColumnPosition(cursor, literal, getCursor());
107+
108+
return violations.stream().anyMatch(violation -> {
109+
return violation.getLine() == line
110+
&& violation.getColumn() == column
111+
&& Path.of(violation.getFileName()).equals(Path.of(currentFileName));
112+
});
113+
}
114+
115+
private int computePosition(
116+
J tree,
117+
J targetElement,
118+
Cursor cursor,
119+
Function<String, Integer> positionCalculator
120+
) {
121+
final TreeVisitor<?, PrintOutputCapture<TreeVisitor<?, ?>>> printer =
122+
tree.printer(cursor);
123+
124+
final PrintOutputCapture<TreeVisitor<?, ?>> capture =
125+
new PrintOutputCapture<>(printer) {
126+
@Override
127+
public PrintOutputCapture<TreeVisitor<?, ?>> append(String text) {
128+
if (targetElement.isScope(getContext().getCursor().getValue())) {
129+
targetElement.getPrefix();
130+
super.append(targetElement.getPrefix().getWhitespace());
131+
throw new CancellationException();
132+
}
133+
return super.append(text);
134+
}
135+
};
136+
137+
final int result;
138+
try {
139+
printer.visit(tree, capture, cursor.getParentOrThrow());
140+
throw new IllegalStateException("Target element not found in tree");
141+
}
142+
catch (CancellationException ignored) {
143+
result = positionCalculator.apply(capture.getOut());
144+
}
145+
catch (RecipeRunException exception) {
146+
if (exception.getCause() instanceof CancellationException) {
147+
result = positionCalculator.apply(capture.getOut());
148+
}
149+
else {
150+
throw exception;
151+
}
152+
}
153+
return result;
154+
}
155+
156+
private int computeLinePosition(J tree, J targetElement, Cursor cursor) {
157+
return computePosition(tree, targetElement, cursor,
158+
out -> 1 + (int) out.chars().filter(chr -> chr == '\n').count());
159+
}
160+
161+
private int computeColumnPosition(J tree, J targetElement, Cursor cursor) {
162+
return computePosition(tree, targetElement, cursor, this::calculateColumnOffset);
163+
}
164+
165+
private int calculateColumnOffset(String out) {
166+
final int lineBreakIndex = out.lastIndexOf('\n');
167+
final int result;
168+
if (lineBreakIndex == -1) {
169+
result = out.length();
170+
}
171+
else {
172+
result = out.length() - lineBreakIndex - 1;
63173
}
64174
return result;
65175
}

src/test/java/org/checkstyle/autofix/recipe/AbstractRecipeTest.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import java.nio.file.Files;
2525
import java.nio.file.Paths;
2626

27+
import javax.xml.stream.XMLStreamException;
28+
2729
import org.checkstyle.autofix.ClassRenameRecipe;
2830
import org.openrewrite.Recipe;
2931
import org.openrewrite.test.RewriteTest;
@@ -53,7 +55,7 @@ private Recipe createPreprocessingRecipe() {
5355
*
5456
* @return the main recipe to test
5557
*/
56-
protected abstract Recipe getRecipe();
58+
protected abstract Recipe getRecipe() throws XMLStreamException, IOException;
5759

5860
/**
5961
* Tests a recipe with the given recipe path and test case name.
@@ -67,7 +69,8 @@ private Recipe createPreprocessingRecipe() {
6769
* @param testCaseName the name of the test case (should match directory and file names)
6870
* @throws IOException if files cannot be read
6971
*/
70-
protected void testRecipe(String recipePath, String testCaseName) throws IOException {
72+
protected void testRecipe(String recipePath, String testCaseName)
73+
throws IOException, XMLStreamException {
7174
final String testCaseDir = testCaseName.toLowerCase();
7275
final String inputFileName = "Input" + testCaseName + ".java";
7376
final String outputFileName = "Output" + testCaseName + ".java";

src/test/java/org/checkstyle/autofix/recipe/UpperEllRecipeTest.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,40 @@
1818
package org.checkstyle.autofix.recipe;
1919

2020
import java.io.IOException;
21+
import java.nio.file.Path;
22+
import java.util.List;
2123

24+
import javax.xml.stream.XMLStreamException;
25+
26+
import org.checkstyle.autofix.parser.CheckstyleReportsParser;
27+
import org.checkstyle.autofix.parser.CheckstyleViolation;
2228
import org.junit.jupiter.api.Test;
2329
import org.openrewrite.Recipe;
2430

2531
public class UpperEllRecipeTest extends AbstractRecipeTest {
2632

2733
@Override
28-
protected Recipe getRecipe() {
29-
return new UpperEllRecipe();
34+
protected Recipe getRecipe() throws XMLStreamException, IOException {
35+
final String reportPath = "src/test/resources/org/checkstyle/autofix/recipe/upperell"
36+
+ "/report.xml";
37+
38+
final List<CheckstyleViolation> violations =
39+
CheckstyleReportsParser.parse(Path.of(reportPath));
40+
return new UpperEllRecipe(violations);
3041
}
3142

3243
@Test
33-
void hexOctalLiteralTest() throws IOException {
44+
void hexOctalLiteralTest() throws IOException, XMLStreamException {
3445
testRecipe("upperell", "HexOctalLiteral");
3546
}
3647

3748
@Test
38-
void complexLongLiterals() throws IOException {
49+
void complexLongLiterals() throws IOException, XMLStreamException {
3950
testRecipe("upperell", "ComplexLongLiterals");
4051
}
4152

4253
@Test
43-
void stringAndCommentTest() throws IOException {
54+
void stringAndCommentTest() throws IOException, XMLStreamException {
4455
testRecipe("upperell", "StringAndComments");
4556
}
4657
}

src/test/resources/org/checkstyle/autofix/recipe/upperell/complexlongliterals/InputComplexLongLiterals.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ public class InputComplexLongLiterals {
1111
private Long simpleLong = 1234l;
1212
private Long negativeLong = -5678l;
1313
private Long underscoreLong = 1_000_000l;
14-
Long maxLongObject = 9223372036854775807l;
15-
Long minLongObject = -9223372036854775808l;
14+
Long maxLongObject = 9223372036854775807l; //suppressed violation
15+
Long minLongObject = -9223372036854775808l; //suppressed violation
1616

1717
public long calculate(long input1, long input2) {
1818
return input1 + input2 + 1000l;

src/test/resources/org/checkstyle/autofix/recipe/upperell/complexlongliterals/OutputComplexLongLiterals.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ public class OutputComplexLongLiterals {
1111
private Long simpleLong = 1234L;
1212
private Long negativeLong = -5678L;
1313
private Long underscoreLong = 1_000_000L;
14-
Long maxLongObject = 9223372036854775807L;
15-
Long minLongObject = -9223372036854775808L;
14+
Long maxLongObject = 9223372036854775807l; //suppressed violation
15+
Long minLongObject = -9223372036854775808l; //suppressed violation
1616

1717
public long calculate(long input1, long input2) {
1818
return input1 + input2 + 1000L;
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package org.checkstyle.autofix.recipe.upperell.hexoctalliteral;
22

33
public class InputHexOctalLiteral {
4-
private long hexLower = 0x1ABCl;
5-
private long hexUpper = 0X2DEFl;
6-
private long octal = 0777l;
7-
private long binary = 0b1010l;
8-
private long decimal = 12345l;
4+
private long hexLower = 0x1ABCL;
5+
private long hexUpper = 0X2DEFL;
6+
private long octal = 0777L;
7+
private long binary = 0b1010L;
8+
private long decimal = 12345L;
99

1010
public void calculateValues() {
11-
long hexResult = 0xDEADBEEFl;
12-
long octalResult = 01234l;
13-
long binaryResult = 0b11110000l;
11+
long hexResult = 0xDEADBEEFl + 0xDEADBEFl; //suppressed violation for 0xDEADBEFl
12+
long octalResult = 01234l + 0xDEADBEEFl; //suppressed violation for 0xDEADBEFl
13+
long binaryResult = 0b11110000L;
1414
}
1515
}

src/test/resources/org/checkstyle/autofix/recipe/upperell/hexoctalliteral/OutputHexOctalLiteral.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
public class OutputHexOctalLiteral {
44
private long hexLower = 0x1ABCL;
5-
private long hexUpper = 0X2DEFL;
6-
private long octal = 0777L;
7-
private long binary = 0b1010L;
8-
private long decimal = 12345L;
5+
private long hexUpper = 0X2DEFL;
6+
private long octal = 0777L;
7+
private long binary = 0b1010L;
8+
private long decimal = 12345L;
99

1010
public void calculateValues() {
11-
long hexResult = 0xDEADBEEFL;
12-
long octalResult = 01234L;
11+
long hexResult = 0xDEADBEEFL + 0xDEADBEFl; //suppressed violation for 0xDEADBEFl
12+
long octalResult = 01234L + 0xDEADBEEFl; //suppressed violation for 0xDEADBEFl
1313
long binaryResult = 0b11110000L;
1414
}
1515
}

0 commit comments

Comments
 (0)