Revert "Record desugar dependencies for interface bridge methods."

This reverts commit b2a9ac6433f10bd1790f1c8a093140bc4d38bd8a.

Reason for revert: broke it all

Change-Id: I606af35669f893668442498aa10279593abfc79d
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 86b2cb8..b9542eb 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -9,7 +9,6 @@
 import com.android.tools.r8.graph.ResolutionResult.IncompatibleClassResult;
 import com.android.tools.r8.graph.ResolutionResult.NoSuchMethodResult;
 import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
-import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.InternalOptions;
@@ -145,18 +144,6 @@
     return app.definitionFor(type);
   }
 
-  public DexClass definitionForDesugarDependency(DexClass dependent, DexType type) {
-    if (dependent.type == type) {
-      return dependent;
-    }
-    DexClass definition = definitionFor(type);
-    if (definition != null && !definition.isLibraryClass() && dependent.isProgramClass()) {
-      InterfaceMethodRewriter.reportDependencyEdge(
-          dependent.asProgramClass(), definition, options());
-    }
-    return definition;
-  }
-
   @Override
   public DexProgramClass definitionForProgramType(DexType type) {
     return app.programDefinitionFor(type);
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 b54bcc9..6fb1c27 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
@@ -140,6 +140,14 @@
               : closestProgramSubClass);
     }
 
+    public void reportDependency(DexClass clazz, AppView<?> appView) {
+      // If the direct subclass is in the compilation unit, report its dependencies.
+      if (clazz != directSubClass && directSubClass.isProgramClass()) {
+        InterfaceMethodRewriter.reportDependencyEdge(
+            directSubClass.asProgramClass(), clazz, appView);
+      }
+    }
+
     public void reportMissingType(DexType missingType, InterfaceMethodRewriter rewriter) {
       rewriter.warnMissingInterface(closestProgramSubClass, closestProgramSubClass, missingType);
     }
@@ -160,6 +168,11 @@
     }
 
     @Override
+    public void reportDependency(DexClass clazz, AppView<?> appView) {
+      // Don't report dependencies in the library.
+    }
+
+    @Override
     public void reportMissingType(DexType missingType, InterfaceMethodRewriter rewriter) {
       // Ignore missing types in the library.
     }
@@ -388,7 +401,7 @@
     if (type == null || type == dexItemFactory.objectType) {
       return null;
     }
-    DexClass clazz = appView.appInfo().definitionForDesugarDependency(context.directSubClass, type);
+    DexClass clazz = appView.definitionFor(type);
     if (clazz == null) {
       context.reportMissingType(type, rewriter);
       return null;
@@ -406,6 +419,7 @@
     if (clazz.isLibraryClass()) {
       return ClassInfo.EMPTY;
     }
+    context.reportDependency(clazz, appView);
     return classInfo.computeIfAbsent(clazz, key -> visitClassInfoRaw(key, context));
   }
 
@@ -456,6 +470,7 @@
     if (iface.isLibraryClass() && ignoreLibraryInfo()) {
       return MethodSignatures.EMPTY;
     }
+    context.reportDependency(iface, appView);
     return interfaceInfo.computeIfAbsent(iface, key -> visitInterfaceInfoRaw(key, context));
   }
 
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 7f4c043..795755e 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
@@ -961,7 +961,7 @@
     InterfaceProcessor processor = new InterfaceProcessor(appView, this);
     for (DexProgramClass clazz : builder.getProgramClasses()) {
       if (shouldProcess(clazz, flavour, true)) {
-        processor.process(clazz, graphLensBuilder);
+        processor.process(clazz.asProgramClass(), graphLensBuilder);
       }
     }
     for (Entry<DexLibraryClass, Set<DexProgramClass>> entry : requiredDispatchClasses.entrySet()) {
@@ -1114,8 +1114,8 @@
 
     // At this point we likely have a non-library type that may depend on default method information
     // from its interfaces and the dependency should be reported.
-    if (implementing.isProgramClass() && !definedInterface.isLibraryClass()) {
-      reportDependencyEdge(implementing.asProgramClass(), definedInterface, appView.options());
+    if (!definedInterface.isLibraryClass()) {
+      reportDependencyEdge(implementing, definedInterface, appView);
     }
 
     // Merge information from all superinterfaces.
@@ -1139,9 +1139,8 @@
   }
 
   public static void reportDependencyEdge(
-      DexProgramClass dependent, DexClass dependency, InternalOptions options) {
-    assert !dependency.isLibraryClass();
-    DesugarGraphConsumer consumer = options.desugarGraphConsumer;
+      DexClass dependent, DexClass dependency, AppView<?> appView) {
+    DesugarGraphConsumer consumer = appView.options().desugarGraphConsumer;
     if (consumer != null) {
       Origin dependentOrigin = dependent.getOrigin();
       Origin dependencyOrigin = dependency.getOrigin();
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 9599834..787fbe1 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
@@ -34,7 +34,6 @@
 import com.android.tools.r8.ir.synthetic.ForwardMethodSourceCode;
 import com.android.tools.r8.ir.synthetic.SynthesizedCode;
 import com.android.tools.r8.origin.SynthesizedOrigin;
-import com.android.tools.r8.utils.Pair;
 import com.google.common.collect.BiMap;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -303,12 +302,6 @@
     return true;
   }
 
-  private DexClass definitionForDependency(DexType dependency, DexClass dependent) {
-    return dependent.isProgramClass()
-        ? appView.appInfo().definitionForDesugarDependency(dependent.asProgramClass(), dependency)
-        : appView.definitionFor(dependency);
-  }
-
   // Returns true if the given interface method must be kept on [iface] after moving its
   // implementation to the companion class of [iface]. This is always the case for non-bridge
   // methods. Bridge methods that does not override an implementation in a super-interface must
@@ -320,33 +313,32 @@
       }
     }
     if (method.accessFlags.isBridge()) {
-      Deque<Pair<DexClass, DexType>> worklist = new ArrayDeque<>();
+      Deque<DexType> worklist = new ArrayDeque<>();
       Set<DexType> seenBefore = new HashSet<>();
-      addSuperTypes(iface, worklist);
+      if (iface.superType != null) {
+        worklist.add(iface.superType);
+      }
+      Collections.addAll(worklist, iface.interfaces.values);
       while (!worklist.isEmpty()) {
-        Pair<DexClass, DexType> item = worklist.pop();
-        DexClass clazz = definitionForDependency(item.getSecond(), item.getFirst());
-        if (clazz == null || !seenBefore.add(clazz.type)) {
+        DexType superType = worklist.pop();
+        if (!seenBefore.add(superType)) {
           continue;
         }
-        if (clazz.lookupVirtualMethod(method.method) != null) {
-          return false;
+        DexClass clazz = appView.definitionFor(superType);
+        if (clazz != null) {
+          if (clazz.lookupVirtualMethod(method.method) != null) {
+            return false;
+          }
+          if (clazz.superType != null) {
+            worklist.add(clazz.superType);
+          }
+          Collections.addAll(worklist, clazz.interfaces.values);
         }
-        addSuperTypes(clazz, worklist);
       }
     }
     return true;
   }
 
-  private static void addSuperTypes(DexClass clazz, Deque<Pair<DexClass, DexType>> worklist) {
-    if (clazz.superType != null) {
-      worklist.add(new Pair<>(clazz, clazz.superType));
-    }
-    for (DexType iface : clazz.interfaces.values) {
-      worklist.add(new Pair<>(clazz, iface));
-    }
-  }
-
   private boolean isStaticMethod(DexEncodedMethod method) {
     if (method.accessFlags.isNative()) {
       throw new Unimplemented("Native interface methods are not yet supported.");
diff --git a/src/test/java/com/android/tools/r8/desugar/graph/DesugarGraphTestConsumer.java b/src/test/java/com/android/tools/r8/desugar/graph/DesugarGraphTestConsumer.java
deleted file mode 100644
index 2111b7d..0000000
--- a/src/test/java/com/android/tools/r8/desugar/graph/DesugarGraphTestConsumer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2019, 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.graph;
-
-import com.android.tools.r8.DesugarGraphConsumer;
-import com.android.tools.r8.origin.Origin;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public class DesugarGraphTestConsumer implements DesugarGraphConsumer {
-
-  private Map<Origin, Set<Origin>> edges = new HashMap<>();
-
-  public boolean contains(Origin dependency, Origin dependent) {
-    return edges.getOrDefault(dependency, Collections.emptySet()).contains(dependent);
-  }
-
-  public int totalEdgeCount() {
-    int count = 0;
-    for (Set<Origin> dependents : edges.values()) {
-      count += dependents.size();
-    }
-    return count;
-  }
-
-  @Override
-  public synchronized void accept(Origin dependent, Origin dependency) {
-    edges.computeIfAbsent(dependency, s -> new HashSet<>()).add(dependent);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/graph/DesugarGraphUtils.java b/src/test/java/com/android/tools/r8/desugar/graph/DesugarGraphUtils.java
deleted file mode 100644
index af3c6a0..0000000
--- a/src/test/java/com/android/tools/r8/desugar/graph/DesugarGraphUtils.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2019, 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.graph;
-
-import com.android.tools.r8.D8TestBuilder;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.origin.Origin;
-import java.io.IOException;
-
-public class DesugarGraphUtils {
-
-  public static Origin addClassWithOrigin(Class<?> clazz, D8TestBuilder builder)
-      throws IOException {
-    Origin origin = makeOrigin(clazz.getTypeName());
-    builder.getBuilder().addClassProgramData(ToolHelper.getClassAsBytes(clazz), origin);
-    return origin;
-  }
-
-  private static Origin makeOrigin(String name) {
-    return new Origin(Origin.root()) {
-      @Override
-      public String part() {
-        return name;
-      }
-    };
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/graph/InterfaceBridgeDependencyTest.java b/src/test/java/com/android/tools/r8/desugar/graph/InterfaceBridgeDependencyTest.java
deleted file mode 100644
index ec8fcd4..0000000
--- a/src/test/java/com/android/tools/r8/desugar/graph/InterfaceBridgeDependencyTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2019, 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.graph;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.D8TestBuilder;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.StringUtils;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class InterfaceBridgeDependencyTest extends TestBase {
-
-  public interface I {
-    Object foo();
-  }
-
-  public interface J extends I {
-    // Covariant override of foo will result in a synthetic bridge method and J will depend on I.
-    default String foo() {
-      return "J::foo";
-    }
-  }
-
-  public interface K extends I {
-    // A simple override does not cause a bridge and there is no desugar dependencies for K.
-    default Object foo() {
-      return "K::foo";
-    }
-  }
-
-  public static class TestClass {
-
-    public static void main(String[] args) {
-      // There are no instances of I, J or K, so just make sure that the code requires they exist.
-      System.out.println(I.class.getName());
-      System.out.println(J.class.getName());
-      System.out.println(K.class.getName());
-    }
-  }
-
-  // Test runner follows.
-
-  private static final String EXPECTED =
-      StringUtils.lines(I.class.getName(), J.class.getName(), K.class.getName());
-
-  @Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withAllRuntimes().withAllApiLevels().build();
-  }
-
-  private final TestParameters parameters;
-
-  public InterfaceBridgeDependencyTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  @Test
-  public void test() throws Exception {
-    if (parameters.isCfRuntime()) {
-      testForJvm()
-          .addProgramClasses(I.class, J.class, K.class, TestClass.class)
-          .run(parameters.getRuntime(), TestClass.class)
-          .assertSuccessWithOutput(EXPECTED);
-    } else {
-      D8TestBuilder builder = testForD8();
-      DesugarGraphTestConsumer consumer = new DesugarGraphTestConsumer();
-      builder.getBuilder().setDesugarGraphConsumer(consumer);
-      Origin originI = DesugarGraphUtils.addClassWithOrigin(I.class, builder);
-      Origin originJ = DesugarGraphUtils.addClassWithOrigin(J.class, builder);
-      Origin originK = DesugarGraphUtils.addClassWithOrigin(K.class, builder);
-      builder
-          .setMinApi(parameters.getApiLevel())
-          .addProgramClasses(TestClass.class)
-          .run(parameters.getRuntime(), TestClass.class)
-          .assertSuccessWithOutput(EXPECTED);
-      // If API level indicates desugaring is needed check the edges are reported.
-      if (parameters.getApiLevel().getLevel() < AndroidApiLevel.N.getLevel()) {
-        assertTrue(consumer.contains(originI, originJ));
-        assertFalse(consumer.contains(originI, originK));
-        assertEquals(1, consumer.totalEdgeCount());
-      } else {
-        assertEquals(0, consumer.totalEdgeCount());
-      }
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/graph/InterfaceToImplementingClassDependencyTest.java b/src/test/java/com/android/tools/r8/desugar/graph/InterfaceToImplementingClassDependencyTest.java
index 7f76cad..64044e6 100644
--- a/src/test/java/com/android/tools/r8/desugar/graph/InterfaceToImplementingClassDependencyTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/graph/InterfaceToImplementingClassDependencyTest.java
@@ -4,14 +4,18 @@
 package com.android.tools.r8.desugar.graph;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 
-import com.android.tools.r8.D8TestBuilder;
+import com.android.tools.r8.DesugarGraphConsumer;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -22,7 +26,7 @@
 
   // The simplest program that gives rise to a dependency edge in the graph is an interface with
   // an implementing class. In this case, changes to the interface could require re-dexing the
-  // implementing class despite no derived changes happening to the classfile for the implementing
+  // implementing class despite no derived changes happing to the classfile for the implementing
   // class.
   //
   // For example, adding default method I.foo will trigger javac compilation of I and A to I.class
@@ -68,24 +72,47 @@
           .run(parameters.getRuntime(), TestClass.class)
           .assertSuccessWithOutputLines("Hello World!");
     } else {
-      D8TestBuilder builder = testForD8();
-      DesugarGraphTestConsumer consumer = new DesugarGraphTestConsumer();
-      builder.getBuilder().setDesugarGraphConsumer(consumer);
-      Origin originI = DesugarGraphUtils.addClassWithOrigin(I.class, builder);
-      Origin originA = DesugarGraphUtils.addClassWithOrigin(A.class, builder);
-      builder
-          .addProgramClasses(TestClass.class)
+      MyDesugarGraphConsumer consumer = new MyDesugarGraphConsumer();
+      Origin originI = makeOrigin("I");
+      Origin originA = makeOrigin("A");
+      testForD8()
           .setMinApi(parameters.getApiLevel())
+          .addProgramClasses(TestClass.class)
+          .apply(
+              b ->
+                  b.getBuilder()
+                      .setDesugarGraphConsumer(consumer)
+                      .addClassProgramData(ToolHelper.getClassAsBytes(I.class), originI)
+                      .addClassProgramData(ToolHelper.getClassAsBytes(A.class), originA))
           .run(parameters.getRuntime(), TestClass.class)
           .assertSuccessWithOutputLines("Hello World!");
       // If API level indicates desugaring is needed check the edges are reported.
       if (parameters.getApiLevel().getLevel() < AndroidApiLevel.N.getLevel()) {
-        assertEquals(1, consumer.totalEdgeCount());
-        assertTrue(consumer.contains(originI, originA));
+        assertEquals(1, consumer.edges.size());
+        assertEquals(originI, consumer.edges.keySet().iterator().next());
+        assertEquals(originA, consumer.edges.values().iterator().next().iterator().next());
       } else {
-        assertEquals(0, consumer.totalEdgeCount());
+        assertEquals(0, consumer.edges.size());
       }
     }
   }
 
+  private Origin makeOrigin(String name) {
+    return new Origin(Origin.root()) {
+      @Override
+      public String part() {
+        return name;
+      }
+    };
+  }
+
+  public static class MyDesugarGraphConsumer implements DesugarGraphConsumer {
+
+    Map<Origin, Set<Origin>> edges = new HashMap<>();
+
+    @Override
+    public synchronized void accept(Origin dependent, Origin dependency) {
+      edges.computeIfAbsent(dependency, s -> new HashSet<>()).add(dependent);
+    }
+  }
 }