Support @CovariantReturnType on abstract methods
Fixes: b/307689296
Change-Id: I3673717c8148fbdb47309964f40b9565c443b1b0
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
index 76a4b02..aa69f8f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
@@ -173,6 +173,7 @@
MethodAccessFlags newAccessFlags = methodDefinition.accessFlags.copy();
newAccessFlags.setBridge();
newAccessFlags.setSynthetic();
+ newAccessFlags.unsetAbstract(); // Synthetic bridge has code, so never abstract.
DexMethod newMethod =
factory.createMethod(methodHolder.getType(), newProto, methodReference.getName());
ForwardMethodBuilder forwardMethodBuilder =
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/Client.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/Client.java
index 0c6bd44..2fb0363 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/annotations/Client.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/Client.java
@@ -9,9 +9,15 @@
A a = new A().method();
A b = new B().method();
A c = new C().method();
+ D d = ((D) new F()).method();
+ D e = ((E) new F()).method();
+ D f = new F().method();
System.out.println("a=" + a.getClass().getSimpleName());
System.out.println("b=" + b.getClass().getSimpleName());
System.out.println("c=" + c.getClass().getSimpleName());
+ System.out.println("d=" + d.getClass().getSimpleName());
+ System.out.println("e=" + e.getClass().getSimpleName());
+ System.out.println("f=" + f.getClass().getSimpleName());
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/CovariantReturnTypeAnnotationTransformerTest.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/CovariantReturnTypeAnnotationTransformerTest.java
index 4d2f87d..7853976 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/annotations/CovariantReturnTypeAnnotationTransformerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/CovariantReturnTypeAnnotationTransformerTest.java
@@ -52,7 +52,10 @@
ToolHelper.getClassAsBytes(Client.class),
ToolHelper.getClassAsBytes(A.class),
ToolHelper.getClassAsBytes(B.class),
- ToolHelper.getClassAsBytes(C.class));
+ ToolHelper.getClassAsBytes(C.class),
+ ToolHelper.getClassAsBytes(D.class),
+ ToolHelper.getClassAsBytes(E.class),
+ ToolHelper.getClassAsBytes(F.class));
// Version 1 does not contain annotations.
checkPresenceOfCovariantAnnotations(input, false);
@@ -68,7 +71,10 @@
com.android.tools.r8.ir.desugar.annotations.version3.ClientDump.dump(),
ToolHelper.getClassAsBytes(A.class),
ToolHelper.getClassAsBytes(B.class),
- ToolHelper.getClassAsBytes(C.class));
+ ToolHelper.getClassAsBytes(C.class),
+ ToolHelper.getClassAsBytes(D.class),
+ ToolHelper.getClassAsBytes(E.class),
+ ToolHelper.getClassAsBytes(F.class));
// Version 1 does not contain annotations.
checkPresenceOfCovariantAnnotations(input, false);
@@ -85,7 +91,10 @@
ToolHelper.getClassAsBytes(Client.class),
ToolHelper.getClassAsBytes(A.class),
com.android.tools.r8.ir.desugar.annotations.version2.BDump.dump(),
- com.android.tools.r8.ir.desugar.annotations.version2.CDump.dump());
+ com.android.tools.r8.ir.desugar.annotations.version2.CDump.dump(),
+ ToolHelper.getClassAsBytes(D.class),
+ com.android.tools.r8.ir.desugar.annotations.version2.EDump.dump(),
+ com.android.tools.r8.ir.desugar.annotations.version2.FDump.dump());
// Version 2 contains annotations.
checkPresenceOfCovariantAnnotations(input, true);
@@ -101,7 +110,10 @@
com.android.tools.r8.ir.desugar.annotations.version3.ClientDump.dump(),
ToolHelper.getClassAsBytes(A.class),
com.android.tools.r8.ir.desugar.annotations.version2.BDump.dump(),
- com.android.tools.r8.ir.desugar.annotations.version2.CDump.dump());
+ com.android.tools.r8.ir.desugar.annotations.version2.CDump.dump(),
+ ToolHelper.getClassAsBytes(D.class),
+ com.android.tools.r8.ir.desugar.annotations.version2.EDump.dump(),
+ com.android.tools.r8.ir.desugar.annotations.version2.FDump.dump());
// Version 2 contains annotations.
checkPresenceOfCovariantAnnotations(input, true);
@@ -122,7 +134,10 @@
com.android.tools.r8.ir.desugar.annotations.version3.ClientDump.dump(),
ToolHelper.getClassAsBytes(A.class),
com.android.tools.r8.ir.desugar.annotations.version3.BDump.dump(),
- com.android.tools.r8.ir.desugar.annotations.version3.CDump.dump());
+ com.android.tools.r8.ir.desugar.annotations.version3.CDump.dump(),
+ ToolHelper.getClassAsBytes(D.class),
+ com.android.tools.r8.ir.desugar.annotations.version3.EDump.dump(),
+ com.android.tools.r8.ir.desugar.annotations.version3.FDump.dump());
// Version 3 does not contain annotations.
checkPresenceOfCovariantAnnotations(input, false);
@@ -138,7 +153,10 @@
ToolHelper.getClassAsBytes(Client.class),
ToolHelper.getClassAsBytes(A.class),
com.android.tools.r8.ir.desugar.annotations.version3.BDump.dump(),
- com.android.tools.r8.ir.desugar.annotations.version3.CDump.dump());
+ com.android.tools.r8.ir.desugar.annotations.version3.CDump.dump(),
+ ToolHelper.getClassAsBytes(D.class),
+ com.android.tools.r8.ir.desugar.annotations.version3.EDump.dump(),
+ com.android.tools.r8.ir.desugar.annotations.version3.FDump.dump());
// Version 3 does not contain annotations.
checkPresenceOfCovariantAnnotations(input, false);
@@ -154,7 +172,10 @@
ToolHelper.getClassAsBytes(Client.class),
ToolHelper.getClassAsBytes(A.class),
com.android.tools.r8.ir.desugar.annotations.version2.BDump.dump(),
- com.android.tools.r8.ir.desugar.annotations.version2.CDump.dump());
+ com.android.tools.r8.ir.desugar.annotations.version2.CDump.dump(),
+ ToolHelper.getClassAsBytes(D.class),
+ com.android.tools.r8.ir.desugar.annotations.version2.EDump.dump(),
+ com.android.tools.r8.ir.desugar.annotations.version2.FDump.dump());
// Version 2 contains annotations.
checkPresenceOfCovariantAnnotations(input, true);
@@ -248,7 +269,7 @@
// Check that the original methods are there, and that they are not synthetic.
MethodSubject methodA =
- clazzB.method(A.class.getCanonicalName(), "method", Collections.emptyList());
+ clazzA.method(A.class.getCanonicalName(), "method", Collections.emptyList());
assertThat(methodA, isPresent());
Assert.assertTrue(!methodA.getMethod().isSyntheticMethod());
@@ -278,9 +299,52 @@
clazzC.method(C.class.getCanonicalName(), "method", Collections.emptyList());
assertThat(methodC3, isPresent());
Assert.assertTrue(methodC3.getMethod().isSyntheticMethod());
+
+ // Get classes D, E, and F.
+ ClassSubject clazzD = inspector.clazz(D.class.getCanonicalName());
+ assertThat(clazzD, isPresent());
+
+ ClassSubject clazzE = inspector.clazz(E.class.getCanonicalName());
+ assertThat(clazzE, isPresent());
+
+ ClassSubject clazzF = inspector.clazz(F.class.getCanonicalName());
+ assertThat(clazzF, isPresent());
+
+ // Check that the original methods are there, and that they are not synthetic.
+ MethodSubject methodD =
+ clazzD.method(D.class.getCanonicalName(), "method", Collections.emptyList());
+ assertThat(methodD, isPresent());
+ Assert.assertTrue(!methodD.getMethod().isSyntheticMethod());
+
+ MethodSubject methodE =
+ clazzE.method(D.class.getCanonicalName(), "method", Collections.emptyList());
+ assertThat(methodE, isPresent());
+ Assert.assertTrue(!methodE.getMethod().isSyntheticMethod());
+
+ MethodSubject methodF =
+ clazzF.method(D.class.getCanonicalName(), "method", Collections.emptyList());
+ assertThat(methodF, isPresent());
+ Assert.assertTrue(!methodF.getMethod().isSyntheticMethod());
+
+ // Check that a synthetic method has been added to class E.
+ MethodSubject methodE2 =
+ clazzE.method(E.class.getCanonicalName(), "method", Collections.emptyList());
+ assertThat(methodE2, isPresent());
+ Assert.assertTrue(methodE2.getMethod().isSyntheticMethod());
+
+ // Check that two synthetic methods have been added to class F.
+ MethodSubject methodF2 =
+ clazzF.method(E.class.getCanonicalName(), "method", Collections.emptyList());
+ assertThat(methodF2, isPresent());
+ Assert.assertTrue(methodF2.getMethod().isSyntheticMethod());
+
+ MethodSubject methodF3 =
+ clazzF.method(F.class.getCanonicalName(), "method", Collections.emptyList());
+ assertThat(methodF3, isPresent());
+ Assert.assertTrue(methodF3.getMethod().isSyntheticMethod());
}
private String getExpectedOutput() {
- return "a=A\nb=B\nc=C\n";
+ return "a=A\nb=B\nc=C\nd=F\ne=F\nf=F\n";
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/D.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/D.java
new file mode 100644
index 0000000..038c59c
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/D.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations;
+
+public abstract class D {
+ public abstract D method();
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/E.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/E.java
new file mode 100644
index 0000000..fc62630
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/E.java
@@ -0,0 +1,10 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations;
+
+public abstract class E extends D {
+ @Override
+ public abstract D method();
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/F.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/F.java
new file mode 100644
index 0000000..b332595
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/F.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations;
+
+public class F extends E {
+ @Override
+ public D method() {
+ return new F();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/E.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/E.java
new file mode 100644
index 0000000..592c1b9
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/E.java
@@ -0,0 +1,14 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations.version2;
+
+import com.android.tools.r8.ir.desugar.annotations.CovariantReturnType;
+import com.android.tools.r8.ir.desugar.annotations.D;
+
+public abstract class E extends D {
+ @CovariantReturnType(returnType = E.class, presentAfter = 25)
+ @Override
+ public abstract D method();
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/EDump.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/EDump.java
new file mode 100644
index 0000000..1717468
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/EDump.java
@@ -0,0 +1,60 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations.version2;
+
+import static com.android.tools.r8.ir.desugar.annotations.CovariantReturnTypeAnnotationTransformerTest.CRT_BINARY_NAME;
+import static com.android.tools.r8.ir.desugar.annotations.CovariantReturnTypeAnnotationTransformerTest.PACKAGE_NAME;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+// Generated by running tools/asmifier.py on build/classes/test/com/android/tools/r8/ir/desugar/
+// annotations/version2/E.class, removing the subpackage "version2" from all class names, and
+// manually changing the name of the CovariantReturnType annotation to
+// "Ldalvik/annotation/codegen/CovariantReturnType;".
+public class EDump implements Opcodes {
+ public static byte[] dump() throws Exception {
+
+ ClassWriter cw = new ClassWriter(0);
+ MethodVisitor mv;
+ AnnotationVisitor av0;
+
+ cw.visit(
+ V1_8,
+ ACC_PUBLIC | ACC_SUPER | ACC_ABSTRACT,
+ PACKAGE_NAME + "/E",
+ null,
+ PACKAGE_NAME + "/D",
+ null);
+
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, PACKAGE_NAME + "/D", "<init>", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ {
+ mv =
+ cw.visitMethod(
+ ACC_PUBLIC | ACC_ABSTRACT, "method", "()L" + PACKAGE_NAME + "/D;", null, null);
+ {
+ av0 = mv.visitAnnotation("L" + CRT_BINARY_NAME + ";", false);
+ av0.visit("returnType", Type.getType("L" + PACKAGE_NAME + "/E;"));
+ av0.visit("presentAfter", new Integer(25));
+ av0.visitEnd();
+ }
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/F.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/F.java
new file mode 100644
index 0000000..a133826
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/F.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations.version2;
+
+import com.android.tools.r8.ir.desugar.annotations.CovariantReturnType;
+import com.android.tools.r8.ir.desugar.annotations.D;
+
+public class F extends E {
+ @CovariantReturnType(returnType = E.class, presentAfter = 25)
+ @CovariantReturnType(returnType = F.class, presentAfter = 28)
+ @Override
+ public D method() {
+ return new F();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/FDump.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/FDump.java
new file mode 100644
index 0000000..266bc46
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version2/FDump.java
@@ -0,0 +1,87 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations.version2;
+
+import static com.android.tools.r8.ir.desugar.annotations.CovariantReturnTypeAnnotationTransformerTest.CRTS_BINARY_NAME;
+import static com.android.tools.r8.ir.desugar.annotations.CovariantReturnTypeAnnotationTransformerTest.CRTS_INNER_NAME;
+import static com.android.tools.r8.ir.desugar.annotations.CovariantReturnTypeAnnotationTransformerTest.CRT_BINARY_NAME;
+import static com.android.tools.r8.ir.desugar.annotations.CovariantReturnTypeAnnotationTransformerTest.PACKAGE_NAME;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+// Generated by running tools/asmifier.py on build/classes/test/com/android/tools/r8/ir/desugar/
+// annotations/version2/F.class, removing the subpackage "version2" from all class names, and
+// manually changing the name of the CovariantReturnType and CovariantReturnTypes annotations to
+// "Ldalvik/annotation/codegen/CovariantReturnType;" and
+// "Ldalvik/annotation/codegen/CovariantReturnType$CovariantReturnTypes;", respectively.
+public class FDump implements Opcodes {
+ public static byte[] dump() throws Exception {
+
+ ClassWriter cw = new ClassWriter(0);
+ MethodVisitor mv;
+ AnnotationVisitor av0;
+
+ cw.visit(V1_8, ACC_PUBLIC | ACC_SUPER, PACKAGE_NAME + "/F", null, PACKAGE_NAME + "/E", null);
+
+ cw.visitInnerClass(
+ CRTS_BINARY_NAME,
+ CRT_BINARY_NAME,
+ CRTS_INNER_NAME,
+ ACC_PUBLIC | ACC_STATIC | ACC_ANNOTATION | ACC_ABSTRACT | ACC_INTERFACE);
+
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, PACKAGE_NAME + "/E", "<init>", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ {
+ mv =
+ cw.visitMethod(
+ ACC_PUBLIC,
+ "method",
+ "()Lcom/android/tools/r8/ir/desugar/annotations/D;",
+ null,
+ null);
+ {
+ av0 = mv.visitAnnotation("L" + CRTS_BINARY_NAME + ";", false);
+ {
+ AnnotationVisitor av1 = av0.visitArray("value");
+ {
+ AnnotationVisitor av2 = av1.visitAnnotation(null, "L" + CRT_BINARY_NAME + ";");
+ av2.visit("returnType", Type.getType("L" + PACKAGE_NAME + "/E;"));
+ av2.visit("presentAfter", new Integer(25));
+ av2.visitEnd();
+ }
+ {
+ AnnotationVisitor av2 = av1.visitAnnotation(null, "L" + CRT_BINARY_NAME + ";");
+ av2.visit("returnType", Type.getType("L" + PACKAGE_NAME + "/F;"));
+ av2.visit("presentAfter", new Integer(28));
+ av2.visitEnd();
+ }
+ av1.visitEnd();
+ }
+ av0.visitEnd();
+ }
+ mv.visitCode();
+ mv.visitTypeInsn(NEW, PACKAGE_NAME + "/F");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, PACKAGE_NAME + "/F", "<init>", "()V", false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(2, 1);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/Client.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/Client.java
index f2feffa..09a8513 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/Client.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/Client.java
@@ -5,15 +5,22 @@
package com.android.tools.r8.ir.desugar.annotations.version3;
import com.android.tools.r8.ir.desugar.annotations.A;
+import com.android.tools.r8.ir.desugar.annotations.D;
public class Client {
public static void main(String[] args) {
A a = new A().method();
B b = new B().method();
C c = new C().method();
+ D d = ((D) new F()).method();
+ E e = ((E) new F()).method();
+ F f = new F().method();
System.out.println("a=" + a.getClass().getSimpleName());
System.out.println("b=" + b.getClass().getSimpleName());
System.out.println("c=" + c.getClass().getSimpleName());
+ System.out.println("d=" + d.getClass().getSimpleName());
+ System.out.println("e=" + e.getClass().getSimpleName());
+ System.out.println("f=" + f.getClass().getSimpleName());
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/ClientDump.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/ClientDump.java
index 5fea864..a509d96 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/ClientDump.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/ClientDump.java
@@ -55,6 +55,24 @@
mv.visitMethodInsn(
INVOKEVIRTUAL, PACKAGE_NAME + "/C", "method", "()L" + PACKAGE_NAME + "/C;", false);
mv.visitVarInsn(ASTORE, 3);
+ mv.visitTypeInsn(NEW, PACKAGE_NAME + "/F");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, PACKAGE_NAME + "/F", "<init>", "()V", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, PACKAGE_NAME + "/D", "method", "()L" + PACKAGE_NAME + "/D;", false);
+ mv.visitVarInsn(ASTORE, 4);
+ mv.visitTypeInsn(NEW, PACKAGE_NAME + "/F");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, PACKAGE_NAME + "/F", "<init>", "()V", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, PACKAGE_NAME + "/E", "method", "()L" + PACKAGE_NAME + "/E;", false);
+ mv.visitVarInsn(ASTORE, 5);
+ mv.visitTypeInsn(NEW, PACKAGE_NAME + "/F");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, PACKAGE_NAME + "/F", "<init>", "()V", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, PACKAGE_NAME + "/F", "method", "()L" + PACKAGE_NAME + "/F;", false);
+ mv.visitVarInsn(ASTORE, 6);
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
mv.visitInsn(DUP);
@@ -133,8 +151,86 @@
INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
mv.visitMethodInsn(
INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
+ mv.visitLdcInsn("d=");
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "java/lang/StringBuilder",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuilder;",
+ false);
+ mv.visitVarInsn(ALOAD, 4);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Class", "getSimpleName", "()Ljava/lang/String;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "java/lang/StringBuilder",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuilder;",
+ false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
+ mv.visitLdcInsn("e=");
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "java/lang/StringBuilder",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuilder;",
+ false);
+ mv.visitVarInsn(ALOAD, 5);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Class", "getSimpleName", "()Ljava/lang/String;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "java/lang/StringBuilder",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuilder;",
+ false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
+ mv.visitLdcInsn("f=");
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "java/lang/StringBuilder",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuilder;",
+ false);
+ mv.visitVarInsn(ALOAD, 6);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Class", "getSimpleName", "()Ljava/lang/String;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "java/lang/StringBuilder",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuilder;",
+ false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
mv.visitInsn(RETURN);
- mv.visitMaxs(3, 4);
+ mv.visitMaxs(3, 7);
mv.visitEnd();
}
cw.visitEnd();
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/E.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/E.java
new file mode 100644
index 0000000..bd48708
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/E.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations.version3;
+
+import com.android.tools.r8.ir.desugar.annotations.D;
+
+public abstract class E extends D {
+ @Override
+ public abstract E method();
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/EDump.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/EDump.java
new file mode 100644
index 0000000..2572ae8
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/EDump.java
@@ -0,0 +1,64 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations.version3;
+
+import static com.android.tools.r8.ir.desugar.annotations.CovariantReturnTypeAnnotationTransformerTest.PACKAGE_NAME;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+// Generated by running tools/asmifier.py on build/classes/test/com/android/tools/r8/ir/desugar/
+// annotations/version3/E.class, and removing the subpackage "version3" from all class names.
+public class EDump implements Opcodes {
+ public static byte[] dump() throws Exception {
+
+ ClassWriter cw = new ClassWriter(0);
+ MethodVisitor mv;
+
+ cw.visit(
+ V1_8,
+ ACC_PUBLIC | ACC_SUPER | ACC_ABSTRACT,
+ "" + PACKAGE_NAME + "/E",
+ null,
+ "" + PACKAGE_NAME + "/D",
+ null);
+
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "" + PACKAGE_NAME + "/D", "<init>", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ {
+ mv =
+ cw.visitMethod(
+ ACC_PUBLIC | ACC_ABSTRACT, "method", "()L" + PACKAGE_NAME + "/E;", null, null);
+ mv.visitEnd();
+ }
+ {
+ mv =
+ cw.visitMethod(
+ ACC_PUBLIC | ACC_BRIDGE | ACC_SYNTHETIC,
+ "method",
+ "()L" + PACKAGE_NAME + "/D;",
+ null,
+ null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, PACKAGE_NAME + "/E", "method", "()L" + PACKAGE_NAME + "/E;", false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/F.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/F.java
new file mode 100644
index 0000000..ec786fb
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/F.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations.version3;
+
+public class F extends E {
+ @Override
+ public F method() {
+ return new F();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/FDump.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/FDump.java
new file mode 100644
index 0000000..01d9d2c
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/version3/FDump.java
@@ -0,0 +1,79 @@
+// Copyright (c) 2023, 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.ir.desugar.annotations.version3;
+
+import static com.android.tools.r8.ir.desugar.annotations.CovariantReturnTypeAnnotationTransformerTest.PACKAGE_NAME;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+// Generated by running tools/asmifier.py on build/classes/test/com/android/tools/r8/ir/desugar/
+// annotations/version3/F.class, and removing the subpackage "version3" from all class names.
+public class FDump implements Opcodes {
+
+ public static byte[] dump() {
+
+ ClassWriter cw = new ClassWriter(0);
+ MethodVisitor mv;
+
+ cw.visit(V1_8, ACC_PUBLIC | ACC_SUPER, PACKAGE_NAME + "/F", null, PACKAGE_NAME + "/E", null);
+
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, PACKAGE_NAME + "/E", "<init>", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "method", "()L" + PACKAGE_NAME + "/F;", null, null);
+ mv.visitCode();
+ mv.visitTypeInsn(NEW, PACKAGE_NAME + "/F");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, PACKAGE_NAME + "/F", "<init>", "()V", false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(2, 1);
+ mv.visitEnd();
+ }
+ {
+ mv =
+ cw.visitMethod(
+ ACC_PUBLIC | ACC_BRIDGE | ACC_SYNTHETIC,
+ "method",
+ "()L" + PACKAGE_NAME + "/E;",
+ null,
+ null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, PACKAGE_NAME + "/F", "method", "()L" + PACKAGE_NAME + "/F;", false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ {
+ mv =
+ cw.visitMethod(
+ ACC_PUBLIC | ACC_BRIDGE | ACC_SYNTHETIC,
+ "method",
+ "()L" + PACKAGE_NAME + "/D;",
+ null,
+ null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, PACKAGE_NAME + "/F", "method", "()L" + PACKAGE_NAME + "/F;", false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+}