diff --git a/rewrite-java-test/src/test/java/org/openrewrite/java/format/TabsAndIndentsTest.java b/rewrite-java-test/src/test/java/org/openrewrite/java/format/TabsAndIndentsTest.java
index e4cb56a7a11..070b5b96b03 100644
--- a/rewrite-java-test/src/test/java/org/openrewrite/java/format/TabsAndIndentsTest.java
+++ b/rewrite-java-test/src/test/java/org/openrewrite/java/format/TabsAndIndentsTest.java
@@ -173,6 +173,31 @@ private void firstArgOnNewLine(
);
}
+ @Test
+ void firstParameterNameConflictWithReturnTypeAndMethodName() {
+ rewriteRun(
+ tabsAndIndents(style -> style.withMethodDeclarationParameters(new TabsAndIndentsStyle.MethodDeclarationParameters(true))),
+ java(
+ """
+ class Test {
+ private String first(String first,
+ int times,
+ String third) {
+ }
+ }
+ """,
+ """
+ class Test {
+ private String first(String first,
+ int times,
+ String third) {
+ }
+ }
+ """
+ )
+ );
+ }
+
@Test
void alignMethodDeclarationParamsWhenContinuationIndentUsingTabs() {
rewriteRun(
diff --git a/rewrite-java/src/main/java/org/openrewrite/java/format/TabsAndIndentsVisitor.java b/rewrite-java/src/main/java/org/openrewrite/java/format/TabsAndIndentsVisitor.java
index 3a51e8c3617..33c977107f7 100644
--- a/rewrite-java/src/main/java/org/openrewrite/java/format/TabsAndIndentsVisitor.java
+++ b/rewrite-java/src/main/java/org/openrewrite/java/format/TabsAndIndentsVisitor.java
@@ -17,8 +17,11 @@
import org.jspecify.annotations.Nullable;
import org.openrewrite.Cursor;
+import org.openrewrite.PrintOutputCapture;
import org.openrewrite.Tree;
+import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.ListUtils;
+import org.openrewrite.internal.RecipeRunException;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.style.TabsAndIndentsStyle;
@@ -26,6 +29,7 @@
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.CancellationException;
public class TabsAndIndentsVisitor
extends JavaIsoVisitor
{
@Nullable
@@ -226,30 +230,27 @@ public Space visitSpace(Space space, Space.Location loc, P p) {
}
JContainer container = getCursor().getParentOrThrow().getValue();
List elements = container.getElements();
- J firstArg = elements.iterator().next();
J lastArg = elements.get(elements.size() - 1);
- if (style.getMethodDeclarationParameters().getAlignWhenMultiple()) {
+ if (elements.size() > 1 && style.getMethodDeclarationParameters().getAlignWhenMultiple()) {
J.MethodDeclaration method = getCursor().firstEnclosing(J.MethodDeclaration.class);
if (method != null) {
- int alignTo;
- if (firstArg.getPrefix().getLastWhitespace().contains("\n")) {
- alignTo = getLengthOfWhitespace(firstArg.getPrefix().getLastWhitespace());
+ int alignTo = computeFirstParameterColumn(method);
+ if (alignTo != -1) {
+ getCursor().getParentOrThrow().putMessage("lastIndent", alignTo - style.getContinuationIndent());
+ elem = visitAndCast(elem, p);
+ getCursor().getParentOrThrow().putMessage("lastIndent", indent);
+ after = indentTo(right.getAfter(), t == lastArg ? indent : alignTo, loc.getAfterLocation());
} else {
- String source = method.print(getCursor());
- int firstArgIndex = source.indexOf(firstArg.print(getCursor()));
- int lineBreakIndex = source.lastIndexOf('\n', firstArgIndex);
- alignTo = (firstArgIndex - (lineBreakIndex == -1 ? 0 : lineBreakIndex)) - 1;
+ after = right.getAfter();
}
- getCursor().getParentOrThrow().putMessage("lastIndent", alignTo - style.getContinuationIndent());
- elem = visitAndCast(elem, p);
- getCursor().getParentOrThrow().putMessage("lastIndent", indent);
- after = indentTo(right.getAfter(), t == lastArg ? indent : alignTo, loc.getAfterLocation());
} else {
after = right.getAfter();
}
- } else {
+ } else if (elements.size() > 1) {
elem = visitAndCast(elem, p);
after = indentTo(right.getAfter(), t == lastArg ? indent : style.getContinuationIndent(), loc.getAfterLocation());
+ } else {
+ after = right.getAfter();
}
break;
}
@@ -353,6 +354,37 @@ public Space visitSpace(Space space, Space.Location loc, P p) {
return (after == right.getAfter() && t == right.getElement()) ? right : new JRightPadded<>(t, after, right.getMarkers());
}
+ private int computeFirstParameterColumn(J.MethodDeclaration method) {
+ List> arguments = method.getPadding().getParameters().getPadding().getElements();
+ J firstArg = arguments.isEmpty() ? null : arguments.get(0).getElement();
+ if (firstArg == null || firstArg instanceof J.Empty) {
+ return -1;
+ }
+
+ if (firstArg.getPrefix().getLastWhitespace().contains("\n")) {
+ return getLengthOfWhitespace(firstArg.getPrefix().getLastWhitespace());
+ } else {
+ TreeVisitor, PrintOutputCapture>> printer = method.printer(getCursor());
+ PrintOutputCapture> capture = new PrintOutputCapture>(printer) {
+ @Override
+ public PrintOutputCapture> append(@Nullable String text) {
+ if (getContext().getCursor().getValue() == firstArg) {
+ throw new CancellationException();
+ }
+ return super.append(text);
+ }
+ };
+ try {
+ printer.visit(method, capture, getCursor().getParentOrThrow());
+ throw new IllegalStateException();
+ } catch (RecipeRunException e) {
+ String out = capture.getOut();
+ int lineBreakIndex = out.lastIndexOf('\n');
+ return (out.length() - (lineBreakIndex == -1 ? 0 : lineBreakIndex)) - 1;
+ }
+ }
+ }
+
@Override
public @Nullable JContainer visitContainer(@Nullable JContainer container, JContainer.Location loc, P p) {
if (container == null) {