Revert "Support CONSTANT_Dynamic in interface default methods (part 1)"
This reverts commit 7cbc40263192a47927707085f4a9076ab69cb423.
Change-Id: Icb60b1fd090386866bd6a5e6ec2f1b27a095cd82
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicClass.java b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicClass.java
index 6bd38bb..e9fa936 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicClass.java
@@ -54,7 +54,6 @@
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.desugar.FreshLocalProvider;
import com.android.tools.r8.ir.desugar.LocalStackAllocator;
-import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations;
import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations.MethodSynthesizerConsumer;
import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations.UtilityMethodForCodeOptimizations;
@@ -86,9 +85,8 @@
public final DexField constantValueField;
private final DexMethod getConstMethod;
private final Behaviour behaviour;
- private DexMethod bootstrapMethodReference;
+ private DexEncodedMethod bootstrapMethodImpl;
private DexMethod finalBootstrapMethodReference;
- private boolean isFinalBootstrapMethodReferenceOnInterface;
// Considered final but is set after due to circularity in allocation.
private DexProgramClass clazz = null;
@@ -117,7 +115,7 @@
factory.createString("get"));
DexMethodHandle bootstrapMethodHandle = reference.getBootstrapMethod();
- bootstrapMethodReference = bootstrapMethodHandle.asMethod();
+ DexMethod bootstrapMethodReference = bootstrapMethodHandle.asMethod();
MethodResolutionResult resolution =
appView
.appInfoForDesugaring()
@@ -125,34 +123,22 @@
if (resolution.isSingleResolution()
&& resolution.asSingleResolution().getResolvedMethod().isStatic()) {
SingleResolutionResult result = resolution.asSingleResolution();
- if (bootstrapMethodHandle.isInterface
- && appView.options().isInterfaceMethodDesugaringEnabled()) {
- bootstrapMethodReference =
- bootstrapMethodReference.withHolder(
- InterfaceDesugaringSyntheticHelper.getCompanionClassType(
- bootstrapMethodReference.getHolderType(), factory),
- factory);
- isFinalBootstrapMethodReferenceOnInterface = false;
- } else {
- assert bootstrapMethodReference.getHolderType() == resolution.getResolvedHolder().getType();
- isFinalBootstrapMethodReferenceOnInterface = bootstrapMethodHandle.isInterface;
- }
+ bootstrapMethodImpl = result.getResolvedMethod();
if (shouldRewriteBootstrapMethodSignature()) {
// The bootstrap method will have its signature modified to have type Object as its first
// argument.
this.finalBootstrapMethodReference =
factory.createMethod(
- bootstrapMethodReference.getHolderType(),
+ result.getResolvedHolder().getType(),
factory.createProto(
bootstrapMethodReference.getReturnType(),
factory.objectType,
factory.stringType,
factory.classType),
- bootstrapMethodReference.getName());
+ bootstrapMethodImpl.getName());
} else {
this.finalBootstrapMethodReference = bootstrapMethodReference;
// Ensure that the bootstrap method is accessible from the generated class.
- DexEncodedMethod bootstrapMethodImpl = result.getResolvedMethod();
MethodAccessFlags flags = bootstrapMethodImpl.getAccessFlags();
flags.unsetPrivate();
flags.setPublic();
@@ -267,11 +253,7 @@
instructions.add(new CfConstNull());
instructions.add(new CfConstString(reference.getName()));
instructions.add(new CfConstClass(reference.getType()));
- instructions.add(
- new CfInvoke(
- INVOKESTATIC,
- finalBootstrapMethodReference,
- isFinalBootstrapMethodReferenceOnInterface));
+ instructions.add(new CfInvoke(INVOKESTATIC, finalBootstrapMethodReference, false));
instructions.add(new CfCheckCast(reference.getType()));
}
@@ -374,12 +356,12 @@
return;
}
DexProgramClass bootstrapMethodHolder =
- appView.definitionFor(bootstrapMethodReference.getHolderType()).asProgramClass();
+ appView.definitionFor(bootstrapMethodImpl.getHolderType()).asProgramClass();
DexEncodedMethod replacement =
bootstrapMethodHolder
.getMethodCollection()
.replaceDirectMethod(
- bootstrapMethodReference,
+ bootstrapMethodImpl.getReference(),
encodedMethod -> {
MethodAccessFlags newAccessFlags = encodedMethod.accessFlags.copy();
// Ensure that the bootstrap method is accessible from the generated class.
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
index 8db4171..9ee3606 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
@@ -156,7 +156,7 @@
}
// Gets the companion class for the interface `type`.
- public static DexType getCompanionClassType(DexType type, DexItemFactory factory) {
+ static DexType getCompanionClassType(DexType type, DexItemFactory factory) {
assert type.isClassType();
String descriptor = type.descriptor.toString();
String ccTypeDescriptor = getCompanionClassDescriptor(descriptor);
diff --git a/src/test/java/com/android/tools/r8/TestBuilder.java b/src/test/java/com/android/tools/r8/TestBuilder.java
index 63eeb87..656955e 100644
--- a/src/test/java/com/android/tools/r8/TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestBuilder.java
@@ -61,23 +61,6 @@
return self;
}
- public T applyIf(
- boolean value,
- ThrowableConsumer<T> trueConsumer,
- boolean value2,
- ThrowableConsumer<T> trueConsumer2,
- ThrowableConsumer<T> falseConsumer) {
- T self = self();
- if (value) {
- trueConsumer.acceptWithRuntimeException(self);
- } else if (value2) {
- trueConsumer2.acceptWithRuntimeException(self);
- } else {
- falseConsumer.acceptWithRuntimeException(self);
- }
- return self;
- }
-
@Deprecated
public RR run(String mainClass)
throws CompilationFailedException, ExecutionException, IOException {
diff --git a/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicInDefaultInterfaceMethodTest.java b/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicInDefaultInterfaceMethodTest.java
deleted file mode 100644
index a09ae6a..0000000
--- a/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicInDefaultInterfaceMethodTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.desugar.constantdynamic;
-
-import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assume.assumeTrue;
-
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.DesugarTestConfiguration;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.cf.CfVersion;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.StringUtils;
-import java.lang.invoke.MethodHandles;
-import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class ConstantDynamicInDefaultInterfaceMethodTest extends TestBase {
-
- @Parameter() public TestParameters parameters;
-
- @Parameters(name = "{0}")
- public static List<Object[]> data() {
- return buildParameters(
- getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build());
- }
-
- private static final String EXPECTED_OUTPUT = StringUtils.lines("true", "true");
- private static final Class<?> MAIN_CLASS = A.class;
-
- @Test
- public void testReference() throws Exception {
- assumeTrue(parameters.isCfRuntime());
- assumeTrue(parameters.getRuntime().asCf().isNewerThanOrEqual(CfVm.JDK11));
- assumeTrue(parameters.getApiLevel().isEqualTo(AndroidApiLevel.B));
-
- testForJvm()
- .addProgramClasses(MAIN_CLASS)
- .addProgramClassFileData(getTransformedClasses())
- .run(parameters.getRuntime(), MAIN_CLASS)
- .assertSuccessWithOutput(EXPECTED_OUTPUT);
- }
-
- @Test
- public void testDesugaring() throws Exception {
- testForDesugaring(parameters)
- .addProgramClasses(MAIN_CLASS)
- .addProgramClassFileData(getTransformedClasses())
- .run(parameters.getRuntime(), MAIN_CLASS)
- .applyIf(
- // When not desugaring the CF code requires JDK 11.
- DesugarTestConfiguration::isNotDesugared,
- r -> {
- if (parameters.isCfRuntime()
- && parameters.getRuntime().asCf().isNewerThanOrEqual(CfVm.JDK11)) {
- r.assertSuccessWithOutput(EXPECTED_OUTPUT);
- } else {
- r.assertFailureWithErrorThatThrows(UnsupportedClassVersionError.class);
- }
- })
- .applyIf(
- DesugarTestConfiguration::isDesugared, r -> r.assertSuccessWithOutput(EXPECTED_OUTPUT));
- }
-
- @Test
- public void testR8() throws Exception {
- assumeTrue(parameters.isDexRuntime() || parameters.getApiLevel().isEqualTo(AndroidApiLevel.B));
-
- testForR8(parameters.getBackend())
- .addProgramClasses(MAIN_CLASS)
- .addProgramClassFileData(getTransformedClasses())
- .setMinApi(parameters.getApiLevel())
- .addKeepMainRule(MAIN_CLASS)
- // TODO(b/198142613): There should not be a warnings on class references which are
- // desugared away.
- .applyIf(
- parameters.getApiLevel().isLessThan(AndroidApiLevel.O),
- b -> b.addDontWarn("java.lang.invoke.MethodHandles$Lookup"))
- // TODO(b/198142625): Support CONSTANT_Dynamic output for class files.
- .applyIf(
- parameters.isCfRuntime(),
- b -> {
- assertThrows(
- CompilationFailedException.class,
- () ->
- b.compileWithExpectedDiagnostics(
- diagnostics -> {
- diagnostics.assertOnlyErrors();
- diagnostics.assertErrorsMatch(
- diagnosticMessage(
- containsString(
- "Unsupported dynamic constant (not desugaring)")));
- }));
- },
- // TODO(b/210485236): This should not fail for R8.
- !parameters.canUseDefaultAndStaticInterfaceMethodsWhenDesugaring(),
- b ->
- b.run(parameters.getRuntime(), MAIN_CLASS)
- .assertFailureWithErrorThatThrows(NoSuchMethodError.class),
- b ->
- b.run(parameters.getRuntime(), MAIN_CLASS)
- .assertSuccessWithOutput(EXPECTED_OUTPUT));
- }
-
- private byte[] getTransformedClasses() throws Exception {
- return transformer(I.class)
- .setVersion(CfVersion.V11)
- .transformConstStringToConstantDynamic(
- "condy1", I.class, "myConstant", "constantName", Object.class)
- .transformConstStringToConstantDynamic(
- "condy2", I.class, "myConstant", "constantName", Object.class)
- .setPrivate(
- I.class.getDeclaredMethod(
- "myConstant", MethodHandles.Lookup.class, String.class, Class.class))
- .transform();
- }
-
- public interface I {
-
- default Object f() {
- return "condy1"; // Will be transformed to Constant_DYNAMIC.
- }
-
- default Object g() {
- return "condy2"; // Will be transformed to Constant_DYNAMIC.
- }
-
- /* private */ static Object myConstant(
- MethodHandles.Lookup lookup, String name, Class<?> type) {
- return new Object();
- }
- }
-
- public static class A implements I {
- public static void main(String[] args) {
- A a = new A();
- System.out.println(a.f() != null);
- System.out.println(a.f() == a.g());
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/constantdynamic/JacocoConstantDynamicTest.java b/src/test/java/com/android/tools/r8/desugar/constantdynamic/JacocoConstantDynamicTest.java
index 46261e5..9c33f50 100644
--- a/src/test/java/com/android/tools/r8/desugar/constantdynamic/JacocoConstantDynamicTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/constantdynamic/JacocoConstantDynamicTest.java
@@ -16,7 +16,6 @@
import com.android.tools.r8.jacoco.JacocoClasses;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
-import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -51,7 +50,7 @@
public JacocoClasses testClasses;
private static final String MAIN_CLASS = TestRunner.class.getTypeName();
- private static final String EXPECTED_OUTPUT = StringUtils.lines("Hello, world!", "Hello from I!");
+ private static final String EXPECTED_OUTPUT = StringUtils.lines("Hello, world!");
@BeforeClass
public static void setUpInput() throws IOException {
@@ -86,7 +85,7 @@
.run(parameters.getRuntime(), MAIN_CLASS)
.assertSuccessWithOutput(EXPECTED_OUTPUT);
List<String> onTheFlyReport = testClasses.generateReport(agentOutputOnTheFly);
- assertEquals(3, onTheFlyReport.size());
+ assertEquals(2, onTheFlyReport.size());
// Run the instrumented code.
Path agentOutputOffline = output.resolve("offline");
@@ -115,7 +114,7 @@
// TODO(sgjesse): Need to figure out why there is no instrumentation output for newer VMs.
if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
List<String> report = testClasses.generateReport(agentOutput);
- assertEquals(3, report.size());
+ assertEquals(2, report.size());
} else {
assertFalse(Files.exists(agentOutput));
}
@@ -131,23 +130,16 @@
private static JacocoClasses testClasses(TemporaryFolder temp, CfVersion version)
throws IOException {
return new JacocoClasses(
- ImmutableList.of(
- transformer(TestRunner.class).setVersion(version).transform(),
- transformer(I.class).setVersion(version).transform()),
+ transformer(TestRunner.class)
+ .setVersion(version) /*.setClassDescriptor("LTestRunner;")*/
+ .transform(),
temp);
}
- interface I {
- default void m() {
- System.out.println("Hello from I!");
- }
- }
-
- static class TestRunner implements I {
+ static class TestRunner {
public static void main(String[] args) {
System.out.println("Hello, world!");
- new TestRunner().m();
}
}
}
diff --git a/src/test/java/com/android/tools/r8/jacoco/JacocoClasses.java b/src/test/java/com/android/tools/r8/jacoco/JacocoClasses.java
index dd2700f..b98cc63 100644
--- a/src/test/java/com/android/tools/r8/jacoco/JacocoClasses.java
+++ b/src/test/java/com/android/tools/r8/jacoco/JacocoClasses.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.utils.ZipUtils;
-import com.google.common.collect.ImmutableList;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@@ -29,29 +28,22 @@
private final Path originalJar;
private final Path instrumentedJar;
- // Create JacocoClasses with just one class provided as class file bytes.
+ // Create JacocoClasses with just one class provided as bytes.
public JacocoClasses(byte[] clazz, TemporaryFolder temp) throws IOException {
- this(ImmutableList.of(clazz), temp);
- }
-
- // Create JacocoClasses with multiple classes provided as class file bytes.
- public JacocoClasses(List<byte[]> classes, TemporaryFolder temp) throws IOException {
this.temp = temp;
dir = temp.newFolder().toPath();
// Write the class to a .class file with package sub-directories.
+ String typeName = TestBase.extractClassName(clazz);
+ int lastDotIndex = typeName.lastIndexOf('.');
+ String pkg = typeName.substring(0, lastDotIndex);
+ String baseFileName = typeName.substring(lastDotIndex + 1) + CLASS_EXTENSION;
Path original = dir.resolve("original");
- for (byte[] clazz : classes) {
- String typeName = TestBase.extractClassName(clazz);
- int lastDotIndex = typeName.lastIndexOf('.');
- String pkg = typeName.substring(0, lastDotIndex);
- String baseFileName = typeName.substring(lastDotIndex + 1) + CLASS_EXTENSION;
- Files.createDirectories(original);
- Path packageDir = original.resolve(pkg.replace(JAVA_PACKAGE_SEPARATOR, File.separatorChar));
- Files.createDirectories(packageDir);
- Path classFile = packageDir.resolve(baseFileName);
- Files.write(classFile, clazz);
- }
+ Files.createDirectories(original);
+ Path packageDir = original.resolve(pkg.replace(JAVA_PACKAGE_SEPARATOR, File.separatorChar));
+ Files.createDirectories(packageDir);
+ Path classFile = packageDir.resolve(baseFileName);
+ Files.write(classFile, clazz);
// Run offline instrumentation.
Path instrumented = dir.resolve("instrumented");
diff --git a/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java b/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
index d9d0a54..a38f6f2 100644
--- a/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
+++ b/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
@@ -976,7 +976,7 @@
DescriptorUtils.getClassBinaryName(bootstrapMethodHolder),
bootstrapMethodName,
bootstrapMethodSignature,
- bootstrapMethodHolder.isInterface()),
+ false),
new Object[] {}));
} else {
super.visitLdcInsn(value);