Clean-up AppInfo
- Remove deprecated methods and move others down to
AppinfoWithClassHierarchy
Change-Id: I56f4bf81f1172ef9eb56cfc4ffbdc6f4f5a87eee
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfo.java b/src/main/java/com/android/tools/r8/graph/AppInfo.java
index 7acefcd..666bc88 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -256,43 +256,6 @@
return null;
}
- // TODO(b/147578480): RemoveDeprecation Use AppInfoWithClassHierarchy and
- // lookupXX(DexMethod, DexProgramClass). The following 3 methods should either be removed or
- // return null.
-
- /**
- * Lookup static method following the super chain from the holder of {@code method}.
- *
- * <p>This method will resolve the method on the holder of {@code method} and only return a
- * non-null value if the result of resolution was a static, non-abstract method.
- *
- * @param method the method to lookup
- * @return The actual target for {@code method} or {@code null} if none found.
- */
- @Deprecated // TODO(b/147578480): Remove
- public DexEncodedMethod lookupStaticTarget(DexMethod method) {
- assert checkIfObsolete();
- ResolutionResult resolutionResult = resolveMethod(method.holder, method);
- DexEncodedMethod target = resolutionResult.getSingleTarget();
- return target == null || target.isStatic() ? target : null;
- }
-
- /**
- * Lookup direct method following the super chain from the holder of {@code method}.
- *
- * <p>This method will lookup private and constructor methods.
- *
- * @param method the method to lookup
- * @return The actual target for {@code method} or {@code null} if none found.
- */
- @Deprecated // TODO(b/147578480): Remove
- public DexEncodedMethod lookupDirectTarget(DexMethod method) {
- assert checkIfObsolete();
- ResolutionResult resolutionResult = resolveMethod(method.holder, method);
- DexEncodedMethod target = resolutionResult.getSingleTarget();
- return target == null || target.isDirectMethod() ? target : null;
- }
-
/**
* Lookup virtual method starting in type and following the super chain.
*
@@ -448,28 +411,12 @@
}
/**
- * Helper method used for emulated interface resolution (not in JVM specifications). The result
- * may be abstract.
- */
- public ResolutionResult resolveMaximallySpecificMethods(DexClass clazz, DexMethod method) {
- assert !clazz.type.isArrayType();
- if (clazz.isInterface()) {
- // Look for exact method on interface.
- DexEncodedMethod result = clazz.lookupMethod(method);
- if (result != null) {
- return new SingleResolutionResult(clazz, clazz, result);
- }
- }
- return resolveMethodStep3(clazz, method);
- }
-
- /**
* Implements step 3 of <a
* href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.3">Section
* 5.4.3.3 of the JVM Spec</a>. As this is the same for interfaces and classes, we share one
* implementation.
*/
- private ResolutionResult resolveMethodStep3(DexClass clazz, DexMethod method) {
+ ResolutionResult resolveMethodStep3(DexClass clazz, DexMethod method) {
MaximallySpecificMethodsBuilder builder = new MaximallySpecificMethodsBuilder(clazz);
resolveMethodStep3Helper(clazz, method, builder);
return builder.resolve();
@@ -564,32 +511,6 @@
}
/**
- * Lookup instance field starting in type and following the interface and super chain.
- * <p>
- * The result is the field that will be hit at runtime, if such field is known. A result
- * of null indicates that the field is either undefined or not an instance field.
- */
- public DexEncodedField lookupInstanceTarget(DexType type, DexField field) {
- assert checkIfObsolete();
- assert type.isClassType();
- DexEncodedField result = resolveFieldOn(type, field);
- return result == null || result.accessFlags.isStatic() ? null : result;
- }
-
- /**
- * Lookup static field starting in type and following the interface and super chain.
- * <p>
- * The result is the field that will be hit at runtime, if such field is known. A result
- * of null indicates that the field is either undefined or not a static field.
- */
- public DexEncodedField lookupStaticTarget(DexType type, DexField field) {
- assert checkIfObsolete();
- assert type.isClassType();
- DexEncodedField result = resolveFieldOn(type, field);
- return result == null || !result.accessFlags.isStatic() ? null : result;
- }
-
- /**
* Implements resolution of a field descriptor against the holder of the field. See also {@link
* #resolveFieldOn}.
*/
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
index 4344794..96fee36 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.graph;
+import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
import java.util.ArrayDeque;
import java.util.Deque;
@@ -89,6 +90,48 @@
}
/**
+ * Helper method used for emulated interface resolution (not in JVM specifications). The result
+ * may be abstract.
+ */
+ public ResolutionResult resolveMaximallySpecificMethods(DexClass clazz, DexMethod method) {
+ assert !clazz.type.isArrayType();
+ if (clazz.isInterface()) {
+ // Look for exact method on interface.
+ DexEncodedMethod result = clazz.lookupMethod(method);
+ if (result != null) {
+ return new SingleResolutionResult(clazz, clazz, result);
+ }
+ }
+ return resolveMethodStep3(clazz, method);
+ }
+
+ /**
+ * Lookup instance field starting in type and following the interface and super chain.
+ *
+ * <p>The result is the field that will be hit at runtime, if such field is known. A result of
+ * null indicates that the field is either undefined or not an instance field.
+ */
+ public DexEncodedField lookupInstanceTarget(DexType type, DexField field) {
+ assert checkIfObsolete();
+ assert type.isClassType();
+ DexEncodedField result = resolveFieldOn(type, field);
+ return result == null || result.accessFlags.isStatic() ? null : result;
+ }
+
+ /**
+ * Lookup static field starting in type and following the interface and super chain.
+ *
+ * <p>The result is the field that will be hit at runtime, if such field is known. A result of
+ * null indicates that the field is either undefined or not a static field.
+ */
+ public DexEncodedField lookupStaticTarget(DexType type, DexField field) {
+ assert checkIfObsolete();
+ assert type.isClassType();
+ DexEncodedField result = resolveFieldOn(type, field);
+ return result == null || !result.accessFlags.isStatic() ? null : result;
+ }
+
+ /**
* Lookup static method following the super chain from the holder of {@code method}.
*
* <p>This method will resolve the method on the holder of {@code method} and only return a
diff --git a/src/main/java/com/android/tools/r8/graph/ResolutionResult.java b/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
index 7e98588..6f5a1d7 100644
--- a/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
-import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.utils.SetUtils;
import com.google.common.collect.Sets;
import java.util.Collection;
@@ -71,9 +70,6 @@
public abstract DexEncodedMethod lookupInvokeDirectTarget(
DexProgramClass context, AppInfoWithClassHierarchy appInfo);
- @Deprecated
- public abstract DexEncodedMethod lookupInvokeSuperTarget(DexClass context, AppInfo appInfo);
-
/** Lookup the single target of an invoke-static on this resolution result if possible. */
public abstract DexEncodedMethod lookupInvokeStaticTarget(
DexProgramClass context, AppInfoWithClassHierarchy appInfo);
@@ -189,7 +185,7 @@
if (!isAccessibleFrom(context, appInfo)) {
return null;
}
- DexEncodedMethod target = lookupInvokeSuperTarget(context.asDexClass(), appInfo);
+ DexEncodedMethod target = internalInvokeSpecialOrSuper(context, appInfo, (sup, sub) -> true);
if (target == null) {
return null;
}
@@ -244,21 +240,10 @@
return null;
}
- @Override
- public DexEncodedMethod lookupInvokeSuperTarget(DexClass context, AppInfo appInfo) {
- assert context != null;
- if (resolvedMethod.isInstanceInitializer()
- || (appInfo.hasSubtyping()
- && initialResolutionHolder != context
- && !isSuperclass(initialResolutionHolder, context, appInfo.withSubtyping()))) {
- throw new CompilationError(
- "Illegal invoke-super to " + resolvedMethod.toSourceString(), context.getOrigin());
- }
- return internalInvokeSpecialOrSuper(context, appInfo, (sup, sub) -> true);
- }
-
private DexEncodedMethod internalInvokeSpecialOrSuper(
- DexClass context, AppInfo appInfo, BiPredicate<DexClass, DexClass> isSuperclass) {
+ DexClass context,
+ AppInfoWithClassHierarchy appInfo,
+ BiPredicate<DexClass, DexClass> isSuperclass) {
// Statics cannot be targeted by invoke-special/super.
if (getResolvedMethod().isStatic()) {
@@ -455,11 +440,6 @@
}
@Override
- public final DexEncodedMethod lookupInvokeSuperTarget(DexClass context, AppInfo appInfo) {
- return null;
- }
-
- @Override
public DexEncodedMethod lookupInvokeStaticTarget(DexProgramClass context,
AppInfoWithClassHierarchy appInfo) {
return null;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index ea6e851..fe87616 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -1636,6 +1636,8 @@
}
private void initializeRetargetCoreLibraryMembers(AppView<?> appView) {
+ assert appView.appInfo().hasClassHierarchy()
+ : "Class hierarchy required for desugared library.";
Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
for (DexString methodName : retargetCoreLibMember.keySet()) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
index 0204455..2f54714 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.desugar;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexClass;
@@ -174,7 +175,7 @@
}
}
- private final AppView<?> appView;
+ private final AppView<? extends AppInfoWithClassHierarchy> appView;
private final DexItemFactory dexItemFactory;
private final InterfaceMethodRewriter rewriter;
private final Consumer<DexEncodedMethod> newSynthesizedMethodConsumer;
@@ -195,7 +196,7 @@
new IdentityHashMap<>();
ClassProcessor(
- AppView<?> appView,
+ AppView<? extends AppInfoWithClassHierarchy> appView,
InterfaceMethodRewriter rewriter,
Consumer<DexEncodedMethod> newSynthesizedMethodConsumer) {
this.appView = appView;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index ab215b6..09cd2aa 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
@@ -97,7 +98,7 @@
public static final String DEFAULT_METHOD_PREFIX = "$default$";
public static final String PRIVATE_METHOD_PREFIX = "$private$";
- private final AppView<?> appView;
+ private final AppView<? extends AppInfoWithClassHierarchy> appView;
private final IRConverter converter;
private final InternalOptions options;
final DexItemFactory factory;
@@ -132,7 +133,9 @@
public InterfaceMethodRewriter(AppView<?> appView, IRConverter converter) {
assert converter != null;
- this.appView = appView;
+ assert appView.appInfo().hasClassHierarchy()
+ : "Cannot desugar interfaces without class hierarchy";
+ this.appView = appView.withClassHierarchy();
this.converter = converter;
this.options = appView.options();
this.factory = appView.dexItemFactory();
@@ -280,7 +283,6 @@
DexEncodedMethod dexEncodedMethod =
appView
.appInfo()
- .withClassHierarchy()
.lookupSuperTarget(invokeSuper.getInvokedMethod(), code.method.method.holder);
if (dexEncodedMethod != null) {
DexClass dexClass = appView.definitionFor(dexEncodedMethod.method.holder);
diff --git a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
index b38dd21..03c8d70 100644
--- a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
@@ -197,7 +197,7 @@
);
AndroidApp application = buildApplication(builder);
- AppInfo appInfo = computeAppInfo(application);
+ AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
DexItemFactory factory = appInfo.dexItemFactory();
DexField aFieldOnSubClass = factory