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
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 7370b66..ee211b5 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 @@ 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 f3dee6b..28a1103 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 @@ 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<JCVariableDecl> 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 @@ dropEmptyDeclarations(); } + private static Optional<JCMethodDecl> 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<JCVariableDecl> 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 ce9c125..ecbea28 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 @@ } } + 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 @@ 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 bddf08d..c8c435b 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 @@ } } + record Foo(int id) {} + + record Rcv(int id) { + public Rcv(Rcv this, int id) { + this.id = id; + } + } + void g() { var block = """ hello