diff --git a/rewrite-java-11/src/main/java/org/openrewrite/java/isolated/ReloadableJava11ParserVisitor.java b/rewrite-java-11/src/main/java/org/openrewrite/java/isolated/ReloadableJava11ParserVisitor.java index b6fa2675765..d683e93bc5b 100644 --- a/rewrite-java-11/src/main/java/org/openrewrite/java/isolated/ReloadableJava11ParserVisitor.java +++ b/rewrite-java-11/src/main/java/org/openrewrite/java/isolated/ReloadableJava11ParserVisitor.java @@ -1364,9 +1364,22 @@ private TypeTree arrayTypeTree(Tree tree, Map annotationP elemType = convert(typeIdent); } List annotations = leadingAnnotations(annotationPosTable); - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } + assert arrayTypeTree != null; - TypeTree result = new J.ArrayType(randomId(), prefix, Markers.EMPTY, + TypeTree result = new J.ArrayType(randomId(), prefix, markers, count == 1 ? elemType : mapDimensions(elemType, arrayTypeTree.getType(), annotationPosTable), annotations, dimension, @@ -1386,22 +1399,32 @@ private TypeTree mapDimensions(TypeTree baseType, Tree tree, Map annotations = leadingAnnotations(annotationPosTable); - int saveCursor = cursor; - whitespace(); - if (source.startsWith("[", cursor)) { - cursor = saveCursor; - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); - return new J.ArrayType( - randomId(), - EMPTY, - Markers.EMPTY, - mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), - annotations, - dimension, - typeMapping.type(tree) - ); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else if (source.startsWith("[", nextNonWhitespace)) { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } else { + // No dimension found + return baseType; } - cursor = saveCursor; + + return new J.ArrayType( + randomId(), + EMPTY, + markers, + mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), + annotations, + dimension, + typeMapping.type(tree) + ); } return baseType; } @@ -1582,7 +1605,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm } } int idx = indexOfNextNonWhitespace(elementType.getEndPosition(endPosTable), source); - typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@') ? convert(vartype) : + typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@' || source.startsWith("...", idx)) ? convert(vartype) : // we'll capture the array dimensions in a bit, just convert the element type convert(elementType); } else { @@ -1608,17 +1631,6 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm typeExpr = new J.AnnotatedType(randomId(), prefix, Markers.EMPTY, ListUtils.mapFirst(typeExprAnnotations, a -> a.withPrefix(EMPTY)), typeExpr); } - List> beforeDimensions = emptyList(); - - Space varargs = null; - if (typeExpr != null && typeExpr.getMarkers().findFirst(JavaVarKeyword.class).isEmpty()) { - int varargStart = indexOfNextNonWhitespace(cursor, source); - if (source.startsWith("...", varargStart)) { - varargs = format(source, cursor, varargStart); - cursor = varargStart + 3; - } - } - List> vars = new ArrayList<>(nodes.size()); for (int i = 0; i < nodes.size(); i++) { JCVariableDecl n = (JCVariableDecl) nodes.get(i); @@ -1644,7 +1656,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm ); } - return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, varargs, beforeDimensions, vars); + return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, null, vars); } private List> arrayDimensions() { diff --git a/rewrite-java-17/src/main/java/org/openrewrite/java/isolated/ReloadableJava17ParserVisitor.java b/rewrite-java-17/src/main/java/org/openrewrite/java/isolated/ReloadableJava17ParserVisitor.java index eb9a635f83a..e0d3e355cdb 100644 --- a/rewrite-java-17/src/main/java/org/openrewrite/java/isolated/ReloadableJava17ParserVisitor.java +++ b/rewrite-java-17/src/main/java/org/openrewrite/java/isolated/ReloadableJava17ParserVisitor.java @@ -1507,9 +1507,22 @@ private TypeTree arrayTypeTree(Tree tree, Map annotationP elemType = convert(typeIdent); } List annotations = leadingAnnotations(annotationPosTable); - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } + assert arrayTypeTree != null; - TypeTree result = new J.ArrayType(randomId(), prefix, Markers.EMPTY, + TypeTree result = new J.ArrayType(randomId(), prefix, markers, count == 1 ? elemType : mapDimensions(elemType, arrayTypeTree.getType(), annotationPosTable), annotations, dimension, @@ -1529,22 +1542,32 @@ private TypeTree mapDimensions(TypeTree baseType, Tree tree, Map annotations = leadingAnnotations(annotationPosTable); - int saveCursor = cursor; - whitespace(); - if (source.startsWith("[", cursor)) { - cursor = saveCursor; - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); - return new J.ArrayType( - randomId(), - EMPTY, - Markers.EMPTY, - mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), - annotations, - dimension, - typeMapping.type(tree) - ); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else if (source.startsWith("[", nextNonWhitespace)) { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } else { + // No dimension found + return baseType; } - cursor = saveCursor; + + return new J.ArrayType( + randomId(), + EMPTY, + markers, + mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), + annotations, + dimension, + typeMapping.type(tree) + ); } return baseType; } @@ -1725,7 +1748,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm } } int idx = indexOfNextNonWhitespace(elementType.getEndPosition(endPosTable), source); - typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@') ? convert(vartype) : + typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@' || source.startsWith("...", idx)) ? convert(vartype) : // we'll capture the array dimensions in a bit, just convert the element type convert(elementType); } else { @@ -1741,15 +1764,6 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm typeExpr = new J.AnnotatedType(randomId(), prefix, Markers.EMPTY, ListUtils.mapFirst(typeExprAnnotations, a -> a.withPrefix(EMPTY)), typeExpr); } - Space varargs = null; - if (typeExpr != null && typeExpr.getMarkers().findFirst(JavaVarKeyword.class).isEmpty()) { - int varargStart = indexOfNextNonWhitespace(cursor, source); - if (source.startsWith("...", varargStart)) { - varargs = format(source, cursor, varargStart); - cursor = varargStart + 3; - } - } - List> vars = new ArrayList<>(nodes.size()); for (int i = 0; i < nodes.size(); i++) { JCVariableDecl n = (JCVariableDecl) nodes.get(i); @@ -1775,7 +1789,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm ); } - return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, varargs, vars); + return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, null, vars); } private List> arrayDimensions() { diff --git a/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java b/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java index fb3137f9697..9d478f06d49 100644 --- a/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java +++ b/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java @@ -1538,9 +1538,22 @@ private TypeTree arrayTypeTree(Tree tree, Map annotationP elemType = convert(typeIdent); } List annotations = leadingAnnotations(annotationPosTable); - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } + assert arrayTypeTree != null; - TypeTree result = new J.ArrayType(randomId(), prefix, Markers.EMPTY, + TypeTree result = new J.ArrayType(randomId(), prefix, markers, count == 1 ? elemType : mapDimensions(elemType, arrayTypeTree.getType(), annotationPosTable), annotations, dimension, @@ -1560,22 +1573,32 @@ private TypeTree mapDimensions(TypeTree baseType, Tree tree, Map annotations = leadingAnnotations(annotationPosTable); - int saveCursor = cursor; - whitespace(); - if (source.startsWith("[", cursor)) { - cursor = saveCursor; - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); - return new J.ArrayType( - randomId(), - EMPTY, - Markers.EMPTY, - mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), - annotations, - dimension, - typeMapping.type(tree) - ); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else if (source.startsWith("[", nextNonWhitespace)) { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } else { + // No dimension found + return baseType; } - cursor = saveCursor; + + return new J.ArrayType( + randomId(), + EMPTY, + markers, + mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), + annotations, + dimension, + typeMapping.type(tree) + ); } return baseType; } @@ -1756,7 +1779,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm } } int idx = indexOfNextNonWhitespace(elementType.getEndPosition(endPosTable), source); - typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@') ? convert(vartype) : + typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@' || source.startsWith("...", idx)) ? convert(vartype) : // we'll capture the array dimensions in a bit, just convert the element type convert(elementType); } else { @@ -1773,15 +1796,6 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm typeExpr = new J.AnnotatedType(randomId(), prefix, Markers.EMPTY, ListUtils.mapFirst(typeExprAnnotations, a -> a.withPrefix(EMPTY)), typeExpr); } - Space varargs = null; - if (typeExpr != null && typeExpr.getMarkers().findFirst(JavaVarKeyword.class).isEmpty()) { - int varargStart = indexOfNextNonWhitespace(cursor, source); - if (source.startsWith("...", varargStart)) { - varargs = format(source, cursor, varargStart); - cursor = varargStart + 3; - } - } - List> vars = new ArrayList<>(nodes.size()); for (int i = 0; i < nodes.size(); i++) { JCVariableDecl n = (JCVariableDecl) nodes.get(i); @@ -1807,7 +1821,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm ); } - return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, varargs, vars); + return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, null, vars); } private List> arrayDimensions() { diff --git a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java index b20c6c9c40f..32495a11fa8 100644 --- a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java +++ b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java @@ -1572,9 +1572,22 @@ private TypeTree arrayTypeTree(Tree tree, Map annotationP elemType = convert(typeIdent); } List annotations = leadingAnnotations(annotationPosTable); - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } + assert arrayTypeTree != null; - TypeTree result = new J.ArrayType(randomId(), prefix, Markers.EMPTY, + TypeTree result = new J.ArrayType(randomId(), prefix, markers, count == 1 ? elemType : mapDimensions(elemType, arrayTypeTree.getType(), annotationPosTable), annotations, dimension, @@ -1594,22 +1607,32 @@ private TypeTree mapDimensions(TypeTree baseType, Tree tree, Map annotations = leadingAnnotations(annotationPosTable); - int saveCursor = cursor; - whitespace(); - if (source.startsWith("[", cursor)) { - cursor = saveCursor; - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); - return new J.ArrayType( - randomId(), - EMPTY, - Markers.EMPTY, - mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), - annotations, - dimension, - typeMapping.type(tree) - ); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else if (source.startsWith("[", nextNonWhitespace)) { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } else { + // No dimension found + return baseType; } - cursor = saveCursor; + + return new J.ArrayType( + randomId(), + EMPTY, + markers, + mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), + annotations, + dimension, + typeMapping.type(tree) + ); } return baseType; } @@ -1790,7 +1813,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm } } int idx = indexOfNextNonWhitespace(elementType.getEndPosition(endPosTable), source); - typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@') ? convert(vartype) : + typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@' || source.startsWith("...", idx)) ? convert(vartype) : // we'll capture the array dimensions in a bit, just convert the element type convert(elementType); } else { @@ -1807,15 +1830,6 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm typeExpr = new J.AnnotatedType(randomId(), prefix, Markers.EMPTY, ListUtils.mapFirst(typeExprAnnotations, a -> a.withPrefix(EMPTY)), typeExpr); } - Space varargs = null; - if (typeExpr != null && typeExpr.getMarkers().findFirst(JavaVarKeyword.class).isEmpty()) { - int varargStart = indexOfNextNonWhitespace(cursor, source); - if (source.startsWith("...", varargStart)) { - varargs = format(source, cursor, varargStart); - cursor = varargStart + 3; - } - } - List> vars = new ArrayList<>(nodes.size()); for (int i = 0; i < nodes.size(); i++) { JCVariableDecl n = (JCVariableDecl) nodes.get(i); @@ -1844,7 +1858,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm ); } - return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, varargs, vars); + return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, null, vars); } private List> arrayDimensions() { diff --git a/rewrite-java-8/src/main/java/org/openrewrite/java/ReloadableJava8ParserVisitor.java b/rewrite-java-8/src/main/java/org/openrewrite/java/ReloadableJava8ParserVisitor.java index bd7913da93b..44c47592d0c 100644 --- a/rewrite-java-8/src/main/java/org/openrewrite/java/ReloadableJava8ParserVisitor.java +++ b/rewrite-java-8/src/main/java/org/openrewrite/java/ReloadableJava8ParserVisitor.java @@ -1357,9 +1357,22 @@ private TypeTree arrayTypeTree(Tree tree, Map annotationP elemType = convert(typeIdent); } List annotations = leadingAnnotations(annotationPosTable); - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } + assert arrayTypeTree != null; - TypeTree result = new J.ArrayType(randomId(), prefix, Markers.EMPTY, + TypeTree result = new J.ArrayType(randomId(), prefix, markers, count == 1 ? elemType : mapDimensions(elemType, arrayTypeTree.getType(), annotationPosTable), annotations, dimension, @@ -1379,22 +1392,32 @@ private TypeTree mapDimensions(TypeTree baseType, Tree tree, Map annotations = leadingAnnotations(annotationPosTable); - int saveCursor = cursor; - whitespace(); - if (source.startsWith("[", cursor)) { - cursor = saveCursor; - JLeftPadded dimension = padLeft(sourceBefore("["), sourceBefore("]")); - return new J.ArrayType( - randomId(), - EMPTY, - Markers.EMPTY, - mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), - annotations, - dimension, - typeMapping.type(tree) - ); + + // Check if this is varargs (...) or regular array brackets ([]) + Markers markers = Markers.EMPTY; + JLeftPadded dimension; + int nextNonWhitespace = indexOfNextNonWhitespace(cursor, source); + if (source.startsWith("...", nextNonWhitespace)) { + // Varargs syntax + markers = markers.addIfAbsent(new org.openrewrite.java.marker.Varargs(randomId())); + dimension = padLeft(sourceBefore("..."), EMPTY); + } else if (source.startsWith("[", nextNonWhitespace)) { + // Regular array brackets + dimension = padLeft(sourceBefore("["), sourceBefore("]")); + } else { + // No dimension found + return baseType; } - cursor = saveCursor; + + return new J.ArrayType( + randomId(), + EMPTY, + markers, + mapDimensions(baseType, ((JCArrayTypeTree) typeIdent).elemtype, annotationPosTable), + annotations, + dimension, + typeMapping.type(tree) + ); } return baseType; } @@ -1570,7 +1593,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm } } int idx = indexOfNextNonWhitespace(elementType.getEndPosition(endPosTable), source); - typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@') ? convert(vartype) : + typeExpr = idx != -1 && (source.charAt(idx) == '[' || source.charAt(idx) == '@' || source.startsWith("...", idx)) ? convert(vartype) : // we'll capture the array dimensions in a bit, just convert the element type convert(elementType); } else { @@ -1582,17 +1605,6 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm typeExpr = new J.AnnotatedType(randomId(), prefix, Markers.EMPTY, ListUtils.mapFirst(typeExprAnnotations, a -> a.withPrefix(EMPTY)), typeExpr); } - List> beforeDimensions = emptyList(); - - Space varargs = null; - if (typeExpr != null) { - int varargStart = indexOfNextNonWhitespace(cursor, source); - if (source.startsWith("...", varargStart)) { - varargs = format(source, cursor, varargStart); - cursor = varargStart + 3; - } - } - List> vars = new ArrayList<>(nodes.size()); for (int i = 0; i < nodes.size(); i++) { JCVariableDecl n = (JCVariableDecl) nodes.get(i); @@ -1618,7 +1630,7 @@ private J.VariableDeclarations visitVariables(List nodes, Space fm ); } - return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, varargs, beforeDimensions, vars); + return new J.VariableDeclarations(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), typeExpr, null, vars); } private List> arrayDimensions() { diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/AnnotationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/AnnotationTest.java index 8d7f2b490d8..6a6bbf653b3 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/AnnotationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/AnnotationTest.java @@ -690,4 +690,64 @@ class A { ) ); } + + @Issue("https://github.com/openrewrite/rewrite/issues/3881") + @Test + void annotatedVarargs() { + rewriteRun( + java( + """ + package com.example; + + import org.jspecify.annotations.NonNull; + + class Test { + void method(@NonNull String @NonNull ... args) { + } + } + """ + ) + ); + } + + @Issue("https://github.com/openrewrite/rewrite/issues/3881") + @Test + void annotatedVarargsFinal() { + rewriteRun( + java( + """ + package com.example; + + import org.jspecify.annotations.NonNull; + + class Test { + private String method(@NonNull final String @NonNull... args) { + return ""; + } + } + """ + ) + ); + } + + @Issue("https://github.com/openrewrite/rewrite/issues/3881") + @Test + void multipleParametersWithAnnotatedVarargs() { + rewriteRun( + java( + """ + package com.example; + + import org.jspecify.annotations.NonNull; + + class Test { + public static int resolvePoolSize(@NonNull String propertyName, @NonNull String value, + @NonNull String @NonNull... magicValues) { + return 0; + } + } + """ + ) + ); + } } diff --git a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java index c9b1749c792..32116270a9a 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java @@ -218,9 +218,15 @@ public J visitArrayType(ArrayType arrayType, PrintOutputCapture

p) { visit(arrayType.getAnnotations(), p); if (arrayType.getDimension() != null) { visitSpace(arrayType.getDimension().getBefore(), Space.Location.DIMENSION_PREFIX, p); - p.append('['); - visitSpace(arrayType.getDimension().getElement(), Space.Location.DIMENSION, p); - p.append(']'); + if (arrayType.getMarkers().findFirst(Varargs.class).isPresent()) { + // Print varargs syntax + p.append("..."); + } else { + // Print regular array brackets + p.append('['); + visitSpace(arrayType.getDimension().getElement(), Space.Location.DIMENSION, p); + p.append(']'); + } if (arrayType.getElementType() instanceof J.ArrayType) { printDimensions((ArrayType) arrayType.getElementType(), p); @@ -234,9 +240,15 @@ private void printDimensions(J.ArrayType arrayType, PrintOutputCapture

p) { beforeSyntax(arrayType, Space.Location.ARRAY_TYPE_PREFIX, p); visit(arrayType.getAnnotations(), p); visitSpace(arrayType.getDimension().getBefore(), Space.Location.DIMENSION_PREFIX, p); - p.append('['); - visitSpace(arrayType.getDimension().getElement(), Space.Location.DIMENSION, p); - p.append(']'); + if (arrayType.getMarkers().findFirst(Varargs.class).isPresent()) { + // Print varargs syntax + p.append("..."); + } else { + // Print regular array brackets + p.append('['); + visitSpace(arrayType.getDimension().getElement(), Space.Location.DIMENSION, p); + p.append(']'); + } if (arrayType.getElementType() instanceof J.ArrayType) { printDimensions((ArrayType) arrayType.getElementType(), p); } diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/Varargs.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/Varargs.java new file mode 100644 index 00000000000..5a88f5deb2d --- /dev/null +++ b/rewrite-java/src/main/java/org/openrewrite/java/marker/Varargs.java @@ -0,0 +1,34 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.marker; + +import lombok.Value; +import lombok.With; +import org.openrewrite.marker.Marker; + +import java.util.UUID; + +/** + * Indicates that a {@link org.openrewrite.java.tree.J.ArrayType} represents a varargs parameter type. + * When present, the array type should be printed using {@code ...} syntax instead of {@code []}. + *

+ * For example, {@code String...} instead of {@code String[]}. + */ +@Value +@With +public class Varargs implements Marker { + UUID id; +} diff --git a/rewrite-java/src/main/java/org/openrewrite/java/tree/J.java b/rewrite-java/src/main/java/org/openrewrite/java/tree/J.java index e28b3c458ce..c401229d081 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/tree/J.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/tree/J.java @@ -6171,6 +6171,7 @@ final class VariableDeclarations implements J, Statement, TypedTree { @With @Nullable @Getter + @Deprecated Space varargs; @Deprecated diff --git a/rewrite-java/src/test/java/org/openrewrite/java/format/SpacesVisitorTest.java b/rewrite-java/src/test/java/org/openrewrite/java/format/SpacesVisitorTest.java index 0f9452d0e3a..dbdce2631eb 100644 --- a/rewrite-java/src/test/java/org/openrewrite/java/format/SpacesVisitorTest.java +++ b/rewrite-java/src/test/java/org/openrewrite/java/format/SpacesVisitorTest.java @@ -373,7 +373,7 @@ void method( String first , int ... values ) { """, """ class Test { - void method(String first, int... values) {} + void method(String first, int ... values) {} } """ )