Add tests for reflected use of class-bound in formal type parameter
Change-Id: I798487e8ec7676362c2fc45bf43e8d2ad1f89c7c
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/FormalTypeParameterClassBoundPruneTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/FormalTypeParameterClassBoundPruneTest.java
new file mode 100644
index 0000000..c6d21b8
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/graph/genericsignature/FormalTypeParameterClassBoundPruneTest.java
@@ -0,0 +1,88 @@
+// Copyright (c) 2020, 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.graph.genericsignature;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.DescriptorUtils;
+import java.lang.reflect.TypeVariable;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class FormalTypeParameterClassBoundPruneTest extends TestBase {
+
+ private final TestParameters parameters;
+ private final String INTERFACE_BOUND =
+ "L" + DescriptorUtils.getBinaryNameFromJavaType(Interface.class.getTypeName()) + "<TT;>;";
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
+ }
+
+ public FormalTypeParameterClassBoundPruneTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testRuntimeWithNoPrunedSuperType() throws Exception {
+ testForRuntime(parameters)
+ .addProgramClassFileData(
+ transformer(Main.class).removeInnerClasses().transform(),
+ transformer(Super.class).removeInnerClasses().transform(),
+ transformer(Interface.class).removeInnerClasses().transform())
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(
+ Super.class.getTypeName() + "<T>", Interface.class.getTypeName() + "<T>");
+ }
+
+ @Test
+ public void testRuntimeWithPrunedSuperType() throws Exception {
+ testForRuntime(parameters)
+ .addProgramClassFileData(
+ transformer(Main.class)
+ .removeInnerClasses()
+ .setGenericSignature("<T::" + INTERFACE_BOUND + ">Ljava/lang/Object;")
+ .transform(),
+ transformer(Super.class).removeInnerClasses().transform(),
+ transformer(Interface.class).removeInnerClasses().transform())
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(Interface.class.getTypeName() + "<T>");
+ }
+
+ @Test
+ public void testRuntimeWithObjectSuperType() throws Exception {
+ testForRuntime(parameters)
+ .addProgramClassFileData(
+ transformer(Main.class)
+ .removeInnerClasses()
+ .setGenericSignature(
+ "<T:Ljava/lang/Object;:" + INTERFACE_BOUND + ">Ljava/lang/Object;")
+ .transform(),
+ transformer(Super.class).removeInnerClasses().transform(),
+ transformer(Interface.class).removeInnerClasses().transform())
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(
+ "class java.lang.Object", Interface.class.getTypeName() + "<T>");
+ }
+
+ public static class Super<T> {}
+
+ public interface Interface<T> {}
+
+ public static class Main<T extends Super<T> & Interface<T>> {
+
+ public static void main(String[] args) {
+ TypeVariable<Class<Main>> typeParameter = Main.class.getTypeParameters()[0];
+ for (java.lang.reflect.Type bound : typeParameter.getBounds()) {
+ System.out.println(bound.toString());
+ }
+ }
+ }
+}
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 d9f3b1d..269c6c2 100644
--- a/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
+++ b/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
@@ -306,6 +306,22 @@
});
}
+ public ClassFileTransformer setGenericSignature(String newGenericSignature) {
+ return addClassTransformer(
+ new ClassTransformer() {
+ @Override
+ public void visit(
+ int version,
+ int access,
+ String name,
+ String signature,
+ String superName,
+ String[] interfaces) {
+ super.visit(version, access, name, newGenericSignature, superName, interfaces);
+ }
+ });
+ }
+
public ClassFileTransformer setNest(Class<?> host, Class<?>... members) {
assert !Arrays.asList(members).contains(host);
return setMinVersion(CfVm.JDK11)