From a399e821dab2ad6286d5f5ad4ff8299cbc8b41fb Mon Sep 17 00:00:00 2001 From: cushon Date: Mon, 27 Apr 2020 11:13:08 -0700 Subject: [PATCH] Fix formatting of records without an explicit constructor Fixes https://github.com/google/google-java-format/issues/460 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=308658958 --- .../java/JavaInputAstVisitor.java | 5 ++- .../java/java14/Java14InputAstVisitor.java | 38 +++++++++++++------ .../java/testdata/java14.input | 10 ++++- .../java/testdata/java14.output | 8 ++++ 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 7370b668c..ee211b500 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1332,9 +1332,12 @@ public Void visitAnnotatedType(AnnotatedTypeTree node, Void unused) { return null; } - // TODO(cushon): Use Flags.COMPACT_RECORD_CONSTRUCTOR once if/when we drop support for Java 11 + // TODO(cushon): Use Flags if/when we drop support for Java 11 + protected static final long COMPACT_RECORD_CONSTRUCTOR = 1L << 51; + protected static final long RECORD = 1L << 61; + @Override public Void visitMethod(MethodTree node, Void unused) { sync(node); diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index f3dee6b67..28a110395 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -15,9 +15,10 @@ package com.google.googlejavaformat.java.java14; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.MoreCollectors.onlyElement; +import static com.google.common.collect.MoreCollectors.toOptional; import com.google.common.base.Verify; +import com.google.common.collect.ImmutableList; import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.java.JavaInputAstVisitor; @@ -26,13 +27,13 @@ import com.sun.source.tree.ClassTree; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.InstanceOfTree; -import com.sun.source.tree.MethodTree; import com.sun.source.tree.SwitchExpressionTree; import com.sun.source.tree.Tree; import com.sun.source.tree.YieldTree; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeInfo; import java.util.List; import java.util.Optional; @@ -112,20 +113,17 @@ public void visitRecordDeclaration(ClassTree node) { if (!node.getTypeParameters().isEmpty()) { typeParametersRest(node.getTypeParameters(), hasSuperInterfaceTypes ? plusFour : ZERO); } - MethodTree constructor = - node.getMembers().stream() - .filter(JCMethodDecl.class::isInstance) - .map(JCMethodDecl.class::cast) - .filter( - m -> (m.mods.flags & COMPACT_RECORD_CONSTRUCTOR) == COMPACT_RECORD_CONSTRUCTOR) - .collect(onlyElement()); + ImmutableList parameters = + compactRecordConstructor(node) + .map(m -> ImmutableList.copyOf(m.getParameters())) + .orElseGet(() -> recordVariables(node)); token("("); - if (!constructor.getParameters().isEmpty() || constructor.getReceiverParameter() != null) { + if (!parameters.isEmpty()) { // Break before args. builder.breakToFill(""); } - visitFormals( - Optional.ofNullable(constructor.getReceiverParameter()), constructor.getParameters()); + // record headers can't declare receiver parameters + visitFormals(/* receiver= */ Optional.empty(), parameters); token(")"); if (hasSuperInterfaceTypes) { builder.breakToFill(" "); @@ -157,6 +155,22 @@ public void visitRecordDeclaration(ClassTree node) { dropEmptyDeclarations(); } + private static Optional compactRecordConstructor(ClassTree node) { + return node.getMembers().stream() + .filter(JCMethodDecl.class::isInstance) + .map(JCMethodDecl.class::cast) + .filter(m -> (m.mods.flags & COMPACT_RECORD_CONSTRUCTOR) == COMPACT_RECORD_CONSTRUCTOR) + .collect(toOptional()); + } + + private static ImmutableList recordVariables(ClassTree node) { + return node.getMembers().stream() + .filter(JCVariableDecl.class::isInstance) + .map(JCVariableDecl.class::cast) + .filter(m -> (m.mods.flags & RECORD) == RECORD) + .collect(toImmutableList()); + } + @Override public Void visitInstanceOf(InstanceOfTree node, Void unused) { sync(node); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input index ce9c1257c..ecbea285b 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input @@ -19,6 +19,14 @@ class Java14 { } } + record Foo(int id) {} + + record Rcv(int id) { + public Rcv(Rcv this, int id) { + this.id = id; + } + } + void g() { var block = """ hello @@ -35,4 +43,4 @@ class Java14 { case WEDNESDAY -> 9; }; } -} \ No newline at end of file +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output index bddf08da7..c8c435bbd 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output @@ -19,6 +19,14 @@ class Java14 { } } + record Foo(int id) {} + + record Rcv(int id) { + public Rcv(Rcv this, int id) { + this.id = id; + } + } + void g() { var block = """ hello