Merge "Tweak handling of arguments when argument register reuse is disabled."
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index d169661..e21b00a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -18,14 +18,11 @@
 import com.android.tools.r8.dex.IndexedItemCollection;
 import com.android.tools.r8.dex.MixedSectionCollection;
 import com.android.tools.r8.ir.code.IRCode;
-import com.android.tools.r8.ir.code.Invoke;
 import com.android.tools.r8.ir.code.MoveType;
 import com.android.tools.r8.ir.code.ValueNumberGenerator;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.InliningConstraint;
 import com.android.tools.r8.ir.regalloc.RegisterAllocator;
-import com.android.tools.r8.ir.synthetic.ForwardMethodSourceCode;
-import com.android.tools.r8.ir.synthetic.SynthesizedCode;
 import com.android.tools.r8.logging.Log;
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
@@ -308,25 +305,6 @@
     return builder.build();
   }
 
-  public DexEncodedMethod toForwardingMethod(DexClass holder, DexItemFactory itemFactory) {
-    DexMethod newMethod = itemFactory.createMethod(holder.type, method.proto, method.name);
-    Builder builder = builder(this);
-    builder.setMethod(newMethod);
-    builder.setCode(new SynthesizedCode(
-        new ForwardMethodSourceCode(holder.type, method.proto, method.holder, method,
-            Invoke.Type.SUPER),
-        registry -> {
-          if (this.method.holder.isInterface()) {
-            registry.registerInvokeInterface(newMethod);
-          } else {
-            registry.registerInvokeVirtual(newMethod);
-          }
-        }));
-    builder.accessFlags.setSynthetic();
-    accessFlags.unsetFinal();
-    return builder.build();
-  }
-
   public String codeToString() {
     return code == null ? "<no code>" : code.toString();
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 8302ab2..368cb22 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -52,7 +52,6 @@
     }
   }
 
-  @Override
   public void addDependencies(MixedSectionCollection collector) {
     // We only have a class data item if there are methods or fields.
     if (hasMethodsOrFields()) {
@@ -120,9 +119,4 @@
   public DexEncodedArray getStaticValues() {
     return staticValues;
   }
-
-  public void addVirtualMethod(DexEncodedMethod virtualMethod) {
-    virtualMethods = Arrays.copyOf(virtualMethods, virtualMethods.length + 1);
-    virtualMethods[virtualMethods.length - 1] = virtualMethod;
-  }
 }
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 c957b58..bee210c 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
@@ -18,7 +18,6 @@
 
 // Source code representing synthesized accessor method.
 final class AccessorMethodSourceCode extends SynthesizedLambdaSourceCode {
-
   AccessorMethodSourceCode(LambdaClass lambda) {
     super(/* no receiver for static method */ null, lambda, lambda.target.callTarget);
     // We should never need an accessor for interface methods since
@@ -82,7 +81,7 @@
   }
 
   @Override
-  protected void prepareInstructions() {
+  void prepareInstructions() {
     DexMethod implMethod = descriptor().implHandle.asMethod();
     DexType[] accessorParams = proto.parameters.values;
 
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 236c9e5..ecda01e 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
@@ -11,8 +11,6 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.code.Invoke;
-import com.android.tools.r8.ir.synthetic.ForwardMethodSourceCode;
-import com.android.tools.r8.ir.synthetic.SynthesizedCode;
 import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.IdentityHashMap;
@@ -24,7 +22,6 @@
 // Default and static method interface desugaring processor for classes.
 // Adds default interface methods into the class when needed.
 final class ClassProcessor {
-
   private final InterfaceMethodRewriter rewriter;
   // Set of already processed classes.
   private final Set<DexClass> processedClasses = Sets.newIdentityHashSet();
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/ForwardMethodSourceCode.java
similarity index 87%
rename from src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java
rename to src/main/java/com/android/tools/r8/ir/desugar/ForwardMethodSourceCode.java
index bcc9462..808456b 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ForwardMethodSourceCode.java
@@ -2,7 +2,7 @@
 // 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.ir.synthetic;
+package com.android.tools.r8.ir.desugar;
 
 import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.graph.DexMethod;
@@ -16,13 +16,12 @@
 import java.util.List;
 
 // Source code representing simple forwarding method.
-public final class ForwardMethodSourceCode extends SingleBlockSourceCode {
-
+final class ForwardMethodSourceCode extends SingleBlockSourceCode {
   private final DexType targetReceiver;
   private final DexMethod target;
   private final Invoke.Type invokeType;
 
-  public ForwardMethodSourceCode(DexType receiver, DexProto proto,
+  ForwardMethodSourceCode(DexType receiver, DexProto proto,
       DexType targetReceiver, DexMethod target, Invoke.Type invokeType) {
     super(receiver, proto);
     assert (targetReceiver == null) == (invokeType == Invoke.Type.STATIC);
@@ -32,14 +31,8 @@
     this.invokeType = invokeType;
     assert checkSignatures();
 
-    switch (invokeType) {
-      case STATIC:
-      case SUPER:
-      case INTERFACE:
-      case VIRTUAL:
-        break;
-      default:
-        throw new Unimplemented("Invoke type " + invokeType + " is not yet supported.");
+    if (invokeType != Invoke.Type.STATIC) {
+      throw new Unimplemented("Invoke type " + invokeType + " is not yet supported.");
     }
   }
 
@@ -72,7 +65,7 @@
   }
 
   @Override
-  protected void prepareInstructions() {
+  void prepareInstructions() {
     // Prepare call arguments.
     List<MoveType> argMoveTypes = new ArrayList<>();
     List<Integer> argRegisters = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaBridgeMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaBridgeMethodSourceCode.java
index cc4f1f2..d35566a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaBridgeMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaBridgeMethodSourceCode.java
@@ -14,7 +14,6 @@
 
 // Source code representing synthesized lambda bridge method.
 final class LambdaBridgeMethodSourceCode extends SynthesizedLambdaSourceCode {
-
   private final DexMethod mainMethod;
 
   LambdaBridgeMethodSourceCode(LambdaClass lambda, DexMethod mainMethod, DexMethod bridgeMethod) {
@@ -23,7 +22,7 @@
   }
 
   @Override
-  protected void prepareInstructions() {
+  void prepareInstructions() {
     DexType[] currentParams = proto.parameters.values;
     DexType[] enforcedParams = descriptor().enforcedProto.parameters.values;
 
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 a4801c9..e92f78f 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
@@ -12,8 +12,8 @@
 import com.android.tools.r8.graph.DexAnnotationSetRefList;
 import com.android.tools.r8.graph.DexApplication.Builder;
 import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexClassPromise;
 import com.android.tools.r8.graph.DexCode;
+import com.android.tools.r8.graph.DexClassPromise;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
@@ -27,7 +27,6 @@
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.DexValue;
 import com.android.tools.r8.ir.code.Invoke;
-import com.android.tools.r8.ir.synthetic.SynthesizedCode;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -50,7 +49,6 @@
  * separate lambda classes.
  */
 final class LambdaClass {
-
   final LambdaRewriter rewriter;
   final DexType type;
   final LambdaDescriptor descriptor;
@@ -372,7 +370,6 @@
   // be the same method as specified in lambda descriptor or a newly synthesized accessor.
   // Also provides action for ensuring accessibility of the referenced symbols.
   abstract class Target {
-
     final DexMethod callTarget;
     final Invoke.Type invokeType;
 
@@ -389,7 +386,6 @@
 
   // Used for targeting methods referenced directly without creating accessors.
   private final class NoAccessorMethodTarget extends Target {
-
     NoAccessorMethodTarget(Invoke.Type invokeType) {
       super(descriptor.implHandle.asMethod(), invokeType);
     }
@@ -402,7 +398,6 @@
 
   // Used for static private lambda$ methods. Only needs access relaxation.
   private final class StaticLambdaImplTarget extends Target {
-
     StaticLambdaImplTarget() {
       super(descriptor.implHandle.asMethod(), Invoke.Type.STATIC);
     }
@@ -425,7 +420,6 @@
   // Used for instance private lambda$ methods. Needs to be converted to
   // a package-private static method.
   private class InstanceLambdaImplTarget extends Target {
-
     InstanceLambdaImplTarget(DexMethod staticMethod) {
       super(staticMethod, Invoke.Type.STATIC);
     }
@@ -458,7 +452,7 @@
           dexCode.setDebugInfo(dexCode.debugInfoWithAdditionalFirstParameter(null));
           assert (dexCode.getDebugInfo() == null)
               || (callTarget.proto.parameters.values.length
-              == dexCode.getDebugInfo().parameters.length);
+                  == dexCode.getDebugInfo().parameters.length);
           directMethods[i] = newMethod;
           return true;
         }
@@ -470,7 +464,6 @@
   // Used for instance/static methods or constructors accessed via
   // synthesized accessor method. Needs accessor method to be created.
   private class ClassMethodWithAccessorTarget extends Target {
-
     ClassMethodWithAccessorTarget(DexMethod accessorMethod) {
       super(accessorMethod, Invoke.Type.STATIC);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClassConstructorSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClassConstructorSourceCode.java
index 539fcf0..db8e1f5 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClassConstructorSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClassConstructorSourceCode.java
@@ -13,14 +13,13 @@
 // Source code representing synthesized lambda class constructor.
 // Used for stateless lambdas to instantiate singleton instance.
 final class LambdaClassConstructorSourceCode extends SynthesizedLambdaSourceCode {
-
   LambdaClassConstructorSourceCode(LambdaClass lambda) {
     super(null /* Class initializer is static */, lambda, lambda.classConstructor);
     assert lambda.instanceField != null;
   }
 
   @Override
-  protected void prepareInstructions() {
+  void prepareInstructions() {
     // Create and initialize an instance.
     int instance = nextRegister(MoveType.OBJECT);
     add(builder -> builder.addNewInstance(instance, lambda.type));
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaConstructorSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaConstructorSourceCode.java
index b736403..b4aef78 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaConstructorSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaConstructorSourceCode.java
@@ -14,13 +14,12 @@
 
 // Source code representing synthesized lambda constructor.
 final class LambdaConstructorSourceCode extends SynthesizedLambdaSourceCode {
-
   LambdaConstructorSourceCode(LambdaClass lambda) {
     super(lambda, lambda.constructor);
   }
 
   @Override
-  protected void prepareInstructions() {
+  void prepareInstructions() {
     // Super constructor call (always java.lang.Object.<init>()).
     DexMethod objectInitMethod = lambda.rewriter.objectInitMethod;
     add(builder -> builder.addInvoke(Invoke.Type.DIRECT, objectInitMethod,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
index 5eb4c30..9e4c570 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
@@ -25,7 +25,6 @@
 
 // Source code representing synthesized lambda main method
 final class LambdaMainMethodSourceCode extends SynthesizedLambdaSourceCode {
-
   LambdaMainMethodSourceCode(LambdaClass lambda, DexMethod mainMethod) {
     super(lambda, mainMethod);
   }
@@ -178,7 +177,7 @@
   }
 
   @Override
-  protected void prepareInstructions() {
+  void prepareInstructions() {
     DexType[] capturedTypes = captures();
     DexType[] erasedParams = descriptor().erasedProto.parameters.values;
     DexType erasedReturnType = descriptor().erasedProto.returnType;
@@ -463,7 +462,7 @@
   private int addPrimitiveBoxing(int register, DexType primitiveType, DexType boxType) {
     // Generate factory method fo boxing.
     DexItemFactory factory = factory();
-    DexProto proto = factory.createProto(boxType, new DexType[]{primitiveType});
+    DexProto proto = factory.createProto(boxType, new DexType[] { primitiveType });
     DexMethod method = factory.createMethod(boxType, proto, factory.valueOfMethodName);
 
     MoveType moveType = MoveType.fromDexType(primitiveType);
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SingleBlockSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/SingleBlockSourceCode.java
similarity index 89%
rename from src/main/java/com/android/tools/r8/ir/synthetic/SingleBlockSourceCode.java
rename to src/main/java/com/android/tools/r8/ir/desugar/SingleBlockSourceCode.java
index 8c97f8f..32631c2 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SingleBlockSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/SingleBlockSourceCode.java
@@ -2,7 +2,7 @@
 // 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.ir.synthetic;
+package com.android.tools.r8.ir.desugar;
 
 import static com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo.NO_THROW;
 
@@ -21,10 +21,9 @@
 import java.util.List;
 import java.util.function.Consumer;
 
-public abstract class SingleBlockSourceCode implements SourceCode {
-
-  protected final DexType receiver;
-  protected final DexProto proto;
+abstract class SingleBlockSourceCode implements SourceCode {
+  final DexType receiver;
+  final DexProto proto;
 
   // The next free register, note that we always
   // assign each value a new (next available) register.
@@ -41,7 +40,7 @@
   // Instruction constructors
   private List<Consumer<IRBuilder>> constructors = new ArrayList<>();
 
-  protected SingleBlockSourceCode(DexType receiver, DexProto proto) {
+  SingleBlockSourceCode(DexType receiver, DexProto proto) {
     assert proto != null;
     this.receiver = receiver;
     this.proto = proto;
@@ -58,45 +57,45 @@
     }
   }
 
-  protected final void add(Consumer<IRBuilder> constructor) {
+  final void add(Consumer<IRBuilder> constructor) {
     constructors.add(constructor);
   }
 
-  protected final int nextRegister(MoveType type) {
+  final int nextRegister(MoveType type) {
     int value = nextRegister;
     nextRegister += type == MoveType.WIDE ? 2 : 1;
     return value;
   }
 
-  protected final Value getReceiverValue() {
+  final Value getReceiverValue() {
     assert receiver != null;
     assert receiverValue != null;
     return receiverValue;
   }
 
-  protected final int getReceiverRegister() {
+  final int getReceiverRegister() {
     assert receiver != null;
     assert receiverRegister >= 0;
     return receiverRegister;
   }
 
-  protected final Value getParamValue(int paramIndex) {
+  final Value getParamValue(int paramIndex) {
     assert paramIndex >= 0;
     assert paramIndex < paramValues.length;
     return paramValues[paramIndex];
   }
 
-  protected final int getParamCount() {
+  final int getParamCount() {
     return paramValues.length;
   }
 
-  protected final int getParamRegister(int paramIndex) {
+  final int getParamRegister(int paramIndex) {
     assert paramIndex >= 0;
     assert paramIndex < paramRegisters.length;
     return paramRegisters[paramIndex];
   }
 
-  protected abstract void prepareInstructions();
+  abstract void prepareInstructions();
 
   @Override
   public final boolean needsPrelude() {
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java b/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedCode.java
similarity index 73%
rename from src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java
rename to src/main/java/com/android/tools/r8/ir/desugar/SynthesizedCode.java
index 7716663..3a07ef4 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedCode.java
@@ -2,7 +2,7 @@
 // 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.ir.synthetic;
+package com.android.tools.r8.ir.desugar;
 
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.Code;
@@ -13,21 +13,12 @@
 import com.android.tools.r8.ir.conversion.SourceCode;
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.InternalOptions;
-import java.util.function.Consumer;
 
 public final class SynthesizedCode extends Code {
-
   private final SourceCode sourceCode;
-  private final Consumer<UseRegistry> registryCallback;
 
   public SynthesizedCode(SourceCode sourceCode) {
     this.sourceCode = sourceCode;
-    this.registryCallback = SynthesizedCode::registerReachableDefinitionsDefault;
-  }
-
-  public SynthesizedCode(SourceCode sourceCode, Consumer<UseRegistry> callback) {
-    this.sourceCode = sourceCode;
-    this.registryCallback = callback;
   }
 
   @Override
@@ -40,13 +31,9 @@
     return toString(null);
   }
 
-  private static void registerReachableDefinitionsDefault(UseRegistry registry) {
-    throw new Unreachable();
-  }
-
   @Override
-  public void registerReachableDefinitions(UseRegistry registry) {
-    registryCallback.accept(registry);
+  public final void registerReachableDefinitions(UseRegistry registry) {
+    throw new Unreachable();
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedLambdaSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedLambdaSourceCode.java
index 9a3531f..7a63c32 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedLambdaSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedLambdaSourceCode.java
@@ -8,11 +8,9 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
-import com.android.tools.r8.ir.synthetic.SingleBlockSourceCode;
 
 // Represents source code of synthesized lambda class methods.
 abstract class SynthesizedLambdaSourceCode extends SingleBlockSourceCode {
-
   final DexMethod currentMethod;
   final LambdaClass lambda;
 
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index 1bde881..4e68d0f 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -9,7 +9,6 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.GraphLense;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
@@ -19,7 +18,6 @@
 import java.util.function.Function;
 
 public class MemberRebindingAnalysis {
-
   private final AppInfoWithLiveness appInfo;
   private final GraphLense lense;
   private final GraphLense.Builder builder = GraphLense.builder();
@@ -121,63 +119,11 @@
       DexEncodedMethod target = lookupTarget.apply(method);
       // Rebind to the lowest library class or program class.
       if (target != null && target.method != method) {
-        DexClass targetClass = appInfo.definitionFor(target.method.holder);
-        if (!targetClass.accessFlags.isPublic()) {
-          DexClass originalClass = appInfo.definitionFor(method.holder);
-          // If the original is public, it might have been called from anywhere, so we need a
-          // bridge. Likewise, if the original is in a different package, we might need a bridge,
-          // too.
-          String packageDescriptor =
-              originalClass.accessFlags.isPublic() ? null : method.holder.getPackageDescriptor();
-          if (packageDescriptor == null
-              || !packageDescriptor.equals(targetClass.type.getPackageDescriptor())) {
-            DexProgramClass bridgeHolder = findBridgeMethodHolder(originalClass, targetClass,
-                packageDescriptor);
-            assert bridgeHolder != null;
-            DexEncodedMethod bridgeMethod = target
-                .toForwardingMethod(bridgeHolder, appInfo.dexItemFactory);
-            bridgeHolder.addVirtualMethod(bridgeMethod);
-            assert lookupTarget.apply(method) == bridgeMethod;
-            target = bridgeMethod;
-          }
-        }
-        // Target can be null, if we would be rebinding to a non-visible method in a library.
-        if (target != null) {
-          builder.map(method, validTargetFor(target.method, method, lookupTargetOnClass));
-        }
+        builder.map(method, validTargetFor(target.method, method, lookupTargetOnClass));
       }
     }
   }
 
-  private DexProgramClass findBridgeMethodHolder(DexClass originalClass, DexClass targetClass,
-      String packageDescriptor) {
-    if (originalClass == targetClass || originalClass.isLibraryClass()) {
-      return null;
-    }
-    DexProgramClass newHolder = null;
-    // Recurse through supertype chain.
-    if (originalClass.superType.isSubtypeOf(targetClass.getType(), appInfo)) {
-      DexClass superClass = appInfo.definitionFor(originalClass.superType);
-      newHolder = findBridgeMethodHolder(superClass, targetClass, packageDescriptor);
-    } else {
-      for (DexType iface : originalClass.interfaces.values) {
-        if (iface.isSubtypeOf(targetClass.getType(), appInfo)) {
-          DexClass interfaceClass = appInfo.definitionFor(iface);
-          newHolder = findBridgeMethodHolder(interfaceClass, targetClass, packageDescriptor);
-        }
-      }
-    }
-    if (newHolder != null) {
-      // A supertype fulfills the visibility requirements.
-      return newHolder;
-    } else if (originalClass.accessFlags.isPublic()
-        || originalClass.type.getPackageDescriptor().equals(packageDescriptor)) {
-      // This class is visible. Return it if it is a program class, otherwise null.
-      return originalClass.asProgramClass();
-    }
-    return null;
-  }
-
   private void computeFieldRebinding(Set<DexField> fields,
       BiFunction<DexType, DexField, DexEncodedField> lookup,
       BiFunction<DexClass, DexField, DexEncodedField> lookupTargetOnClass) {
diff --git a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
index ec430fd..e038f6a 100644
--- a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
@@ -221,5 +221,4 @@
         return false;
     }
   }
-
 }
diff --git a/src/test/examplesAndroidN/memberrebinding4/Test.java b/src/test/examplesAndroidN/memberrebinding4/Test.java
deleted file mode 100644
index 6fc2ad5..0000000
--- a/src/test/examplesAndroidN/memberrebinding4/Test.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2017, 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 memberrebinding4;
-
-import memberrebinding4.subpackage.PublicInterface;
-
-public class Test {
-
-  static class Inner implements PublicInterface {
-
-  }
-
-  public static void main(String[] args) {
-    test();
-  }
-
-  public static void test() {
-    new Inner().dump();
-  }
-}
diff --git a/src/test/examplesAndroidN/memberrebinding4/subpackage/PackagePrivateInterface.java b/src/test/examplesAndroidN/memberrebinding4/subpackage/PackagePrivateInterface.java
deleted file mode 100644
index 4bbb70d..0000000
--- a/src/test/examplesAndroidN/memberrebinding4/subpackage/PackagePrivateInterface.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2017, 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 memberrebinding4.subpackage;
-
-interface PackagePrivateInterface {
-
-  default void dump() {
-    System.out.println("I3");
-  }
-}
-
diff --git a/src/test/examplesAndroidN/memberrebinding4/subpackage/PublicInterface.java b/src/test/examplesAndroidN/memberrebinding4/subpackage/PublicInterface.java
deleted file mode 100644
index 8f2e1bb..0000000
--- a/src/test/examplesAndroidN/memberrebinding4/subpackage/PublicInterface.java
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2017, 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 memberrebinding4.subpackage;
-
-public interface PublicInterface extends PackagePrivateInterface {
-
-}
-
diff --git a/src/test/java/com/android/tools/r8/dex/ExtraFileTest.java b/src/test/java/com/android/tools/r8/dex/ExtraFileTest.java
index 26067c7..d2aa592 100644
--- a/src/test/java/com/android/tools/r8/dex/ExtraFileTest.java
+++ b/src/test/java/com/android/tools/r8/dex/ExtraFileTest.java
@@ -16,6 +16,7 @@
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import org.junit.Assert;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -32,6 +33,7 @@
   @Rule
   public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
 
+  @Ignore("b/38187737")
   @Test
   public void splitMemberRebindingTwoFiles()
       throws IOException, ProguardRuleParserException, ExecutionException, CompilationException {
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index 115aabd..7c75610 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -37,9 +37,9 @@
 import com.android.tools.r8.ir.code.Switch.Type;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.ir.conversion.SourceCode;
+import com.android.tools.r8.ir.desugar.SynthesizedCode;
 import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
 import com.android.tools.r8.ir.regalloc.RegisterAllocator;
-import com.android.tools.r8.ir.synthetic.SynthesizedCode;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
 import com.android.tools.r8.utils.AndroidApp;
@@ -82,7 +82,6 @@
   private static final int MANY_CLASSES_COUNT = 1000;
   private static final List<String> MANY_CLASSES;
   private static final String MANY_CLASSES_APP = "many-classes.zip";
-
   static {
     ImmutableList.Builder<String> builder = ImmutableList.builder();
     for (int i = 0; i < MANY_CLASSES_COUNT; ++i) {
diff --git a/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingTest.java b/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingTest.java
index df02001..e45b639 100644
--- a/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingTest.java
+++ b/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingTest.java
@@ -7,9 +7,9 @@
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.CompilationException;
+import com.android.tools.r8.R8;
 import com.android.tools.r8.R8Command;
 import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
 import com.android.tools.r8.utils.DexInspector;
@@ -22,12 +22,16 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.function.Consumer;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -59,22 +63,23 @@
   private final Path programFile;
   private final Consumer<DexInspector> inspection;
   private final Consumer<DexInspector> originalInspection;
-  private final int minApiLevel;
 
   @Rule
   public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
 
-  public MemberRebindingTest(TestConfiguration configuration) {
-    this.kind = configuration.kind;
-    originalDex = configuration.getDexPath();
+  public MemberRebindingTest(
+      String test, Frontend kind,
+      Consumer<DexInspector> inspection,
+      Consumer<DexInspector> originalInspection) {
+    this.kind = kind;
+    originalDex = Paths.get(ToolHelper.EXAMPLES_BUILD_DIR + test + "/classes.dex");
     if (kind == Frontend.DEX) {
       this.programFile = originalDex;
     } else {
-      this.programFile = configuration.getJarPath();
+      this.programFile = Paths.get(ToolHelper.EXAMPLES_BUILD_DIR + test + ".jar");
     }
-    this.inspection = configuration.processedInspection;
-    this.originalInspection = configuration.originalInspection;
-    this.minApiLevel = configuration.getMinApiLevel();
+    this.inspection = inspection;
+    this.originalInspection = originalInspection;
   }
 
   @Before
@@ -90,7 +95,6 @@
             .setOutputPath(Paths.get(out))
             .addProgramFiles(programFile)
             .addLibraryFiles(ListUtils.map(libs, Paths::get))
-            .setMinApiLevel(minApiLevel)
             .build(),
         options -> options.inlineAccessors = false);
   }
@@ -143,7 +147,7 @@
     assertTrue(iterator.next().holder().is("java.util.ArrayList"));
     assertTrue(iterator.next().holder().is("java.util.ArrayList"));
     assertTrue(iterator.next().holder().is("java.util.ArrayList"));
-    assertTrue(iterator.next().holder().is("memberrebinding.subpackage.PublicClass"));
+    assertTrue(iterator.next().holder().is("memberrebinding.subpackage.PackagePrivateClass"));
     // For the next three - test that we re-bind to the lowest library class.
     assertTrue(iterator.next().holder().is("memberrebindinglib.SubClass"));
     assertTrue(iterator.next().holder().is("memberrebindinglib.SubClass"));
@@ -169,8 +173,6 @@
       assertTrue(iterator.next().holder().is("memberrebinding2.ClassAtBottomOfChain"));
       assertTrue(iterator.next().holder().is("memberrebinding2.subpackage.PublicClass"));
     }
-    assertTrue(iterator.next().holder().is("java.lang.System"));
-    assertFalse(iterator.hasNext());
   }
 
   private static void inspectMain2(DexInspector inspector) {
@@ -184,8 +186,6 @@
       assertTrue(iterator.next().holder().is("memberrebinding2.SuperClassOfAll"));
       assertTrue(iterator.next().holder().is("memberrebinding2.subpackage.PackagePrivateClass"));
     }
-    assertTrue(iterator.next().holder().is("java.lang.System"));
-    assertFalse(iterator.hasNext());
   }
 
   public static MethodSignature TEST =
@@ -198,7 +198,6 @@
     assertTrue(iterator.next().holder().is("memberrebinding3.ClassAtBottomOfChain"));
     assertTrue(iterator.next().holder().is("memberrebinding3.ClassAtBottomOfChain"));
     assertTrue(iterator.next().holder().is("memberrebinding3.ClassAtBottomOfChain"));
-    assertFalse(iterator.hasNext());
   }
 
   private static void inspect3(DexInspector inspector) {
@@ -208,114 +207,38 @@
     assertTrue(iterator.next().holder().is("memberrebinding3.ClassAtBottomOfChain"));
     assertTrue(iterator.next().holder().is("memberrebinding3.ClassInMiddleOfChain"));
     assertTrue(iterator.next().holder().is("memberrebinding3.SuperClassOfAll"));
-    assertFalse(iterator.hasNext());
   }
 
-  private static void inspectOriginal4(DexInspector inspector) {
-    MethodSubject main = inspector.clazz("memberrebinding4.Test").method(TEST);
-    Iterator<InvokeInstructionSubject> iterator =
-        main.iterateInstructions(InstructionSubject::isInvoke);
-    assertTrue(iterator.next().holder().is("memberrebinding4.Test$Inner"));
-    assertTrue(iterator.next().holder().is("memberrebinding4.subpackage.PublicInterface"));
-    assertFalse(iterator.hasNext());
-  }
+  @Parameters(name = "{0}{1}")
+  public static Collection<Object[]> data() {
+    List<String> tests =
+        ImmutableList.of("memberrebinding", "memberrebinding2", "memberrebinding3");
 
-  private static void inspect4(DexInspector inspector) {
-    MethodSubject main = inspector.clazz("memberrebinding4.Test").method(TEST);
-    Iterator<InvokeInstructionSubject> iterator =
-        main.iterateInstructions(InstructionSubject::isInvoke);
-    assertTrue(iterator.next().holder().is("memberrebinding4.Test$Inner"));
-    assertTrue(iterator.next().holder().is("memberrebinding4.subpackage.PublicInterface"));
-    assertFalse(iterator.hasNext());
-  }
+    Map<String, List<Consumer<DexInspector>>> inspections = new HashMap<>();
+    inspections.put("memberrebinding", ImmutableList.of(
+        MemberRebindingTest::inspectMain,
+        MemberRebindingTest::inspectOriginalMain));
+    inspections.put("memberrebinding2", ImmutableList.of(
+        MemberRebindingTest::inspectMain2,
+        MemberRebindingTest::inspectOriginalMain2));
+    inspections.put("memberrebinding3", ImmutableList.of(
+        MemberRebindingTest::inspect3,
+        MemberRebindingTest::inspectOriginal3));
 
-  private static class TestConfiguration {
+    List<Object[]> testCases = new ArrayList<>();
+    Set<String> usedInspections = new HashSet<>();
 
-    private enum AndroidVersion {
-      PRE_N,
-      N
+    for (String test : tests) {
+      List<Consumer<DexInspector>> inspection = inspections.get(test);
+      assert inspection != null;
+      usedInspections.add(test);
+      testCases.add(new Object[]{test, Frontend.JAR, inspection.get(0), inspection.get(1)});
+      testCases.add(new Object[]{test, Frontend.DEX, inspection.get(0), inspection.get(1)});
     }
 
-    final String name;
-    final Frontend kind;
-    final AndroidVersion version;
-    final Consumer<DexInspector> originalInspection;
-    final Consumer<DexInspector> processedInspection;
+    assert usedInspections.size() == inspections.size();
 
-    private TestConfiguration(String name,
-        Frontend kind,
-        AndroidVersion version,
-        Consumer<DexInspector> originalInspection,
-        Consumer<DexInspector> processedInspection) {
-      this.name = name;
-      this.kind = kind;
-      this.version = version;
-      this.originalInspection = originalInspection;
-      this.processedInspection = processedInspection;
-    }
-
-    public static void add(ImmutableList.Builder<TestConfiguration> builder,
-        String name,
-        AndroidVersion version,
-        Consumer<DexInspector> originalInspection,
-        Consumer<DexInspector> processedInspection) {
-      if (version == AndroidVersion.PRE_N) {
-        builder.add(new TestConfiguration(name, Frontend.DEX, version, originalInspection,
-            processedInspection));
-      }
-      builder.add(new TestConfiguration(name, Frontend.JAR, version, originalInspection,
-          processedInspection));
-    }
-
-    public Path getDexPath() {
-      return getBuildPath().resolve(name).resolve("classes.dex");
-    }
-
-    public Path getJarPath() {
-      return getBuildPath().resolve(name + ".jar");
-    }
-
-    public Path getBuildPath() {
-      switch (version) {
-        case PRE_N:
-          return Paths.get(ToolHelper.EXAMPLES_BUILD_DIR);
-        case N:
-          return Paths.get(ToolHelper.EXAMPLES_ANDROID_N_BUILD_DIR);
-        default:
-          Assert.fail();
-          return null;
-      }
-    }
-
-    public int getMinApiLevel() {
-      switch (version) {
-        case PRE_N:
-          return Constants.DEFAULT_ANDROID_API;
-        case N:
-          return Constants.ANDROID_N_API;
-        default:
-          Assert.fail();
-          return -1;
-      }
-    }
-
-    public String toString() {
-      return name + " " + kind;
-    }
-  }
-
-  @Parameters(name = "{0}")
-  public static Collection<TestConfiguration> data() {
-    ImmutableList.Builder<TestConfiguration> builder = ImmutableList.builder();
-    TestConfiguration.add(builder, "memberrebinding", TestConfiguration.AndroidVersion.PRE_N,
-        MemberRebindingTest::inspectOriginalMain, MemberRebindingTest::inspectMain);
-    TestConfiguration.add(builder, "memberrebinding2", TestConfiguration.AndroidVersion.PRE_N,
-        MemberRebindingTest::inspectOriginalMain2, MemberRebindingTest::inspectMain2);
-    TestConfiguration.add(builder, "memberrebinding3", TestConfiguration.AndroidVersion.PRE_N,
-        MemberRebindingTest::inspectOriginal3, MemberRebindingTest::inspect3);
-    TestConfiguration.add(builder, "memberrebinding4", TestConfiguration.AndroidVersion.N,
-        MemberRebindingTest::inspectOriginal4, MemberRebindingTest::inspect4);
-    return builder.build();
+    return testCases;
   }
 
   @Test