Fix the workaround for the ASM workaround for the javac bug.
We can get through the parameter annotations twice for a method.
Once for visible and once for invisible annotations.
R=zerny@google.com
Change-Id: I742b28244dd9cfbf0feedb07a4a875c6e3022ad3
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 3cc3ac4..bca0d14 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -70,11 +70,11 @@
}
private static AnnotationVisitor createAnnotationVisitor(String desc, boolean visible,
- AnnotationVisitor annotationVisitor, List<DexAnnotation> annotations,
+ List<DexAnnotation> annotations,
JarApplicationReader application) {
assert annotations != null;
int visiblity = visible ? DexAnnotation.VISIBILITY_RUNTIME : DexAnnotation.VISIBILITY_BUILD;
- return new CreateAnnotationVisitor(annotationVisitor, application, (names, values) ->
+ return new CreateAnnotationVisitor(application, (names, values) ->
annotations.add(new DexAnnotation(visiblity,
createEncodedAnnotation(desc, names, values, application))));
}
@@ -210,7 +210,7 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible, null, getAnnotations(), application);
+ return createAnnotationVisitor(desc, visible, getAnnotations(), application);
}
@Override
@@ -314,7 +314,7 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible, null, getAnnotations(), parent.application);
+ return createAnnotationVisitor(desc, visible, getAnnotations(), parent.application);
}
@Override
@@ -424,15 +424,12 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible,
- mv == null ? null : mv.visitAnnotation(desc, visible),
- getAnnotations(), parent.application);
+ return createAnnotationVisitor(desc, visible, getAnnotations(), parent.application);
}
@Override
public AnnotationVisitor visitAnnotationDefault() {
- return new CreateAnnotationVisitor(mv == null ? null : mv.visitAnnotationDefault(),
- parent.application, (names, elements) -> {
+ return new CreateAnnotationVisitor(parent.application, (names, elements) -> {
assert elements.size() == 1;
defaultAnnotation = elements.get(0);
});
@@ -455,8 +452,12 @@
// never see this non-existing annotation descriptor. ASM uses the same check to make
// sure to undo their workaround for the javac bug in their MethodWriter.
if (desc.equals("Ljava/lang/Synthetic;")) {
- assert parameterAnnotations == null;
- fakeParameterAnnotations++;
+ // We can iterate through all the parameters twice. Once for visible and once for
+ // invisible parameter annotations. We only record the number of fake parameter
+ // annotations once.
+ if (parameterAnnotations == null) {
+ fakeParameterAnnotations++;
+ }
return null;
}
if (parameterAnnotations == null) {
@@ -466,8 +467,8 @@
parameterAnnotations.add(new ArrayList<>());
}
}
+ assert mv == null;
return createAnnotationVisitor(desc, visible,
- mv == null ? null : mv.visitParameterAnnotation(parameter, desc, visible),
parameterAnnotations.get(parameter - fakeParameterAnnotations), parent.application);
}
@@ -584,10 +585,9 @@
private List<DexString> names = null;
private final List<DexValue> values = new ArrayList<>();
- public CreateAnnotationVisitor(AnnotationVisitor annotationVisitor,
- JarApplicationReader application,
- BiConsumer<List<DexString>, List<DexValue>> onVisitEnd) {
- super(ASM5, annotationVisitor);
+ public CreateAnnotationVisitor(
+ JarApplicationReader application, BiConsumer<List<DexString>, List<DexValue>> onVisitEnd) {
+ super(ASM5);
this.application = application;
this.onVisitEnd = onVisitEnd;
}
@@ -605,14 +605,14 @@
@Override
public AnnotationVisitor visitAnnotation(String name, String desc) {
- return new CreateAnnotationVisitor(av, application, (names, values) ->
+ return new CreateAnnotationVisitor(application, (names, values) ->
addElement(name, new DexValueAnnotation(
createEncodedAnnotation(desc, names, values, application))));
}
@Override
public AnnotationVisitor visitArray(String name) {
- return new CreateAnnotationVisitor(av, application, (names, values) -> {
+ return new CreateAnnotationVisitor(application, (names, values) -> {
assert names == null;
addElement(name, new DexValueArray(values.toArray(new DexValue[values.size()])));
});
diff --git a/src/test/examples/regress_62300145/Regress.java b/src/test/examples/regress_62300145/Regress.java
index 77aa6bd..f151e83 100644
--- a/src/test/examples/regress_62300145/Regress.java
+++ b/src/test/examples/regress_62300145/Regress.java
@@ -3,9 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
package regress_62300145;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
public class Regress {
@@ -13,13 +17,18 @@
public @interface A {
}
+ @Retention(CLASS)
+ @Target({ElementType.PARAMETER})
+ public @interface B {
+ }
+
public class InnerClass {
- public InnerClass(@A String p) {}
+ public InnerClass(@A @B String p1, @A String p2, @B String p3) { }
}
public static void main(String[] args) throws NoSuchMethodException {
- Constructor<InnerClass> constructor =
- InnerClass.class.getDeclaredConstructor(Regress.class, String.class);
+ Constructor<InnerClass> constructor = InnerClass.class.getDeclaredConstructor(
+ Regress.class, String.class, String.class, String.class);
int i = 0;
for (Annotation[] annotations : constructor.getParameterAnnotations()) {
System.out.print(i++ + ": ");