Restore MultiplexAnnotationVisitor for creating annotations on companion class
- Rationale: Keep annotation attributes copied.
- Addressing post-submit comments of https://github.com/bazelbuild/bazel/commit/c89c11c881f28a2792da377d4d8aece940f70f34
PiperOrigin-RevId: 251703322
diff --git a/src/test/java/com/google/devtools/build/android/desugar/DesugarDefaultMethodsFunctionalTest.java b/src/test/java/com/google/devtools/build/android/desugar/DesugarDefaultMethodsFunctionalTest.java
index c90afe9..703b814 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/DesugarDefaultMethodsFunctionalTest.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/DesugarDefaultMethodsFunctionalTest.java
@@ -98,8 +98,11 @@
List<Annotation> annotations = Arrays.asList(method.getAnnotations());
- assertThat(Iterables.getOnlyElement(annotations))
- .isInstanceOf(InterfaceMethodWithParam.Foo.class);
+ Annotation parameterAnnotation = Iterables.getOnlyElement(annotations);
+ assertThat(parameterAnnotation).isInstanceOf(InterfaceMethodWithParam.Foo.class);
+
+ InterfaceMethodWithParam.Foo fooInstance = (InterfaceMethodWithParam.Foo) parameterAnnotation;
+ assertThat(fooInstance.value()).isEqualTo("custom-attr-value-2");
}
@Test
@@ -144,7 +147,7 @@
}
@Test
- public void methodAnnotationsArePreservedOnStaticMethodCompanions() throws Exception {
+ public void methodParameterAnnotationsArePreservedOnStaticMethodCompanions() throws Exception {
Method method = InterfaceMethodWithParam.MethodInvocations.inspectCompanionOfStaticMethod();
Annotation[] parameterAnnotations = method.getAnnotations();
assertThat(parameterAnnotations).hasLength(1);
@@ -201,8 +204,11 @@
InterfaceMethodWithParam.MethodInvocations.inspectCompanionMethodOfDefaultMethod();
List<Annotation> annotations = Arrays.asList(method.getAnnotations());
- assertThat(Iterables.getOnlyElement(annotations))
- .isInstanceOf(InterfaceMethodWithParam.Foo.class);
+ Annotation methodAnnotation = Iterables.getOnlyElement(annotations);
+ assertThat(methodAnnotation).isInstanceOf(InterfaceMethodWithParam.Foo.class);
+
+ InterfaceMethodWithParam.Foo fooInstance = (InterfaceMethodWithParam.Foo) methodAnnotation;
+ assertThat(fooInstance.value()).isEqualTo("custom-attr-value-2");
}
@Test
diff --git a/src/test/java/com/google/devtools/build/android/desugar/testdata/java8/InterfaceMethodWithParam.java b/src/test/java/com/google/devtools/build/android/desugar/testdata/java8/InterfaceMethodWithParam.java
index 2b263e6..a5c111f 100644
--- a/src/test/java/com/google/devtools/build/android/desugar/testdata/java8/InterfaceMethodWithParam.java
+++ b/src/test/java/com/google/devtools/build/android/desugar/testdata/java8/InterfaceMethodWithParam.java
@@ -14,7 +14,9 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD})
- @interface Foo {}
+ @interface Foo {
+ String value() default "default-attr";
+ }
/** For testing the annotations on the parameters of interface static and default methods */
@Documented
@@ -35,7 +37,7 @@
* the name is available at run-time. The name is from $ echo "desugar-static" | sha1sum
* @return The reflection representation of the method itself.
*/
- @Foo
+ @Foo("custom-attr-value-1")
@TyFoo
static Method inspectCompanionMethodOfStaticMethod(
@Foo @TyFoo String v4897b02fddeda3bb31bc15b3cad0f6febc61508) throws Exception {
@@ -48,7 +50,7 @@
* the name is available at run-time. The name is from $ echo "desugar-default" | sha1sum
* @return The reflection representation of the method itself.
*/
- @Foo
+ @Foo("custom-attr-value-2")
@TyFoo
default Method inspectCompanionMethodOfDefaultMethod(
@Foo @TyFoo String v12525d61e4b10b3e27bc280dd61e56728e3e8c27) throws Exception {
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java b/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
index 686d9c2..f78c6d9 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
@@ -601,10 +601,9 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- // Copies method annotation attributes into the companion class of a default method.
- // TODO(b/132700453): Looking into whether to propagate method annotations.
- super.visitAnnotation(desc, visible);
- return annotationOnlyDest.visitAnnotation(desc, visible);
+ AnnotationVisitor dest = super.visitAnnotation(desc, visible);
+ AnnotationVisitor annoDest = annotationOnlyDest.visitAnnotation(desc, visible);
+ return new MultiplexAnnotationVisitor(dest, annoDest);
}
@Override
@@ -624,4 +623,63 @@
return annotationOnlyDest.visitParameterAnnotation(parameter, desc, visible);
}
}
+
+ /**
+ * Annotation visitor that recursively passes the visited annotations to any number of given
+ * {@link AnnotationVisitor}s.
+ */
+ private static class MultiplexAnnotationVisitor extends AnnotationVisitor {
+
+ private final AnnotationVisitor[] moreDestinations;
+
+ public MultiplexAnnotationVisitor(
+ @Nullable AnnotationVisitor dest, AnnotationVisitor... moreDestinations) {
+ super(Opcodes.ASM7, dest);
+ this.moreDestinations = moreDestinations;
+ }
+
+ @Override
+ public void visit(String name, Object value) {
+ super.visit(name, value);
+ for (AnnotationVisitor dest : moreDestinations) {
+ dest.visit(name, value);
+ }
+ }
+
+ @Override
+ public void visitEnum(String name, String desc, String value) {
+ super.visitEnum(name, desc, value);
+ for (AnnotationVisitor dest : moreDestinations) {
+ dest.visitEnum(name, desc, value);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String name, String desc) {
+ AnnotationVisitor[] subVisitors = new AnnotationVisitor[moreDestinations.length];
+ AnnotationVisitor dest = super.visitAnnotation(name, desc);
+ for (int i = 0; i < subVisitors.length; ++i) {
+ subVisitors[i] = moreDestinations[i].visitAnnotation(name, desc);
+ }
+ return new MultiplexAnnotationVisitor(dest, subVisitors);
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(String name) {
+ AnnotationVisitor[] subVisitors = new AnnotationVisitor[moreDestinations.length];
+ AnnotationVisitor dest = super.visitArray(name);
+ for (int i = 0; i < subVisitors.length; ++i) {
+ subVisitors[i] = moreDestinations[i].visitArray(name);
+ }
+ return new MultiplexAnnotationVisitor(dest, subVisitors);
+ }
+
+ @Override
+ public void visitEnd() {
+ super.visitEnd();
+ for (AnnotationVisitor dest : moreDestinations) {
+ dest.visitEnd();
+ }
+ }
+ }
}