Version 2.1.83

Add applied field to GraphLens(e) to ensure that we are not rewriting
invoke-interface to default methods int their companion class.

The fix is manually added since this issue has been resolved on other
branches.

Bug: 171982443
Bug: 172895918
Bug: 173184123
Change-Id: I6b0cbe3e4e8715dc38d615e5a5e89e3a7fcf9f7d
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index d2b632d..2b1533f 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "2.1.82";
+  public static final String LABEL = "2.1.83";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index a277a71..91e03c8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -402,6 +402,15 @@
     }
 
     @Override
+    public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
+      DexMethod previousContext =
+          originalMethodSignatures != null
+              ? originalMethodSignatures.getOrDefault(context, context)
+              : context;
+      return previousLense.lookupMethod(method, previousContext, type);
+    }
+
+    @Override
     protected Type mapInvocationType(DexMethod newMethod, DexMethod originalMethod, Type type) {
       return Type.STATIC;
     }
diff --git a/src/test/java/com/android/tools/r8/desugar/b171982443/Caller.java b/src/test/java/com/android/tools/r8/desugar/b171982443/Caller.java
new file mode 100644
index 0000000..741cd6d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/b171982443/Caller.java
@@ -0,0 +1,118 @@
+// Copyright (c) 2020, 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.b171982443;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.desugar.b171982443.DefaultMethodInvokeReprocessingTest.I;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+public class Caller implements Opcodes {
+
+  @NeverInline
+  public static void callI(I i) {
+    // We will inline the kotlin function that has kotlin style lambdas. That will trigger
+    // the LambdaMerger and force it to reprocess this method again. That is a problem if we
+    // have desugared I.print() to a default method, since the mapping will be applied for the
+    // i.print() call below
+    i.print();
+    // Since the test cannot reference kotlin code during compilation, we insert the call
+    // manually.
+    // SimpleKt.tBirdTaker();
+  }
+
+  public static byte[] dump() {
+
+    ClassWriter classWriter = new ClassWriter(0);
+    MethodVisitor methodVisitor;
+    AnnotationVisitor annotationVisitor0;
+
+    classWriter.visit(
+        V1_8,
+        ACC_PUBLIC | ACC_SUPER,
+        "com/android/tools/r8/desugar/b171982443/Caller",
+        null,
+        "java/lang/Object",
+        null);
+    classWriter.visitSource("Caller.java", null);
+    classWriter.visitInnerClass(
+        "com/android/tools/r8/desugar/b171982443/DefaultMethodInvokeReprocessingTest$I",
+        "com/android/tools/r8/desugar/b171982443/DefaultMethodInvokeReprocessingTest",
+        "I",
+        ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
+
+    {
+      methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(10, label0);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      methodVisitor.visitInsn(RETURN);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitLocalVariable(
+          "this", "Lcom/android/tools/r8/desugar/b171982443/Caller;", null, label0, label1, 0);
+      methodVisitor.visitMaxs(1, 1);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor =
+          classWriter.visitMethod(
+              ACC_PUBLIC | ACC_STATIC,
+              "callI",
+              "(Lcom/android/tools/r8/desugar/b171982443/DefaultMethodInvokeReprocessingTest$I;)V",
+              null,
+              null);
+      {
+        annotationVisitor0 =
+            methodVisitor.visitAnnotation("Lcom/android/tools/r8/NeverInline;", false);
+        annotationVisitor0.visitEnd();
+      }
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(19, label0);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(
+          INVOKEINTERFACE,
+          "com/android/tools/r8/desugar/b171982443/DefaultMethodInvokeReprocessingTest$I",
+          "print",
+          "()V",
+          true);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitLineNumber(22, label1);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/desugar/b171982443/SimpleKt",
+          "tBirdTaker",
+          "()V",
+          false);
+      Label label2 = new Label();
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(23, label2);
+      methodVisitor.visitInsn(RETURN);
+      Label label3 = new Label();
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLocalVariable(
+          "i",
+          "Lcom/android/tools/r8/desugar/b171982443/DefaultMethodInvokeReprocessingTest$I;",
+          null,
+          label0,
+          label3,
+          0);
+      methodVisitor.visitMaxs(1, 1);
+      methodVisitor.visitEnd();
+    }
+    classWriter.visitEnd();
+
+    return classWriter.toByteArray();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/b171982443/DefaultMethodInvokeReprocessingTest.java b/src/test/java/com/android/tools/r8/desugar/b171982443/DefaultMethodInvokeReprocessingTest.java
new file mode 100644
index 0000000..5c2f0d3
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/b171982443/DefaultMethodInvokeReprocessingTest.java
@@ -0,0 +1,114 @@
+// Copyright (c) 2020, 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.b171982443;
+
+import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
+import static com.android.tools.r8.desugar.b171982443.Caller.callI;
+import static org.hamcrest.CoreMatchers.equalTo;
+
+import com.android.tools.r8.KotlinTestBase;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.utils.DescriptorUtils;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+// This is a reproduction of b/171982443.
+@RunWith(Parameterized.class)
+public class DefaultMethodInvokeReprocessingTest extends KotlinTestBase {
+
+  private static final String PKG =
+      DefaultMethodInvokeReprocessingTest.class.getPackage().getName();
+  private static final String PKG_PREFIX = DescriptorUtils.getBinaryNameFromJavaType(PKG);
+  private static final String[] EXPECTED = new String[] {"A::foo", "Hello1", "Hello2", "Hello3"};
+  private final TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDexRuntimes().withAllApiLevels().build(),
+        KotlinTargetVersion.values());
+  }
+
+  public DefaultMethodInvokeReprocessingTest(
+      TestParameters parameters, KotlinTargetVersion targetVersion) {
+    super(targetVersion);
+    this.parameters = parameters;
+  }
+
+  private static final Map<KotlinTargetVersion, Path> libJarMap = new HashMap<>();
+
+  @BeforeClass
+  public static void createLibJar() throws Exception {
+    for (KotlinTargetVersion kotlinTargetVersion : KotlinTargetVersion.values()) {
+      libJarMap.put(
+          kotlinTargetVersion,
+          kotlinc(KOTLINC, kotlinTargetVersion)
+              .addSourceFiles(getKotlinFileInTest(PKG_PREFIX, "Simple"))
+              .compile());
+    }
+  }
+
+  @Test
+  public void testRuntime() throws Exception {
+    testForRuntime(parameters)
+        .addInnerClasses(DefaultMethodInvokeReprocessingTest.class)
+        .addProgramClassFileData(Caller.dump())
+        .addProgramFiles(ToolHelper.getKotlinStdlibJar())
+        .addProgramFiles(libJarMap.get(targetVersion))
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines(EXPECTED);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(DefaultMethodInvokeReprocessingTest.class)
+        .addProgramFiles(libJarMap.get(targetVersion))
+        .addProgramFiles(ToolHelper.getKotlinStdlibJar())
+        .addProgramClassFileData(Caller.dump())
+        .setMinApi(parameters.getApiLevel())
+        .addKeepMainRule(Main.class)
+        .addKeepClassAndMembersRules(I.class)
+        .enableInliningAnnotations()
+        .allowDiagnosticWarningMessages()
+        .compile()
+        .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines(EXPECTED);
+  }
+
+  public interface I {
+
+    default void print() {
+      System.out.println("I::foo");
+    }
+  }
+
+  public static class A implements I {
+
+    @Override
+    @NeverInline
+    public void print() {
+      System.out.println("A::foo");
+    }
+  }
+
+  public static class Main {
+
+    public static void main(String[] args) {
+      callI(args.length == 0 ? new A() : new I() {});
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/b171982443/Simple.kt b/src/test/java/com/android/tools/r8/desugar/b171982443/Simple.kt
new file mode 100644
index 0000000..c0df2d4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/b171982443/Simple.kt
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, 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.b171982443
+
+fun runSimple(cb: () -> Unit) {
+  cb()
+}
+
+fun tBirdTaker() {
+  runSimple { println("Hello1")}
+  runSimple { println("Hello2")}
+  runSimple { println("Hello3")}
+}
\ No newline at end of file