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;
   }