From 4ed1716e03a64198f1cf23fd64bf6a4e3990aeeb Mon Sep 17 00:00:00 2001 From: cushon Date: Thu, 24 Sep 2026 22:51:05 +0300 Subject: [PATCH] Accept an annotated C-style array dimension on a parameter A method parameter declared as "int a @Anno []" crashed the formatter with a VerifyException from visitAnnotatedArrayType: the parameter's type was printed as a whole, dimensions included, before the name, and the annotated dimension that belongs after the name had nowhere to go. Fields and locals were fine, because their path already splits the dimensions off the type; parameters, resources and catch parameters go through visitToDeclare, which did not. This ports the fix for google/google-java-format#374, upstream commit ed40e472 by cushon, together with the null check that google/google-java-format#463 (upstream commit e19b7637) added next to it: a "var" declaration or an untyped lambda parameter has no type tree to split. The golden I374 comes from upstream, with the expected output in this project's style. The 15,747 files of the JDK 21 sources format exactly as before. --- .../javaformat/java/JavaInputAstVisitor.java | 15 +++++++++++++-- .../palantir/javaformat/java/testdata/I374.input | 9 +++++++++ .../palantir/javaformat/java/testdata/I374.output | 9 +++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/I374.input create mode 100644 open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/I374.output diff --git a/open-java-format/src/main/java/com/palantir/javaformat/java/JavaInputAstVisitor.java b/open-java-format/src/main/java/com/palantir/javaformat/java/JavaInputAstVisitor.java index 0fd3569d8..e17ac664d 100644 --- a/open-java-format/src/main/java/com/palantir/javaformat/java/JavaInputAstVisitor.java +++ b/open-java-format/src/main/java/com/palantir/javaformat/java/JavaInputAstVisitor.java @@ -2669,18 +2669,29 @@ private void visitToDeclare( Optional trailing, Optional annotationBreakForRecords) { sync(node); + Optional typeWithDims; + Tree type; + if (node.getType() != null) { + TypeWithDims extractedDims = DimensionHelpers.extractDims(node.getType(), SortedDims.YES); + typeWithDims = Optional.of(extractedDims); + type = extractedDims.node; + } else { + // "var" and an untyped lambda parameter have no type tree + typeWithDims = Optional.empty(); + type = null; + } declareOne( kind, annotationsDirection, Optional.of(node.getModifiers()), - node.getType(), + type, node.getName(), "", equals, initializer, trailing, /* receiverExpression= */ Optional.empty(), - /* typeWithDims= */ Optional.empty(), + typeWithDims, annotationBreakForRecords); } diff --git a/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/I374.input b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/I374.input new file mode 100644 index 000000000..a36919e4d --- /dev/null +++ b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/I374.input @@ -0,0 +1,9 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface MyTypeAnno {} + +public class GjfFailure { + void m(int a @MyTypeAnno []) {} +} diff --git a/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/I374.output b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/I374.output new file mode 100644 index 000000000..50a731dc6 --- /dev/null +++ b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/I374.output @@ -0,0 +1,9 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface MyTypeAnno {} + +public class GjfFailure { + void m(int a @MyTypeAnno []) {} +}