Update handling of @CovariantReturnType
This performs a minor overhaul of the CovariantReturnTypeAnnotationTransformer.
Changes include:
- Limit @CovariantReturnType processing to Android platform builds
- Limit @CovariantReturnType processing to apps that contain or reference CovariantReturnType
- Parallelize DEX conversion of the synthesized bridge methods
- Avoid decoding DexStrings from inside @CovariantReturnType annotations
- Simplify and prepare CovariantReturnTypeAnnotationTransformer for easy adoption in R8
Change-Id: I2692035be1992130e40135a243f38e76536d19c4
diff --git a/src/main/java/com/android/tools/r8/desugar/covariantreturntype/CovariantReturnTypeAnnotationTransformer.java b/src/main/java/com/android/tools/r8/desugar/covariantreturntype/CovariantReturnTypeAnnotationTransformer.java
index cbd23f5..55f4d78 100644
--- a/src/main/java/com/android/tools/r8/desugar/covariantreturntype/CovariantReturnTypeAnnotationTransformer.java
+++ b/src/main/java/com/android/tools/r8/desugar/covariantreturntype/CovariantReturnTypeAnnotationTransformer.java
@@ -7,30 +7,30 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationElement;
-import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedAnnotation;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexProto;
+import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueAnnotation;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.graph.DexValue.DexValueType;
-import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.conversion.MethodConversionOptions;
import com.android.tools.r8.ir.conversion.MethodProcessorEventConsumer;
import com.android.tools.r8.ir.synthetic.ForwardMethodBuilder;
-import com.google.common.base.Predicates;
-import java.util.HashSet;
-import java.util.LinkedList;
+import com.android.tools.r8.utils.ForEachable;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Consumer;
// Responsible for processing the annotations dalvik.annotation.codegen.CovariantReturnType and
// dalvik.annotation.codegen.CovariantReturnType$CovariantReturnTypes.
@@ -54,105 +54,83 @@
// the contained CovariantReturnType annotations.
public final class CovariantReturnTypeAnnotationTransformer {
+ private final AppView<?> appView;
private final IRConverter converter;
- private final MethodProcessorEventConsumer methodProcessorEventConsumer =
- MethodProcessorEventConsumer.empty();
private final DexItemFactory factory;
+ private final CovariantReturnTypeReferences references;
- public CovariantReturnTypeAnnotationTransformer(AppView<?> appView, IRConverter converter) {
+ private CovariantReturnTypeAnnotationTransformer(AppView<?> appView, IRConverter converter) {
+ this.appView = appView;
this.converter = converter;
this.factory = appView.dexItemFactory();
+ this.references = new CovariantReturnTypeReferences(factory);
}
- // TODO(b/270398965): Replace LinkedList.
- @SuppressWarnings("JdkObsolete")
- public void process(
- DexApplication.Builder<?> builder,
- CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
- // List of methods that should be added to the next class.
- List<DexEncodedMethod> methodsWithCovariantReturnTypeAnnotation = new LinkedList<>();
- List<DexEncodedMethod> covariantReturnTypeMethods = new LinkedList<>();
- for (DexProgramClass clazz : builder.getProgramClasses()) {
- // Construct the methods that should be added to clazz.
- buildCovariantReturnTypeMethodsForClass(
- clazz,
- methodsWithCovariantReturnTypeAnnotation,
- covariantReturnTypeMethods,
- eventConsumer);
- if (covariantReturnTypeMethods.isEmpty()) {
- continue;
- }
- updateClass(clazz, methodsWithCovariantReturnTypeAnnotation, covariantReturnTypeMethods);
- // Reset lists for the next class that will have a CovariantReturnType or
- // CovariantReturnType$CovariantReturnTypes annotation.
- methodsWithCovariantReturnTypeAnnotation.clear();
- covariantReturnTypeMethods.clear();
+ public static void runIfNecessary(
+ AppView<?> appView,
+ IRConverter converter,
+ CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer,
+ ExecutorService executorService)
+ throws ExecutionException {
+ if (!appView.options().processCovariantReturnTypeAnnotations) {
+ return;
}
+ assert !appView.options().isDesugaredLibraryCompilation();
+ DexItemFactory factory = appView.dexItemFactory();
+ DexString covariantReturnTypeDescriptor =
+ factory.createString(CovariantReturnTypeReferences.COVARIANT_RETURN_TYPE_DESCRIPTOR);
+ if (factory.lookupType(covariantReturnTypeDescriptor) == null) {
+ return;
+ }
+ new CovariantReturnTypeAnnotationTransformer(appView, converter)
+ .run(eventConsumer, executorService);
}
- private void updateClass(
- DexClass clazz,
- List<DexEncodedMethod> methodsWithCovariantReturnTypeAnnotation,
- List<DexEncodedMethod> covariantReturnTypeMethods) {
- // It is a compilation error if the class already has a method with a signature similar to one
- // of the methods in covariantReturnTypeMethods.
- for (DexEncodedMethod syntheticMethod : covariantReturnTypeMethods) {
- if (hasVirtualMethodWithSignature(clazz, syntheticMethod)) {
- throw new CompilationError(
- String.format(
- "Cannot process CovariantReturnType annotation: Class %s already "
- + "has a method \"%s\"",
- clazz.getType(), syntheticMethod.toSourceString()));
- }
+ private void run(
+ CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer,
+ ExecutorService executorService)
+ throws ExecutionException {
+ List<ProgramMethod> covariantReturnTypeMethods = new ArrayList<>();
+ for (DexProgramClass clazz : appView.appInfo().classes()) {
+ List<ProgramMethod> newCovariantReturnTypeMethods =
+ processClass(clazz, clazz::forEachProgramVirtualMethod, eventConsumer);
+ covariantReturnTypeMethods.addAll(newCovariantReturnTypeMethods);
}
- // Remove the CovariantReturnType annotations.
- for (DexEncodedMethod method : methodsWithCovariantReturnTypeAnnotation) {
- method.setAnnotations(
- method.annotations().keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation)));
- }
- // Add the newly constructed methods to the class.
- clazz.addVirtualMethods(covariantReturnTypeMethods);
+ // Convert methods to DEX.
+ converter.optimizeSynthesizedMethods(
+ covariantReturnTypeMethods,
+ MethodProcessorEventConsumer.empty(),
+ MethodConversionOptions.forD8(appView),
+ executorService);
}
// Processes all the dalvik.annotation.codegen.CovariantReturnType and dalvik.annotation.codegen.
// CovariantReturnTypes annotations in the given DexClass. Adds the newly constructed, synthetic
// methods to the list covariantReturnTypeMethods.
- private void buildCovariantReturnTypeMethodsForClass(
+ private List<ProgramMethod> processClass(
DexProgramClass clazz,
- List<DexEncodedMethod> methodsWithCovariantReturnTypeAnnotation,
- List<DexEncodedMethod> covariantReturnTypeMethods,
+ ForEachable<ProgramMethod> methodsToProcess,
CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
- clazz.forEachProgramVirtualMethod(
- method -> {
- if (methodHasCovariantReturnTypeAnnotation(method.getDefinition())) {
- methodsWithCovariantReturnTypeAnnotation.add(method.getDefinition());
- buildCovariantReturnTypeMethodsForMethod(
- method, covariantReturnTypeMethods, eventConsumer);
- }
- });
- }
-
- private boolean methodHasCovariantReturnTypeAnnotation(DexEncodedMethod method) {
- for (DexAnnotation annotation : method.annotations().annotations) {
- if (isCovariantReturnTypeAnnotation(annotation.annotation)) {
- return true;
- }
- }
- return false;
+ List<ProgramMethod> covariantReturnTypeMethods = new ArrayList<>();
+ methodsToProcess.forEach(
+ method ->
+ processMethod(
+ method,
+ covariantReturnTypeMethod -> {
+ covariantReturnTypeMethods.add(covariantReturnTypeMethod);
+ eventConsumer.acceptCovariantReturnTypeBridgeMethod(
+ covariantReturnTypeMethod, method);
+ }));
+ clazz.getMethodCollection().addVirtualClassMethods(covariantReturnTypeMethods);
+ return covariantReturnTypeMethods;
}
// Processes all the dalvik.annotation.codegen.CovariantReturnType and dalvik.annotation.Co-
// variantReturnTypes annotations on the given method. Adds the newly constructed, synthetic
// methods to the list covariantReturnTypeMethods.
- private void buildCovariantReturnTypeMethodsForMethod(
- ProgramMethod method,
- List<DexEncodedMethod> covariantReturnTypeMethods,
- CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
- assert methodHasCovariantReturnTypeAnnotation(method.getDefinition());
- for (DexType covariantReturnType : getCovariantReturnTypes(method)) {
- DexEncodedMethod covariantReturnTypeMethod =
- buildCovariantReturnTypeMethod(method, covariantReturnType, eventConsumer);
- covariantReturnTypeMethods.add(covariantReturnTypeMethod);
+ private void processMethod(ProgramMethod method, Consumer<ProgramMethod> consumer) {
+ for (DexType covariantReturnType : clearCovariantReturnTypeAnnotations(method)) {
+ consumer.accept(buildCovariantReturnTypeMethod(method, covariantReturnType));
}
}
@@ -161,48 +139,43 @@
// type covariantReturnType.
//
// Note: any "synchronized" or "strictfp" modifier could be dropped safely.
- private DexEncodedMethod buildCovariantReturnTypeMethod(
- ProgramMethod method,
- DexType covariantReturnType,
- CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
- DexProgramClass methodHolder = method.getHolder();
- DexMethod methodReference = method.getReference();
- DexEncodedMethod methodDefinition = method.getDefinition();
- DexProto newProto = factory.createProto(covariantReturnType, methodReference.proto.parameters);
- 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 =
- ForwardMethodBuilder.builder(factory)
- .setNonStaticSource(newMethod)
- .setVirtualTarget(methodReference, methodHolder.isInterface())
- .setCastResult();
- DexEncodedMethod newVirtualMethod =
+ private ProgramMethod buildCovariantReturnTypeMethod(
+ ProgramMethod method, DexType covariantReturnType) {
+ DexMethod covariantReturnTypeMethodReference =
+ method.getReference().withReturnType(covariantReturnType, factory);
+ failIfPresent(method.getHolder(), covariantReturnTypeMethodReference);
+ DexEncodedMethod definition =
DexEncodedMethod.syntheticBuilder()
- .setMethod(newMethod)
- .setAccessFlags(newAccessFlags)
- .setGenericSignature(methodDefinition.getGenericSignature())
- .setAnnotations(
- methodDefinition
- .annotations()
- .keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation)))
- .setParameterAnnotations(
- methodDefinition.parameterAnnotationsList.keepIf(Predicates.alwaysTrue()))
- .setCode(forwardMethodBuilder.buildCf())
- .setApiLevelForDefinition(methodDefinition.getApiLevelForDefinition())
- .setApiLevelForCode(methodDefinition.getApiLevelForCode())
+ .setMethod(covariantReturnTypeMethodReference)
+ .setAccessFlags(
+ method.getAccessFlags().copy().setBridge().setSynthetic().unsetAbstract())
+ .setGenericSignature(method.getDefinition().getGenericSignature())
+ .setAnnotations(method.getAnnotations())
+ .setParameterAnnotations(method.getParameterAnnotations())
+ .setCode(
+ ForwardMethodBuilder.builder(factory)
+ .setNonStaticSource(covariantReturnTypeMethodReference)
+ .setVirtualTarget(method.getReference(), method.getHolder().isInterface())
+ .setCastResult()
+ .buildCf())
+ .setApiLevelForDefinition(method.getDefinition().getApiLevelForDefinition())
+ .setApiLevelForCode(method.getDefinition().getApiLevelForCode())
.build();
- // Optimize to generate DexCode instead of CfCode.
- ProgramMethod programMethod = new ProgramMethod(methodHolder, newVirtualMethod);
- converter.optimizeSynthesizedMethod(
- programMethod,
- methodProcessorEventConsumer,
- MethodConversionOptions.forD8(converter.appView));
- eventConsumer.acceptCovariantReturnTypeBridgeMethod(programMethod, method);
- return newVirtualMethod;
+ return new ProgramMethod(method.getHolder(), definition);
+ }
+
+ private void failIfPresent(DexProgramClass clazz, DexMethod covariantReturnTypeMethodReference) {
+ // It is a compilation error if the class already has a method with a signature similar to one
+ // of the methods in covariantReturnTypeMethods.
+ if (clazz.lookupMethod(covariantReturnTypeMethodReference) != null) {
+ throw appView
+ .reporter()
+ .fatalError(
+ String.format(
+ "Cannot process CovariantReturnType annotation: Class %s already "
+ + "has a method \"%s\"",
+ clazz.getTypeName(), covariantReturnTypeMethodReference.toSourceString()));
+ }
}
// Returns the set of covariant return types for method.
@@ -213,33 +186,36 @@
// @Override
// public Foo foo() { ... return new SubOfSubOfFoo(); }
// then this method returns the set { SubOfFoo, SubOfSubOfFoo }.
- private Set<DexType> getCovariantReturnTypes(ProgramMethod method) {
- Set<DexType> covariantReturnTypes = new HashSet<>();
- for (DexAnnotation annotation : method.getDefinition().annotations().annotations) {
- if (isCovariantReturnTypeAnnotation(annotation.annotation)) {
+ private Set<DexType> clearCovariantReturnTypeAnnotations(ProgramMethod method) {
+ Set<DexType> covariantReturnTypes = new LinkedHashSet<>();
+ for (DexAnnotation annotation : method.getAnnotations().getAnnotations()) {
+ if (references.isOneOfCovariantReturnTypeAnnotations(annotation.getAnnotationType())) {
getCovariantReturnTypesFromAnnotation(
- method.getHolder(),
- method.getDefinition(),
- annotation.annotation,
- covariantReturnTypes);
+ method, annotation.getAnnotation(), covariantReturnTypes);
}
}
+ if (!covariantReturnTypes.isEmpty()) {
+ method
+ .getDefinition()
+ .setAnnotations(
+ method
+ .getAnnotations()
+ .removeIf(
+ annotation ->
+ references.isOneOfCovariantReturnTypeAnnotations(
+ annotation.getAnnotationType())));
+ }
return covariantReturnTypes;
}
- @SuppressWarnings("ReferenceEquality")
private void getCovariantReturnTypesFromAnnotation(
- DexClass clazz,
- DexEncodedMethod method,
- DexEncodedAnnotation annotation,
- Set<DexType> covariantReturnTypes) {
- assert isCovariantReturnTypeAnnotation(annotation);
+ ProgramMethod method, DexEncodedAnnotation annotation, Set<DexType> covariantReturnTypes) {
boolean hasPresentAfterElement = false;
for (DexAnnotationElement element : annotation.elements) {
- String name = element.name.toString();
- if (annotation.type == factory.annotationCovariantReturnType) {
- if (name.equals("returnType")) {
- DexValueType dexValueType = element.value.asDexValueType();
+ DexString name = element.getName();
+ if (references.isCovariantReturnTypeAnnotation(annotation.getType())) {
+ if (name.isIdenticalTo(references.returnTypeName)) {
+ DexValueType dexValueType = element.getValue().asDexValueType();
if (dexValueType == null) {
throw new CompilationError(
String.format(
@@ -247,19 +223,20 @@
+ "reference a type (method: \"%s\", was: %s)",
method.toSourceString(), element.value.getClass().getCanonicalName()));
}
- covariantReturnTypes.add(dexValueType.value);
- } else if (name.equals("presentAfter")) {
+ covariantReturnTypes.add(dexValueType.getValue());
+ } else if (name.isIdenticalTo(references.presentAfterName)) {
hasPresentAfterElement = true;
}
} else {
- if (name.equals("value")) {
- DexValueArray array = element.value.asDexValueArray();
+ assert references.isCovariantReturnTypesAnnotation(annotation.getType());
+ if (name.isIdenticalTo(references.valueName)) {
+ DexValueArray array = element.getValue().asDexValueArray();
if (array == null) {
throw new CompilationError(
String.format(
"Expected element \"value\" of CovariantReturnTypes annotation to "
+ "be an array (method: \"%s\", was: %s)",
- method.toSourceString(), element.value.getClass().getCanonicalName()));
+ method.toSourceString(), element.getValue().getClass().getCanonicalName()));
}
// Handle the inner dalvik.annotation.codegen.CovariantReturnType annotations recursively.
@@ -267,42 +244,19 @@
assert value.isDexValueAnnotation();
DexValueAnnotation innerAnnotation = value.asDexValueAnnotation();
getCovariantReturnTypesFromAnnotation(
- clazz, method, innerAnnotation.value, covariantReturnTypes);
+ method, innerAnnotation.getValue(), covariantReturnTypes);
}
}
}
}
- if (annotation.type == factory.annotationCovariantReturnType && !hasPresentAfterElement) {
+ if (references.isCovariantReturnTypeAnnotation(annotation.getType())
+ && !hasPresentAfterElement) {
throw new CompilationError(
String.format(
"CovariantReturnType annotation for method \"%s\" is missing mandatory element "
+ "\"presentAfter\" (class %s)",
- clazz.getType(), method.toSourceString()));
+ method.toSourceString(), method.getHolder().getType()));
}
}
-
- public boolean isCovariantReturnTypeAnnotation(DexEncodedAnnotation annotation) {
- return isCovariantReturnTypeAnnotation(annotation, factory);
- }
-
- public static boolean isCovariantReturnTypeAnnotation(
- DexEncodedAnnotation annotation, DexItemFactory factory) {
- return isCovariantReturnTypeAnnotation(annotation.type, factory);
- }
-
- @SuppressWarnings("ReferenceEquality")
- public static boolean isCovariantReturnTypeAnnotation(DexType type, DexItemFactory factory) {
- return type == factory.annotationCovariantReturnType
- || type == factory.annotationCovariantReturnTypes;
- }
-
- private static boolean hasVirtualMethodWithSignature(DexClass clazz, DexEncodedMethod method) {
- for (DexEncodedMethod existingMethod : clazz.virtualMethods()) {
- if (existingMethod.getReference().equals(method.getReference())) {
- return true;
- }
- }
- return false;
- }
}
diff --git a/src/main/java/com/android/tools/r8/desugar/covariantreturntype/CovariantReturnTypeReferences.java b/src/main/java/com/android/tools/r8/desugar/covariantreturntype/CovariantReturnTypeReferences.java
new file mode 100644
index 0000000..fa26148
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/desugar/covariantreturntype/CovariantReturnTypeReferences.java
@@ -0,0 +1,42 @@
+// Copyright (c) 2024, 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.covariantreturntype;
+
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
+
+public class CovariantReturnTypeReferences {
+
+ static String COVARIANT_RETURN_TYPE_DESCRIPTOR =
+ "Ldalvik/annotation/codegen/CovariantReturnType;";
+
+ final DexType annotationCovariantReturnType;
+ final DexType annotationCovariantReturnTypes;
+
+ final DexString presentAfterName;
+ final DexString returnTypeName;
+ final DexString valueName;
+
+ CovariantReturnTypeReferences(DexItemFactory factory) {
+ this.annotationCovariantReturnType = factory.createType(COVARIANT_RETURN_TYPE_DESCRIPTOR);
+ this.annotationCovariantReturnTypes =
+ factory.createType("Ldalvik/annotation/codegen/CovariantReturnType$CovariantReturnTypes;");
+ this.presentAfterName = factory.createString("presentAfter");
+ this.returnTypeName = factory.createString("returnType");
+ this.valueName = factory.createString("value");
+ }
+
+ boolean isCovariantReturnTypeAnnotation(DexType type) {
+ return type.isIdenticalTo(annotationCovariantReturnType);
+ }
+
+ boolean isCovariantReturnTypesAnnotation(DexType type) {
+ return type.isIdenticalTo(annotationCovariantReturnTypes);
+ }
+
+ boolean isOneOfCovariantReturnTypeAnnotations(DexType type) {
+ return isCovariantReturnTypeAnnotation(type) || isCovariantReturnTypesAnnotation(type);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/AccessFlags.java b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
index 4151107..58011d6 100644
--- a/src/main/java/com/android/tools/r8/graph/AccessFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
@@ -226,8 +226,9 @@
return isSet(Constants.ACC_SYNTHETIC);
}
- public void setSynthetic() {
+ public T setSynthetic() {
set(Constants.ACC_SYNTHETIC);
+ return self();
}
public T unsetSynthetic() {
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
index be7b2b4..cee4f28 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -5,7 +5,6 @@
import com.android.tools.r8.androidapi.AndroidApiLevelCompute;
import com.android.tools.r8.androidapi.ComputedApiLevel;
-import com.android.tools.r8.desugar.covariantreturntype.CovariantReturnTypeAnnotationTransformer;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.graph.DexValue.DexValueAnnotation;
@@ -79,6 +78,10 @@
this.annotation = annotation;
}
+ public DexEncodedAnnotation getAnnotation() {
+ return annotation;
+ }
+
public boolean isTypeAnnotation() {
return false;
}
@@ -136,22 +139,21 @@
mixedItems.add(this);
}
- @SuppressWarnings("ReferenceEquality")
- public static boolean retainCompileTimeAnnotation(DexType annotation, InternalOptions options) {
+ public static boolean retainCompileTimeAnnotation(
+ DexType annotationType, InternalOptions options) {
if (options.retainCompileTimeAnnotations) {
return true;
}
- if (annotation == options.itemFactory.annotationSynthesizedClass
- || annotation
- .getDescriptor()
- .startsWith(options.itemFactory.dalvikAnnotationOptimizationPrefix)) {
+ DexItemFactory factory = options.itemFactory;
+ if (annotationType.isIdenticalTo(factory.annotationSynthesizedClass)) {
return true;
}
- if (options.processCovariantReturnTypeAnnotations) {
- // @CovariantReturnType annotations are processed by CovariantReturnTypeAnnotationTransformer,
- // they thus need to be read here and will then be removed as part of the processing.
- return CovariantReturnTypeAnnotationTransformer.isCovariantReturnTypeAnnotation(
- annotation, options.itemFactory);
+ DexString descriptor = annotationType.getDescriptor();
+ if (descriptor.startsWith(factory.dalvikAnnotationPrefix)) {
+ if (descriptor.startsWith(factory.dalvikAnnotationCodegenCovariantReturnTypePrefix)) {
+ return options.processCovariantReturnTypeAnnotations;
+ }
+ return descriptor.startsWith(factory.dalvikAnnotationOptimizationPrefix);
}
return false;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java b/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
index 6dab6e8..c76fb95 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
@@ -156,9 +156,17 @@
return getFirstMatching(type) != null;
}
+ public boolean hasAnnotation(Predicate<DexAnnotation> predicate) {
+ return getFirstMatching(predicate) != null;
+ }
+
public DexAnnotation getFirstMatching(DexType type) {
+ return getFirstMatching(annotation -> annotation.getAnnotationType().isIdenticalTo(type));
+ }
+
+ public DexAnnotation getFirstMatching(Predicate<DexAnnotation> predicate) {
for (DexAnnotation annotation : annotations) {
- if (annotation.getAnnotationType().isIdenticalTo(type)) {
+ if (predicate.test(annotation)) {
return annotation;
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexEncodedAnnotation.java
index 143dbe4..884b892 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedAnnotation.java
@@ -41,6 +41,10 @@
return DexEncodedAnnotation::specify;
}
+ public DexType getType() {
+ return type;
+ }
+
public void collectIndexedItems(AppView<?> appView, IndexedItemCollection indexedItems) {
type.collectIndexedItems(appView, indexedItems);
for (DexAnnotationElement element : elements) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 3c056f8..8f6be1b 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -81,8 +81,6 @@
"Lcom/android/tools/r8/DesugarMethodHandlesLookup;";
public static final String methodHandlesLookupDescriptorString =
"Ljava/lang/invoke/MethodHandles$Lookup;";
- public static final String dalvikAnnotationOptimizationPrefixString =
- "Ldalvik/annotation/optimization/";
public static final String androidUtilSparseArrayDescriptorString = "Landroid/util/SparseArray;";
public static final String androidContentResTypedArrayDescriptorString =
"Landroid/content/res/TypedArray;";
@@ -380,8 +378,11 @@
public final DexString apiLevelString = createString("apiLevel");
// Prefix for runtime affecting yet potential class-retained annotations.
+ public final DexString dalvikAnnotationPrefix = createString("Ldalvik/annotation/");
+ public final DexString dalvikAnnotationCodegenCovariantReturnTypePrefix =
+ createString("Ldalvik/annotation/codegen/CovariantReturnType");
public final DexString dalvikAnnotationOptimizationPrefix =
- createString(dalvikAnnotationOptimizationPrefixString);
+ createString("Ldalvik/annotation/optimization/");
// Method names used on VarHandle.
public final DexString getString = createString("get");
@@ -811,11 +812,6 @@
public final DexType annotationThrows = createStaticallyKnownType("Ldalvik/annotation/Throws;");
public final DexType annotationSynthesizedClass =
createStaticallyKnownType("Lcom/android/tools/r8/annotations/SynthesizedClassV2;");
- public final DexType annotationCovariantReturnType =
- createStaticallyKnownType("Ldalvik/annotation/codegen/CovariantReturnType;");
- public final DexType annotationCovariantReturnTypes =
- createStaticallyKnownType(
- "Ldalvik/annotation/codegen/CovariantReturnType$CovariantReturnTypes;");
public final String annotationReachabilitySensitiveDesc =
"Ldalvik/annotation/optimization/ReachabilitySensitive;";
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethod.java b/src/main/java/com/android/tools/r8/graph/DexMethod.java
index ea4be31..4abdb68 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethod.java
@@ -360,4 +360,8 @@
public DexMethod withProto(DexProto proto, DexItemFactory dexItemFactory) {
return dexItemFactory.createMethod(holder, proto, name);
}
+
+ public DexMethod withReturnType(DexType returnType, DexItemFactory dexItemFactory) {
+ return withProto(dexItemFactory.createProto(returnType, getParameters()), dexItemFactory);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 5b0aec4..e890a6a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -755,11 +755,6 @@
methodCollection.addMethod(method);
}
- public void replaceVirtualMethod(
- DexMethod virtualMethod, Function<DexEncodedMethod, DexEncodedMethod> replacement) {
- methodCollection.replaceVirtualMethod(virtualMethod, replacement);
- }
-
public void addExtraInterfaces(List<ClassTypeSignature> extraInterfaces, DexItemFactory factory) {
if (extraInterfaces.isEmpty()) {
return;
diff --git a/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java b/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
index 8ede6f7..742b628 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
@@ -152,8 +152,9 @@
return isSet(Constants.ACC_BRIDGE);
}
- public void setBridge() {
+ public MethodAccessFlags setBridge() {
set(Constants.ACC_BRIDGE);
+ return this;
}
public void unsetBridge() {
@@ -204,8 +205,9 @@
promote(Constants.ACC_ABSTRACT);
}
- public void unsetAbstract() {
+ public MethodAccessFlags unsetAbstract() {
unset(Constants.ACC_ABSTRACT);
+ return this;
}
public boolean isStrict() {
diff --git a/src/main/java/com/android/tools/r8/graph/MethodArrayBacking.java b/src/main/java/com/android/tools/r8/graph/MethodArrayBacking.java
index ab17919..7daef60 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodArrayBacking.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodArrayBacking.java
@@ -184,12 +184,12 @@
}
@Override
- void addVirtualMethods(Collection<DexEncodedMethod> methods) {
+ <T> void addVirtualMethods(Collection<T> methods, Function<? super T, DexEncodedMethod> fn) {
DexEncodedMethod[] newMethods = new DexEncodedMethod[virtualMethods.length + methods.size()];
System.arraycopy(virtualMethods, 0, newMethods, 0, virtualMethods.length);
int i = virtualMethods.length;
- for (DexEncodedMethod method : methods) {
- newMethods[i] = method;
+ for (T method : methods) {
+ newMethods[i] = fn.apply(method);
i++;
}
virtualMethods = newMethods;
diff --git a/src/main/java/com/android/tools/r8/graph/MethodCollection.java b/src/main/java/com/android/tools/r8/graph/MethodCollection.java
index 0f10f5a..17b7e8b 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodCollection.java
@@ -5,6 +5,9 @@
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.TraversalContinuation;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -12,7 +15,6 @@
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
-import java.util.function.Function;
import java.util.function.Predicate;
public class MethodCollection {
@@ -354,9 +356,21 @@
}
public void addVirtualMethods(Collection<DexEncodedMethod> methods) {
- assert verifyCorrectnessOfMethodHolders(methods);
+ internalAddVirtualMethods(methods, Functions.identity());
+ }
+
+ public void addVirtualClassMethods(Collection<? extends DexClassAndMethod> methods) {
+ internalAddVirtualMethods(methods, DexClassAndMethod::getDefinition);
+ }
+
+ private <T> void internalAddVirtualMethods(
+ Collection<T> methods, Function<? super T, DexEncodedMethod> fn) {
+ if (methods.isEmpty()) {
+ return;
+ }
+ assert verifyCorrectnessOfMethodHolders(Iterables.transform(methods, fn));
resetVirtualMethodCaches();
- backing.addVirtualMethods(methods);
+ backing.addVirtualMethods(methods, fn);
}
public void clearVirtualMethods() {
diff --git a/src/main/java/com/android/tools/r8/graph/MethodCollectionBacking.java b/src/main/java/com/android/tools/r8/graph/MethodCollectionBacking.java
index 18a72a3..9de91a2 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodCollectionBacking.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodCollectionBacking.java
@@ -6,6 +6,7 @@
import static com.google.common.base.Predicates.alwaysTrue;
import com.android.tools.r8.utils.TraversalContinuation;
+import com.google.common.base.Functions;
import java.util.Collection;
import java.util.Set;
import java.util.function.Consumer;
@@ -99,7 +100,12 @@
abstract void addDirectMethods(Collection<DexEncodedMethod> methods);
- abstract void addVirtualMethods(Collection<DexEncodedMethod> methods);
+ final void addVirtualMethods(Collection<DexEncodedMethod> methods) {
+ addVirtualMethods(methods, Functions.identity());
+ }
+
+ abstract <T> void addVirtualMethods(
+ Collection<T> methods, Function<? super T, DexEncodedMethod> fn);
// Removal methods.
diff --git a/src/main/java/com/android/tools/r8/graph/MethodCollectionConcurrencyChecked.java b/src/main/java/com/android/tools/r8/graph/MethodCollectionConcurrencyChecked.java
index 78cfebe8..fa3a0a9 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodCollectionConcurrencyChecked.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodCollectionConcurrencyChecked.java
@@ -4,11 +4,11 @@
package com.android.tools.r8.graph;
import com.android.tools.r8.utils.TraversalContinuation;
+import com.google.common.base.Function;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
-import java.util.function.Function;
import java.util.function.Predicate;
public class MethodCollectionConcurrencyChecked extends MethodCollection {
diff --git a/src/main/java/com/android/tools/r8/graph/MethodMapBacking.java b/src/main/java/com/android/tools/r8/graph/MethodMapBacking.java
index fa553d9..f878e46 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodMapBacking.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodMapBacking.java
@@ -198,9 +198,9 @@
}
@Override
- void addVirtualMethods(Collection<DexEncodedMethod> methods) {
- for (DexEncodedMethod method : methods) {
- addVirtualMethod(method);
+ <T> void addVirtualMethods(Collection<T> methods, Function<? super T, DexEncodedMethod> fn) {
+ for (T method : methods) {
+ addVirtualMethod(fn.apply(method));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index acf747a..f5c3538 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.ir.conversion;
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
-import com.android.tools.r8.desugar.covariantreturntype.CovariantReturnTypeAnnotationTransformer;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
@@ -120,7 +119,6 @@
protected final Inliner inliner;
protected final IdentifierNameStringMarker identifierNameStringMarker;
private final Devirtualizer devirtualizer;
- protected final CovariantReturnTypeAnnotationTransformer covariantReturnTypeAnnotationTransformer;
private final TypeChecker typeChecker;
protected EnumUnboxer enumUnboxer;
protected final NumberUnboxer numberUnboxer;
@@ -190,7 +188,6 @@
assert options.desugarState.isOn();
this.instructionDesugaring =
CfInstructionDesugaringCollection.create(appView, appView.apiLevelCompute());
- this.covariantReturnTypeAnnotationTransformer = null;
this.dynamicTypeOptimization = null;
this.classInliner = null;
this.fieldAccessAnalysis = null;
@@ -213,10 +210,6 @@
appView.enableWholeProgramOptimizations()
? CfInstructionDesugaringCollection.empty()
: CfInstructionDesugaringCollection.create(appView, appView.apiLevelCompute());
- this.covariantReturnTypeAnnotationTransformer =
- options.processCovariantReturnTypeAnnotations
- ? new CovariantReturnTypeAnnotationTransformer(appView, this)
- : null;
removeVerificationErrorForUnknownReturnedValues =
(appView.options().apiModelingOptions().enableLibraryApiModeling
&& appView.options().canHaveVerifyErrorForUnknownUnusedReturnValue())
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
index 9ad2b27..93b681a 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
@@ -8,6 +8,7 @@
import static com.android.tools.r8.ir.desugar.lambda.D8LambdaDesugaring.rewriteEnclosingLambdaMethodAttributes;
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
+import com.android.tools.r8.desugar.covariantreturntype.CovariantReturnTypeAnnotationTransformer;
import com.android.tools.r8.desugar.covariantreturntype.CovariantReturnTypeAnnotationTransformerEventConsumer;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppInfo;
@@ -77,6 +78,8 @@
application = commitPendingSyntheticItems(appView, application);
+ processCovariantReturnTypeAnnotations(profileCollectionAdditions, executorService);
+
// Build a new application with jumbo string info,
Builder<?> builder = application.builder();
@@ -85,8 +88,6 @@
new L8InnerOuterAttributeEraser(appView).run();
}
- processCovariantReturnTypeAnnotations(builder, profileCollectionAdditions);
-
timing.end();
application = builder.build();
@@ -272,6 +273,7 @@
appView.appInfo().getMainDexInfo()));
application = appView.appInfo().app();
}
+ assert application == appView.appInfo().app();
return application;
}
@@ -338,14 +340,13 @@
programAdditions.apply(threadingModule, executorService);
}
- @SuppressWarnings("BadImport")
private void processCovariantReturnTypeAnnotations(
- Builder<?> builder, ProfileCollectionAdditions profileCollectionAdditions) {
- if (covariantReturnTypeAnnotationTransformer != null) {
- covariantReturnTypeAnnotationTransformer.process(
- builder,
- CovariantReturnTypeAnnotationTransformerEventConsumer.create(profileCollectionAdditions));
- }
+ ProfileCollectionAdditions profileCollectionAdditions, ExecutorService executorService)
+ throws ExecutionException {
+ CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer =
+ CovariantReturnTypeAnnotationTransformerEventConsumer.create(profileCollectionAdditions);
+ CovariantReturnTypeAnnotationTransformer.runIfNecessary(
+ appView, this, eventConsumer, executorService);
}
Timing rewriteNonDesugaredCode(
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index dac665d..8abdba1 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -372,7 +372,8 @@
if (isAndroidPlatformBuild) {
apiModelingOptions().disableApiModeling();
disableBackportsAndReportIfTriggered = true;
- addAndroidPlatformBuildToMarker = isAndroidPlatformBuild;
+ addAndroidPlatformBuildToMarker = true;
+ processCovariantReturnTypeAnnotations = true;
}
}
@@ -778,7 +779,7 @@
public OffOrAuto tryWithResourcesDesugaring = OffOrAuto.Auto;
// Flag to turn on/off processing of @dalvik.annotation.codegen.CovariantReturnType and
// @dalvik.annotation.codegen.CovariantReturnType$CovariantReturnTypes.
- public boolean processCovariantReturnTypeAnnotations = true;
+ public boolean processCovariantReturnTypeAnnotations = false;
public boolean loadAllClassDefinitions = false;
diff --git a/src/test/java/com/android/tools/r8/androidapi/GenerateCovariantReturnTypeMethodsTest.java b/src/test/java/com/android/tools/r8/androidapi/GenerateCovariantReturnTypeMethodsTest.java
index 3bcbd20..76c0cde 100644
--- a/src/test/java/com/android/tools/r8/androidapi/GenerateCovariantReturnTypeMethodsTest.java
+++ b/src/test/java/com/android/tools/r8/androidapi/GenerateCovariantReturnTypeMethodsTest.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.androidapi;
import static com.android.tools.r8.apimodel.JavaSourceCodePrinter.Type.fromType;
-import static com.android.tools.r8.desugar.covariantreturntype.CovariantReturnTypeAnnotationTransformer.isCovariantReturnTypeAnnotation;
import static com.android.tools.r8.utils.MapUtils.ignoreKey;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -23,7 +22,6 @@
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationElement;
import com.android.tools.r8.graph.DexEncodedAnnotation;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueAnnotation;
import com.android.tools.r8.graph.DexValue.DexValueArray;
@@ -63,6 +61,11 @@
@RunWith(Parameterized.class)
public class GenerateCovariantReturnTypeMethodsTest extends TestBase {
+ private static final String COVARIANT_RETURN_TYPE_ANNOTATION_NAME =
+ "dalvik.annotation.codegen.CovariantReturnType";
+ private static final String COVARIANT_RETURN_TYPES_ANNOTATION_NAME =
+ "dalvik.annotation.codegen.CovariantReturnType$CovariantReturnTypes";
+
private static final String CLASS_NAME = "CovariantReturnTypeMethods";
private static final String PACKAGE_NAME = "com.android.tools.r8.androidapi";
// When updating to support a new api level build libcore in aosp and update the cloud dependency.
@@ -200,20 +203,22 @@
public static CovariantMethodsInJarResult create() throws Exception {
Map<ClassReference, List<MethodReferenceWithApiLevel>> methodReferenceMap = new HashMap<>();
CodeInspector inspector = new CodeInspector(PATH_TO_CORE_JAR);
- DexItemFactory factory = inspector.getFactory();
for (FoundClassSubject clazz : inspector.allClasses()) {
clazz.forAllMethods(
method -> {
List<DexAnnotation> covariantAnnotations =
inspector.findAnnotations(
method.getMethod().annotations(),
- annotation ->
- isCovariantReturnTypeAnnotation(annotation.annotation, factory));
+ annotation -> {
+ String typeName = annotation.getAnnotationType().getTypeName();
+ return typeName.equals(COVARIANT_RETURN_TYPE_ANNOTATION_NAME)
+ || typeName.equals(COVARIANT_RETURN_TYPES_ANNOTATION_NAME);
+ });
if (!covariantAnnotations.isEmpty()) {
MethodReference methodReference = method.asMethodReference();
for (DexAnnotation covariantAnnotation : covariantAnnotations) {
createCovariantMethodReference(
- factory, methodReference, covariantAnnotation.annotation, methodReferenceMap);
+ methodReference, covariantAnnotation.annotation, methodReferenceMap);
}
}
});
@@ -222,19 +227,21 @@
}
private static void createCovariantMethodReference(
- DexItemFactory factory,
MethodReference methodReference,
DexEncodedAnnotation covariantAnnotation,
Map<ClassReference, List<MethodReferenceWithApiLevel>> methodReferenceMap) {
- if (covariantAnnotation.type == factory.annotationCovariantReturnType) {
+ if (covariantAnnotation
+ .getType()
+ .getTypeName()
+ .equals(COVARIANT_RETURN_TYPE_ANNOTATION_NAME)) {
DexAnnotationElement returnTypeElement = covariantAnnotation.getElement(0);
- assert returnTypeElement.name.toString().equals("returnType");
+ assert returnTypeElement.getName().toString().equals("returnType");
DexValueType newReturnType = returnTypeElement.getValue().asDexValueType();
DexAnnotationElement presentAfterElement = covariantAnnotation.getElement(1);
- assert presentAfterElement.name.toString().equals("presentAfter");
+ assert presentAfterElement.getName().toString().equals("presentAfter");
AndroidApiLevel apiLevel =
AndroidApiLevel.getAndroidApiLevel(
- presentAfterElement.getValue().asDexValueInt().value);
+ presentAfterElement.getValue().asDexValueInt().getValue());
methodReferenceMap
.computeIfAbsent(methodReference.getHolderClass(), ignoreKey(ArrayList::new))
.add(
@@ -243,20 +250,23 @@
methodReference.getHolderClass(),
methodReference.getMethodName(),
methodReference.getFormalTypes(),
- newReturnType.value.asClassReference()),
+ newReturnType.getValue().asClassReference()),
apiLevel));
} else {
- assert covariantAnnotation.type == factory.annotationCovariantReturnTypes;
+ assert covariantAnnotation
+ .getType()
+ .getTypeName()
+ .equals(COVARIANT_RETURN_TYPES_ANNOTATION_NAME);
DexAnnotationElement valuesElement = covariantAnnotation.getElement(0);
- assert valuesElement.name.toString().equals("value");
- DexValueArray array = valuesElement.value.asDexValueArray();
+ assertEquals("value", valuesElement.getName().toString());
+ DexValueArray array = valuesElement.getValue().asDexValueArray();
if (array == null) {
fail(
String.format(
"Expected element \"value\" of CovariantReturnTypes annotation to "
+ "be an array (method: \"%s\", was: %s)",
methodReference.toSourceString(),
- valuesElement.value.getClass().getCanonicalName()));
+ valuesElement.getValue().getClass().getCanonicalName()));
}
// Handle the inner dalvik.annotation.codegen.CovariantReturnType annotations recursively.
@@ -264,7 +274,7 @@
assert value.isDexValueAnnotation();
DexValueAnnotation innerAnnotation = value.asDexValueAnnotation();
createCovariantMethodReference(
- factory, methodReference, innerAnnotation.value, methodReferenceMap);
+ methodReference, innerAnnotation.value, methodReferenceMap);
}
}
}
diff --git a/src/test/java/com/android/tools/r8/annotations/DalvikAnnotationOptimizationTest.java b/src/test/java/com/android/tools/r8/annotations/DalvikAnnotationOptimizationTest.java
index f14c979..c6c128f 100644
--- a/src/test/java/com/android/tools/r8/annotations/DalvikAnnotationOptimizationTest.java
+++ b/src/test/java/com/android/tools/r8/annotations/DalvikAnnotationOptimizationTest.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.transformers.MethodTransformer;
import com.android.tools.r8.utils.AndroidApiLevel;
@@ -56,8 +55,7 @@
BooleanUtils.values());
}
- private static final String dalvikOptimizationPrefix =
- DexItemFactory.dalvikAnnotationOptimizationPrefixString;
+ private static final String dalvikOptimizationPrefix = "Ldalvik/annotation/optimization/";
private static final String dalvikCodegenPrefix = "Ldalvik/annotation/codegen/";
private static final String ourClassName =
DescriptorUtils.javaTypeToDescriptor(DalvikAnnotationOptimizationTest.class.getTypeName());