Remove mutation of access flags in LambdaDescriptor.
Change-Id: I6ce16cd5d37610a24d49bee748055a1d6bd46f86
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java
index 81f93a7..b283f96 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/AccessorMethodSourceCode.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.ValueType;
@@ -56,13 +55,6 @@
return true;
}
- private boolean isPrivateMethod() {
- // We should be able to find targets for all private impl-methods, so
- // we can rely on knowing accessibility flags for them.
- MethodAccessFlags flags = descriptor().getAccessibility();
- return flags != null && flags.isPrivate();
- }
-
// Are we delegating to a constructor?
private boolean delegatingToConstructor() {
return descriptor().implHandle.type.isInvokeConstructor();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 6bb06d5..e7d2f34 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -25,6 +25,8 @@
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.Invoke.Type;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
@@ -364,11 +366,15 @@
// Lambda$ method. We must always find it.
assert implMethod.holder == accessedFrom;
- assert descriptor.targetFoundInClass(accessedFrom);
- assert descriptor.getAccessibility() != null;
-
+ assert descriptor.verifyTargetFoundInClass(accessedFrom);
if (implHandle.type.isInvokeStatic()) {
- return new StaticLambdaImplTarget();
+ SingleResolutionResult resolution =
+ rewriter.getAppInfo().resolveMethod(implMethod.holder, implMethod).asSingleResolution();
+ assert resolution.getResolvedMethod().isStatic();
+ assert resolution.getResolvedHolder().isProgramClass();
+ return new StaticLambdaImplTarget(
+ new ProgramMethod(
+ resolution.getResolvedHolder().asProgramClass(), resolution.getResolvedMethod()));
}
assert implHandle.type.isInvokeInstance() || implHandle.type.isInvokeDirect();
@@ -575,18 +581,19 @@
// Used for static private lambda$ methods. Only needs access relaxation.
private final class StaticLambdaImplTarget extends Target {
- StaticLambdaImplTarget() {
+ final ProgramMethod target;
+
+ StaticLambdaImplTarget(ProgramMethod target) {
super(descriptor.implHandle.asMethod(), Invoke.Type.STATIC);
+ this.target = target;
}
@Override
DexEncodedMethod ensureAccessibility() {
// We already found the static method to be called, just relax its accessibility.
- assert descriptor.getAccessibility() != null;
- descriptor.getAccessibility().unsetPrivate();
- DexClass implMethodHolder = definitionFor(descriptor.implHandle.asMethod().holder);
- if (implMethodHolder.isInterface()) {
- descriptor.getAccessibility().setPublic();
+ target.method.accessFlags.unsetPrivate();
+ if (target.holder.isInterface()) {
+ target.method.accessFlags.setPublic();
}
return null;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
index 20becfb..ead20ac 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
@@ -44,7 +44,8 @@
final DexTypeList captures;
// Used for accessibility analysis and few assertions only.
- private final DexEncodedMethod targetMethod;
+ private final MethodAccessFlags targetAccessFlags;
+ private final DexType targetHolder;
private LambdaDescriptor() {
uniqueId = null;
@@ -53,7 +54,8 @@
enforcedProto = null;
implHandle = null;
captures = null;
- targetMethod = null;
+ targetAccessFlags = null;
+ targetHolder = null;
}
private LambdaDescriptor(AppInfo appInfo, DexCallSite callSite,
@@ -76,7 +78,15 @@
this.captures = captures;
this.interfaces.add(mainInterface);
- this.targetMethod = lookupTargetMethod(appInfo);
+
+ DexEncodedMethod targetMethod = lookupTargetMethod(appInfo);
+ if (targetMethod != null) {
+ targetAccessFlags = targetMethod.accessFlags.copy();
+ targetHolder = targetMethod.method.holder;
+ } else {
+ targetAccessFlags = null;
+ targetHolder = null;
+ }
}
final DexType getImplReceiverType() {
@@ -143,12 +153,8 @@
return encodedMethod.isPublicized() && isInstanceMethod(encodedMethod);
}
- final MethodAccessFlags getAccessibility() {
- return targetMethod == null ? null : targetMethod.accessFlags;
- }
-
- final boolean targetFoundInClass(DexType type) {
- return targetMethod != null && targetMethod.method.holder == type;
+ public final boolean verifyTargetFoundInClass(DexType type) {
+ return targetHolder == type;
}
/** If the lambda delegates to lambda$ method. */
@@ -177,9 +183,12 @@
boolean instanceTarget = implHandle.type.isInvokeInstance() || implHandle.type.isInvokeDirect();
boolean initTarget = implHandle.type.isInvokeConstructor();
assert instanceTarget || staticTarget || initTarget;
- assert !implHandle.type.isInvokeDirect() || isPrivateInstanceMethod(targetMethod);
+ assert !implHandle.type.isInvokeDirect()
+ || (targetAccessFlags.isPrivate()
+ && !targetAccessFlags.isConstructor()
+ && !targetAccessFlags.isStatic());
- if (targetMethod == null) {
+ if (targetAccessFlags == null) {
// The target cannot be a private method, since otherwise it
// should have been found.
@@ -200,7 +209,7 @@
return true;
}
- MethodAccessFlags flags = targetMethod.accessFlags;
+ MethodAccessFlags flags = targetAccessFlags;
// Private methods always need accessors.
if (flags.isPrivate()) {
@@ -211,8 +220,7 @@
}
boolean accessedFromSamePackage =
- accessedFrom.getPackageDescriptor().equals(
- targetMethod.method.holder.getPackageDescriptor());
+ accessedFrom.getPackageDescriptor().equals(targetHolder.getPackageDescriptor());
assert flags.isProtected() || accessedFromSamePackage;
return flags.isProtected() && !accessedFromSamePackage;
}