From af4b13837a025a4281ac643b457eeac477cad39e Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 24 Sep 2026 22:54:17 +0300 Subject: [PATCH] Accept a type annotation on the qualifier of a method reference "Supplier> a = @A ArrayList::new;" failed with 'did not generate token "@"'. The printing of a type annotation on a method reference's qualifier was already in place, but visitMemberReference first synced to the tree's start position, and javac's start position for a member reference leaves out the annotation, so the sync reported the annotation's tokens as never generated. This ports google/google-java-format#984 by Liam Miller-Cushon: visitMemberReference no longer syncs to the start position. The golden B308157568 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 | 3 ++- .../javaformat/java/testdata/B308157568.input | 23 +++++++++++++++++++ .../java/testdata/B308157568.output | 23 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/B308157568.input create mode 100644 open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/B308157568.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..e1710b0ff 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 @@ -928,7 +928,8 @@ public boolean visitEnumDeclaration(ClassTree node) { @Override public Void visitMemberReference(MemberReferenceTree node, Void unused) { - sync(node); + // No sync(node): javac's start position for a member reference leaves out a type annotation on its + // qualifier ("@A ArrayList::new"), so syncing to it would report the annotation as never generated. builder.open(OpenOp.builder() .plusIndent(plusFour) .debugName("methodReference") diff --git a/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/B308157568.input b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/B308157568.input new file mode 100644 index 000000000..089a3f1e8 --- /dev/null +++ b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/B308157568.input @@ -0,0 +1,23 @@ +class C { + @A(0x14) + int f(Object o) { + @A(0x40) + int local; + try (@A(0x41) + JarFile jarFile = new JarFile("hello.jar")) { + } catch ( + @A(0x42) + IOException e) { + } + if (o instanceof @A(0x43) String) {} + new @A(0x44) ArrayList<>(); + Supplier> a = @A(0x45) ArrayList::new; + Supplier> b = @A(0x46) ImmutableList::of; + String s = (@A(0x47) String) o; + List xs = new ArrayList<@A(0x48) String>(); + xs = ImmutableList.<@A(0x49) String>of(); + Supplier> c = ArrayList<@A(0x4A) String>::new; + Supplier> d = ImmutableList::<@A(0x4B) String>of; + return 0; + } +} diff --git a/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/B308157568.output b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/B308157568.output new file mode 100644 index 000000000..31eb4bdc2 --- /dev/null +++ b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/B308157568.output @@ -0,0 +1,23 @@ +class C { + @A(0x14) + int f(Object o) { + @A(0x40) + int local; + try (@A(0x41) + JarFile jarFile = new JarFile("hello.jar")) { + } catch ( + @A(0x42) + IOException e) { + } + if (o instanceof @A(0x43) String) {} + new @A(0x44) ArrayList<>(); + Supplier> a = @A(0x45) ArrayList::new; + Supplier> b = @A(0x46) ImmutableList::of; + String s = (@A(0x47) String) o; + List xs = new ArrayList<@A(0x48) String>(); + xs = ImmutableList.<@A(0x49) String>of(); + Supplier> c = ArrayList<@A(0x4A) String>::new; + Supplier> d = ImmutableList::<@A(0x4B) String>of; + return 0; + } +}