No keep rule on Record
Bug: 197081367
Change-Id: I1a4d869f15cae04683474b22e0079bbc1ab19ab2
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordCfMethods.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordCfMethods.java
index adab36a..ed388b8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordCfMethods.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordCfMethods.java
@@ -123,7 +123,7 @@
new int[] {0, 1, 2},
new FrameType[] {
FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")),
- FrameType.initialized(options.itemFactory.stringType),
+ FrameType.initialized(options.itemFactory.classType),
FrameType.initialized(options.itemFactory.stringType)
}),
new ArrayDeque<>(Arrays.asList())),
@@ -144,7 +144,7 @@
new int[] {0, 1, 2},
new FrameType[] {
FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")),
- FrameType.initialized(options.itemFactory.stringType),
+ FrameType.initialized(options.itemFactory.classType),
FrameType.initialized(options.itemFactory.stringType)
}),
new ArrayDeque<>(
@@ -169,6 +169,13 @@
new CfInvoke(
182,
options.itemFactory.createMethod(
+ options.itemFactory.classType,
+ options.itemFactory.createProto(options.itemFactory.stringType),
+ options.itemFactory.createString("getSimpleName")),
+ false),
+ new CfInvoke(
+ 182,
+ options.itemFactory.createMethod(
options.itemFactory.stringBuilderType,
options.itemFactory.createProto(
options.itemFactory.stringBuilderType, options.itemFactory.stringType),
@@ -193,7 +200,7 @@
new int[] {0, 1, 2, 3, 4, 5},
new FrameType[] {
FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")),
- FrameType.initialized(options.itemFactory.stringType),
+ FrameType.initialized(options.itemFactory.classType),
FrameType.initialized(options.itemFactory.stringType),
FrameType.initialized(options.itemFactory.createType("[Ljava/lang/String;")),
FrameType.initialized(options.itemFactory.stringBuilderType),
@@ -263,7 +270,7 @@
new int[] {0, 1, 2, 3, 4, 5},
new FrameType[] {
FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")),
- FrameType.initialized(options.itemFactory.stringType),
+ FrameType.initialized(options.itemFactory.classType),
FrameType.initialized(options.itemFactory.stringType),
FrameType.initialized(options.itemFactory.createType("[Ljava/lang/String;")),
FrameType.initialized(options.itemFactory.stringBuilderType),
@@ -278,7 +285,7 @@
new int[] {0, 1, 2, 3, 4},
new FrameType[] {
FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")),
- FrameType.initialized(options.itemFactory.stringType),
+ FrameType.initialized(options.itemFactory.classType),
FrameType.initialized(options.itemFactory.stringType),
FrameType.initialized(options.itemFactory.createType("[Ljava/lang/String;")),
FrameType.initialized(options.itemFactory.stringBuilderType)
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java
index 1f16c1b..babb6f7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java
@@ -7,6 +7,7 @@
import static com.android.tools.r8.cf.code.CfStackInstruction.Opcode.Dup;
import static com.android.tools.r8.cf.code.CfStackInstruction.Opcode.Swap;
+import com.android.tools.r8.cf.code.CfConstClass;
import com.android.tools.r8.cf.code.CfConstString;
import com.android.tools.r8.cf.code.CfFieldInstruction;
import com.android.tools.r8.cf.code.CfInstruction;
@@ -50,7 +51,6 @@
import com.android.tools.r8.ir.synthetic.RecordCfCodeProvider.RecordEqualsCfCodeProvider;
import com.android.tools.r8.ir.synthetic.RecordCfCodeProvider.RecordGetFieldsAsObjectsCfCodeProvider;
import com.android.tools.r8.ir.synthetic.SyntheticCfCodeProvider;
-import com.android.tools.r8.naming.dexitembasedstring.ClassNameComputationInfo;
import com.android.tools.r8.synthesis.SyntheticNaming;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableList;
@@ -89,7 +89,7 @@
factory = appView.dexItemFactory();
recordToStringHelperProto =
factory.createProto(
- factory.stringType, factory.objectArrayType, factory.stringType, factory.stringType);
+ factory.stringType, factory.objectArrayType, factory.classType, factory.stringType);
recordHashCodeHelperProto =
factory.createProto(factory.intType, factory.classType, factory.objectArrayType);
}
@@ -252,7 +252,6 @@
return desugarInvokeRecordToString(
recordInvokeDynamic,
localStackAllocator,
- context,
eventConsumer,
methodProcessingContext);
}
@@ -382,21 +381,15 @@
private List<CfInstruction> desugarInvokeRecordToString(
RecordInvokeDynamic recordInvokeDynamic,
LocalStackAllocator localStackAllocator,
- ProgramMethod context,
RecordInstructionDesugaringEventConsumer eventConsumer,
MethodProcessingContext methodProcessingContext) {
- DexString simpleName =
- ClassNameComputationInfo.ClassNameMapping.SIMPLE_NAME.map(
- recordInvokeDynamic.getRecordClass().type.toDescriptorString(),
- context.getHolder(),
- factory);
localStackAllocator.allocateLocalStack(2);
DexMethod getFieldsAsObjects =
getFieldsAsObjectsMethod(recordInvokeDynamic.getRecordClass().type);
assert recordInvokeDynamic.getRecordClass().lookupProgramMethod(getFieldsAsObjects) != null;
ArrayList<CfInstruction> instructions = new ArrayList<>();
instructions.add(new CfInvoke(Opcodes.INVOKESPECIAL, getFieldsAsObjects, false));
- instructions.add(new CfConstString(simpleName));
+ instructions.add(new CfConstClass(recordInvokeDynamic.getRecordClass().type));
instructions.add(new CfConstString(recordInvokeDynamic.getFieldNames()));
ProgramMethod programMethod =
synthesizeRecordHelper(
diff --git a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java
index 4ea7cd7..2446b14 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.desugar.records;
-import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF;
import static com.android.tools.r8.utils.InternalOptions.TestingOptions;
import com.android.tools.r8.R8FullTestBuilder;
@@ -70,11 +69,12 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addKeepRules("-keep class records.EmptyRecordAnnotation { *; }")
+ .addKeepRules("-keepattributes *Annotation*")
+ .addKeepRules("-keep class records.EmptyRecordAnnotation$Empty")
.addKeepMainRule(MAIN_TYPE)
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion);
if (parameters.isCfRuntime()) {
builder
- .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF)
.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
.compile()
.inspect(RecordTestUtils::assertRecordsAreRecords)
@@ -84,8 +84,6 @@
return;
}
builder
- .addKeepRules("-keepattributes *Annotation*")
- .addKeepRules("-keep class records.EmptyRecordAnnotation$Empty")
.addKeepRules("-keep class java.lang.Record")
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT_DEX);
diff --git a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
index effcba3..7a64c3c 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.desugar.records;
-import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF;
import static com.android.tools.r8.utils.InternalOptions.TestingOptions;
import com.android.tools.r8.R8FullTestBuilder;
@@ -23,7 +22,8 @@
private static final String RECORD_NAME = "EmptyRecord";
private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME);
private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
- private static final String EXPECTED_RESULT = StringUtils.lines("Empty[]");
+ private static final String EXPECTED_RESULT_D8 = StringUtils.lines("Empty[]");
+ private static final String EXPECTED_RESULT_R8 = StringUtils.lines("a[]");
private final TestParameters parameters;
@@ -48,7 +48,7 @@
testForJvm()
.addProgramClassFileData(PROGRAM_DATA)
.run(parameters.getRuntime(), MAIN_TYPE)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(EXPECTED_RESULT_D8);
}
testForD8(parameters.getBackend())
.addProgramClassFileData(PROGRAM_DATA)
@@ -56,7 +56,7 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(EXPECTED_RESULT_D8);
}
@Test
@@ -69,14 +69,13 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion);
if (parameters.isCfRuntime()) {
builder
- .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF)
.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
.compile()
.inspect(RecordTestUtils::assertRecordsAreRecords)
.run(parameters.getRuntime(), MAIN_TYPE)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(EXPECTED_RESULT_R8);
return;
}
- builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT);
+ builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT_R8);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
index d4da59e..1c32b27 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.desugar.records;
-import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF;
-
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -69,7 +67,6 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion);
if (parameters.isCfRuntime()) {
builder
- .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF)
.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
.compile()
.inspect(RecordTestUtils::assertRecordsAreRecords)
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
index 2d771cc..9ee21d2 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
@@ -22,7 +22,7 @@
private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
private static final String EXPECTED_RESULT =
StringUtils.lines(
- "Empty[]",
+ "%s[]",
"true",
"true",
"true",
@@ -33,7 +33,10 @@
"true",
"false",
"false",
- "Person[name=Jane Doe, age=42]");
+ "%s[name=Jane Doe, age=42]");
+ private static final String EXPECTED_RESULT_D8 =
+ String.format(EXPECTED_RESULT, "Empty", "Person");
+ private static final String EXPECTED_RESULT_R8 = String.format(EXPECTED_RESULT, "a", "b");
private final TestParameters parameters;
@@ -62,7 +65,7 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(EXPECTED_RESULT_D8);
}
@Test
@@ -81,6 +84,6 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(EXPECTED_RESULT_R8);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
index 1fc2f3e..228275b 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.desugar.records;
-import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF;
-
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -25,7 +23,7 @@
private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
private static final String EXPECTED_RESULT =
StringUtils.lines(
- "Empty[]",
+ "%s[]",
"true",
"true",
"true",
@@ -36,7 +34,10 @@
"true",
"false",
"false",
- "Person[name=Jane Doe, age=42]");
+ "%s[name=Jane Doe, age=42]");
+ private static final String EXPECTED_RESULT_D8 =
+ String.format(EXPECTED_RESULT, "Empty", "Person");
+ private static final String EXPECTED_RESULT_R8 = String.format(EXPECTED_RESULT, "a", "b");
private final TestParameters parameters;
@@ -61,7 +62,7 @@
testForJvm()
.addProgramClassFileData(PROGRAM_DATA)
.run(parameters.getRuntime(), MAIN_TYPE)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(EXPECTED_RESULT_D8);
}
testForD8(parameters.getBackend())
.addProgramClassFileData(PROGRAM_DATA)
@@ -69,7 +70,7 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(EXPECTED_RESULT_D8);
}
@Test
@@ -82,14 +83,13 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion);
if (parameters.isCfRuntime()) {
builder
- .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF)
.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
.compile()
.inspect(RecordTestUtils::assertRecordsAreRecords)
.run(parameters.getRuntime(), MAIN_TYPE)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(EXPECTED_RESULT_R8);
return;
}
- builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT);
+ builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT_R8);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordMethods.java b/src/test/java/com/android/tools/r8/desugar/records/RecordMethods.java
index a1fc48e..a3df3b5 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordMethods.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordMethods.java
@@ -11,13 +11,13 @@
public class RecordMethods {
public static String toString(
- Object[] recordFieldsAsObjects, String simpleName, String fieldNames) {
+ Object[] recordFieldsValues, Class<?> recordClass, String fieldNames) {
// Example: "Person[name=Jane Doe, age=42]"
String[] fieldNamesSplit = fieldNames.isEmpty() ? new String[0] : fieldNames.split(";");
StringBuilder builder = new StringBuilder();
- builder.append(simpleName).append("[");
+ builder.append(recordClass.getSimpleName()).append("[");
for (int i = 0; i < fieldNamesSplit.length; i++) {
- builder.append(fieldNamesSplit[i]).append("=").append(recordFieldsAsObjects[i]);
+ builder.append(fieldNamesSplit[i]).append("=").append(recordFieldsValues[i]);
if (i != fieldNamesSplit.length - 1) {
builder.append(", ");
}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
index 26d259a..82891db 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.desugar.records;
-import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF;
-
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfRuntime;
@@ -61,7 +59,8 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(MAIN_TYPE)
- .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF)
+ .addKeepRules("-keepattributes *")
+ .addKeepRules("-keep class * extends java.lang.Record { private final <fields>; }")
.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
.compile()
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java b/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
index 3f8adcc..7008bfe 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
@@ -40,12 +40,6 @@
return Paths.get(ToolHelper.TESTS_BUILD_DIR, EXAMPLE_FOLDER, RECORD_FOLDER + ".jar");
}
- // TODO(b/197081367): Rediscuss if we want to maintain the toString() method.
- // In R8 Cf to Cf we need to maintain the record component attributes, the class name and fields
- // so the mapping between the record components and fields is valid and the toString() prints
- // the record as specified (including the class name).
- public static final String RECORD_KEEP_RULE_R8_CF_TO_CF =
- "-keepattributes *\n" + "-keep class * extends java.lang.Record { private final <fields>; }";
public static Path[] getJdk15LibraryFiles(TemporaryFolder temp) throws IOException {
Assume.assumeFalse(ToolHelper.isWindows());
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
index f1fc5ae..f22f8cd 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.desugar.records;
-import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF;
-
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -71,7 +69,6 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion);
if (parameters.isCfRuntime()) {
builder
- .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF)
.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
.compile()
.inspect(RecordTestUtils::assertRecordsAreRecords)
diff --git a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
index 68ad95e..d29b7df 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.desugar.records;
-import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF;
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestBase;
@@ -73,7 +72,6 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion);
if (parameters.isCfRuntime()) {
builder
- .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF)
.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
.compile()
.inspect(RecordTestUtils::assertRecordsAreRecords)
@@ -101,7 +99,6 @@
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion);
if (parameters.isCfRuntime()) {
builder
- .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF)
.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
.compile()
.inspect(RecordTestUtils::assertRecordsAreRecords)