From fcb02415351e0a20ec7e92f41baf0d6b9cc74331 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 9 Nov 2021 09:35:32 -0800 Subject: [PATCH] Handle compact record constructors https://github.com/bazelbuild/bazel/issues/14249 PiperOrigin-RevId: 408631525 --- .../com/google/turbine/binder/TypeBinder.java | 34 +++++++++++++++---- .../com/google/turbine/model/TurbineFlag.java | 3 ++ java/com/google/turbine/parse/Parser.java | 19 +++++++++++ java/com/google/turbine/tree/Pretty.java | 1 + .../google/turbine/tree/TurbineModifier.java | 3 +- .../turbine/lower/LowerIntegrationTest.java | 5 ++- .../turbine/lower/testdata/record2.test | 27 +++++++++++++++ 7 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 javatests/com/google/turbine/lower/testdata/record2.test diff --git a/java/com/google/turbine/binder/TypeBinder.java b/java/com/google/turbine/binder/TypeBinder.java index ccc0ad3a..e2011e2f 100644 --- a/java/com/google/turbine/binder/TypeBinder.java +++ b/java/com/google/turbine/binder/TypeBinder.java @@ -251,7 +251,7 @@ private SourceTypeBoundClass bind() { ImmutableList.Builder methods = ImmutableList.builder() .addAll(syntheticMethods(syntheticMethods, components)) - .addAll(bindMethods(scope, base.decl().members())); + .addAll(bindMethods(scope, base.decl().members(), components)); if (base.kind().equals(TurbineTyKind.RECORD)) { methods.addAll(syntheticRecordMethods(syntheticMethods, components)); } @@ -563,18 +563,22 @@ private ImmutableMap bindTyParams( return result.build(); } - private List bindMethods(CompoundScope scope, ImmutableList members) { + private List bindMethods( + CompoundScope scope, + ImmutableList members, + ImmutableList components) { List methods = new ArrayList<>(); int idx = 0; for (Tree member : members) { if (member.kind() == Tree.Kind.METH_DECL) { - methods.add(bindMethod(idx++, scope, (Tree.MethDecl) member)); + methods.add(bindMethod(idx++, scope, (MethDecl) member, components)); } } return methods; } - private MethodInfo bindMethod(int idx, CompoundScope scope, Tree.MethDecl t) { + private MethodInfo bindMethod( + int idx, CompoundScope scope, MethDecl t, ImmutableList components) { MethodSymbol sym = new MethodSymbol(idx, owner, t.name().value()); @@ -604,8 +608,26 @@ private MethodInfo bindMethod(int idx, CompoundScope scope, Tree.MethDecl t) { if (name.equals("")) { if (hasEnclosingInstance(base)) { parameters.add(enclosingInstanceParameter(sym)); - } else if (base.kind() == TurbineTyKind.ENUM && name.equals("")) { - parameters.addAll(enumCtorParams(sym)); + } else { + switch (base.kind()) { + case ENUM: + parameters.addAll(enumCtorParams(sym)); + break; + case RECORD: + if (t.mods().contains(TurbineModifier.COMPACT_CTOR)) { + for (RecordComponentInfo component : components) { + parameters.add( + new ParamInfo( + new ParamSymbol(sym, component.name()), + component.type(), + component.annotations(), + component.access())); + } + } + break; + default: + break; + } } } ParamInfo receiver = null; diff --git a/java/com/google/turbine/model/TurbineFlag.java b/java/com/google/turbine/model/TurbineFlag.java index 6e8d64bc..3e68a5e6 100644 --- a/java/com/google/turbine/model/TurbineFlag.java +++ b/java/com/google/turbine/model/TurbineFlag.java @@ -58,5 +58,8 @@ public final class TurbineFlag { public static final int ACC_SEALED = 1 << 19; public static final int ACC_NON_SEALED = 1 << 20; + /** Compact record constructor. */ + public static final int ACC_COMPACT_CTOR = 1 << 21; + private TurbineFlag() {} } diff --git a/java/com/google/turbine/parse/Parser.java b/java/com/google/turbine/parse/Parser.java index ed8958ee..c370ad8d 100644 --- a/java/com/google/turbine/parse/Parser.java +++ b/java/com/google/turbine/parse/Parser.java @@ -846,6 +846,25 @@ private ImmutableList member( name = ident; return ImmutableList.of(methodRest(pos, access, annos, typaram, null, name)); } + case LBRACE: + { + dropBlocks(); + name = new Ident(position, CTOR_NAME); + String javadoc = lexer.javadoc(); + access.add(TurbineModifier.COMPACT_CTOR); + return ImmutableList.of( + new MethDecl( + pos, + access, + annos, + typaram, + /* ret= */ Optional.empty(), + name, + /* params= */ ImmutableList.of(), + /* exntys= */ ImmutableList.of(), + /* defaultValue= */ Optional.empty(), + javadoc)); + } case IDENT: { result = diff --git a/java/com/google/turbine/tree/Pretty.java b/java/com/google/turbine/tree/Pretty.java index 788ab58d..4ebc04f6 100644 --- a/java/com/google/turbine/tree/Pretty.java +++ b/java/com/google/turbine/tree/Pretty.java @@ -544,6 +544,7 @@ private void printModifiers(ImmutableSet mods) { case ACC_ANNOTATION: case ACC_SYNTHETIC: case ACC_BRIDGE: + case COMPACT_CTOR: break; } } diff --git a/java/com/google/turbine/tree/TurbineModifier.java b/java/com/google/turbine/tree/TurbineModifier.java index e5153b91..2bfe53e9 100644 --- a/java/com/google/turbine/tree/TurbineModifier.java +++ b/java/com/google/turbine/tree/TurbineModifier.java @@ -47,7 +47,8 @@ public enum TurbineModifier { DEFAULT(TurbineFlag.ACC_DEFAULT), TRANSITIVE(TurbineFlag.ACC_TRANSITIVE), SEALED(TurbineFlag.ACC_SEALED), - NON_SEALED(TurbineFlag.ACC_NON_SEALED); + NON_SEALED(TurbineFlag.ACC_NON_SEALED), + COMPACT_CTOR(TurbineFlag.ACC_COMPACT_CTOR); private final int flag; diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java index db73ec0f..b45559f2 100644 --- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java +++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java @@ -44,9 +44,7 @@ public class LowerIntegrationTest { private static final ImmutableMap SOURCE_VERSION = - ImmutableMap.of( - "record.test", 16, - "sealed.test", 17); + ImmutableMap.of("record.test", 16, "record2.test", 16, "sealed.test", 17); @Parameters(name = "{index}: {0}") public static Iterable parameters() { @@ -265,6 +263,7 @@ public static Iterable parameters() { "rawfbound.test", "receiver_param.test", "record.test", + "record2.test", "rek.test", "samepkg.test", "sealed.test", diff --git a/javatests/com/google/turbine/lower/testdata/record2.test b/javatests/com/google/turbine/lower/testdata/record2.test new file mode 100644 index 00000000..af4093eb --- /dev/null +++ b/javatests/com/google/turbine/lower/testdata/record2.test @@ -0,0 +1,27 @@ +=== Records.java === + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.Objects; + +class Records { + public record R1(String one) { + public R1 { + Objects.requireNonNull(one); + } + } + + public record R2(String one) { + @Deprecated + public R2 { + Objects.requireNonNull(one); + } + } + + public record R3(T x) { + @Deprecated + public R3 { + Objects.requireNonNull(x); + } + } +}