Skip to content

Commit b6c3d38

Browse files
committed
Issue #46: Extract the position calculation methods into a utility class
1 parent 4bf149c commit b6c3d38

File tree

2 files changed

+99
-85
lines changed

2 files changed

+99
-85
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
///////////////////////////////////////////////////////////////////////////////////////////////
2+
// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite.
3+
// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes Authors
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
///////////////////////////////////////////////////////////////////////////////////////////////
17+
18+
package org.checkstyle.autofix;
19+
20+
import java.util.concurrent.CancellationException;
21+
import java.util.function.Function;
22+
23+
import org.openrewrite.Cursor;
24+
import org.openrewrite.PrintOutputCapture;
25+
import org.openrewrite.TreeVisitor;
26+
import org.openrewrite.internal.RecipeRunException;
27+
import org.openrewrite.java.tree.J;
28+
29+
public final class PositionHelper {
30+
31+
private PositionHelper() {
32+
// Utility class
33+
}
34+
35+
public static int computeLinePosition(J tree, J targetElement, Cursor cursor) {
36+
return computePosition(tree, targetElement, cursor,
37+
out -> 1 + Math.toIntExact(out.chars().filter(chr -> chr == '\n').count()));
38+
}
39+
40+
public static int computeColumnPosition(J tree, J targetElement, Cursor cursor) {
41+
return computePosition(tree, targetElement, cursor, PositionHelper::calculateColumnOffset);
42+
}
43+
44+
private static int computePosition(
45+
J tree,
46+
J targetElement,
47+
Cursor cursor,
48+
Function<String, Integer> positionCalculator
49+
) {
50+
final TreeVisitor<?, PrintOutputCapture<TreeVisitor<?, ?>>> printer =
51+
tree.printer(cursor);
52+
53+
final PrintOutputCapture<TreeVisitor<?, ?>> capture =
54+
new PrintOutputCapture<>(printer) {
55+
@Override
56+
public PrintOutputCapture<TreeVisitor<?, ?>> append(String text) {
57+
if (targetElement.isScope(getContext().getCursor().getValue())) {
58+
super.append(targetElement.getPrefix().getWhitespace());
59+
throw new CancellationException();
60+
}
61+
return super.append(text);
62+
}
63+
};
64+
65+
final int result;
66+
try {
67+
printer.visit(tree, capture, cursor.getParentOrThrow());
68+
throw new IllegalStateException("Target element: " + targetElement
69+
+ ", not found in the syntax tree.");
70+
}
71+
catch (CancellationException exception) {
72+
result = positionCalculator.apply(capture.getOut());
73+
}
74+
catch (RecipeRunException exception) {
75+
if (exception.getCause() instanceof CancellationException) {
76+
result = positionCalculator.apply(capture.getOut());
77+
}
78+
else {
79+
throw exception;
80+
}
81+
}
82+
return result;
83+
}
84+
85+
private static int calculateColumnOffset(String out) {
86+
final int lineBreakIndex = out.lastIndexOf('\n');
87+
final int result;
88+
if (lineBreakIndex == -1) {
89+
result = out.length();
90+
}
91+
else {
92+
result = out.length() - lineBreakIndex - 1;
93+
}
94+
return result;
95+
}
96+
}

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

Lines changed: 3 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,12 @@
1919

2020
import java.nio.file.Path;
2121
import java.util.List;
22-
import java.util.concurrent.CancellationException;
23-
import java.util.function.Function;
2422

23+
import org.checkstyle.autofix.PositionHelper;
2524
import org.checkstyle.autofix.parser.CheckstyleViolation;
26-
import org.openrewrite.Cursor;
2725
import org.openrewrite.ExecutionContext;
28-
import org.openrewrite.PrintOutputCapture;
2926
import org.openrewrite.Recipe;
3027
import org.openrewrite.TreeVisitor;
31-
import org.openrewrite.internal.RecipeRunException;
3228
import org.openrewrite.java.JavaIsoVisitor;
3329
import org.openrewrite.java.tree.J;
3430
import org.openrewrite.java.tree.JavaType;
@@ -93,92 +89,14 @@ && isAtViolationLocation(result)) {
9389
private boolean isAtViolationLocation(J.Literal literal) {
9490
final J.CompilationUnit cursor = getCursor().firstEnclosing(J.CompilationUnit.class);
9591

96-
final int line = computeLinePosition(cursor, literal, getCursor());
97-
final int column = computeColumnPosition(cursor, literal, getCursor());
92+
final int line = PositionHelper.computeLinePosition(cursor, literal, getCursor());
93+
final int column = PositionHelper.computeColumnPosition(cursor, literal, getCursor());
9894

9995
return violations.stream().anyMatch(violation -> {
10096
return violation.getLine() == line
10197
&& violation.getColumn() == column
10298
&& Path.of(violation.getFileName()).equals(sourcePath);
10399
});
104100
}
105-
106-
/**
107-
* Computes the position of a target element within a syntax tree using position calculator.
108-
* This method traverses the given syntax tree and captures the printed output until the
109-
* target element is encountered. When the target is found, a CancellationException
110-
* is thrown to interrupt traversal, and the captured output is passed to the provided
111-
* positionCalculator to compute the position.
112-
*
113-
* @param tree the root of the syntax tree to traverse
114-
* @param targetElement the element whose position is to be computed
115-
* @param cursor the current cursor in the tree traversal
116-
* @param positionCalculator a function to compute the position from the printed output
117-
* @return the computed position of the target element
118-
* @throws IllegalStateException if the target element is not found in the tree
119-
* @throws RecipeRunException if an error occurs during traversal
120-
*/
121-
private int computePosition(
122-
J tree,
123-
J targetElement,
124-
Cursor cursor,
125-
Function<String, Integer> positionCalculator
126-
) {
127-
final TreeVisitor<?, PrintOutputCapture<TreeVisitor<?, ?>>> printer =
128-
tree.printer(cursor);
129-
130-
final PrintOutputCapture<TreeVisitor<?, ?>> capture =
131-
new PrintOutputCapture<>(printer) {
132-
@Override
133-
public PrintOutputCapture<TreeVisitor<?, ?>> append(String text) {
134-
if (targetElement.isScope(getContext().getCursor().getValue())) {
135-
super.append(targetElement.getPrefix().getWhitespace());
136-
throw new CancellationException();
137-
}
138-
return super.append(text);
139-
}
140-
};
141-
142-
final int result;
143-
try {
144-
printer.visit(tree, capture, cursor.getParentOrThrow());
145-
throw new IllegalStateException("Target element: " + targetElement
146-
+ ", not found in the syntax tree.");
147-
}
148-
catch (CancellationException exception) {
149-
result = positionCalculator.apply(capture.getOut());
150-
}
151-
catch (RecipeRunException exception) {
152-
if (exception.getCause() instanceof CancellationException) {
153-
result = positionCalculator.apply(capture.getOut());
154-
}
155-
else {
156-
throw exception;
157-
}
158-
}
159-
return result;
160-
}
161-
162-
private int computeLinePosition(J tree, J targetElement, Cursor cursor) {
163-
return computePosition(tree, targetElement, cursor,
164-
out -> 1 + Math.toIntExact(out.chars().filter(chr -> chr == '\n').count()));
165-
}
166-
167-
private int computeColumnPosition(J tree, J targetElement, Cursor cursor) {
168-
return computePosition(tree, targetElement, cursor, this::calculateColumnOffset);
169-
}
170-
171-
private int calculateColumnOffset(String out) {
172-
final int lineBreakIndex = out.lastIndexOf('\n');
173-
final int result;
174-
if (lineBreakIndex == -1) {
175-
result = out.length();
176-
}
177-
else {
178-
result = out.length() - lineBreakIndex - 1;
179-
}
180-
return result;
181-
}
182-
183101
}
184102
}

0 commit comments

Comments
 (0)