Merge "Collect dependencies of all kept annotations and add with reason"
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 6c3e47e..734e421 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -616,15 +616,17 @@
         new DiscardedChecker(rootSet, application, options).run();
       }
 
-      timing.begin("Minification");
-      // If we did not have keep rules, everything will be marked as keep, so no minification
-      // will happen. Just avoid the overhead.
-      NamingLens namingLens =
-          options.enableMinification
-              ? new Minifier(appView.appInfo().withLiveness(), rootSet, desugaredCallSites, options)
-                  .run(timing)
-              : NamingLens.getIdentityLens();
-      timing.end();
+      // Perform minification.
+      NamingLens namingLens;
+      if (options.enableMinification) {
+        timing.begin("Minification");
+        namingLens =
+            new Minifier(appView.appInfo().withLiveness(), rootSet, desugaredCallSites, options)
+                .run(timing);
+        timing.end();
+      } else {
+        namingLens = NamingLens.getIdentityLens();
+      }
 
       ProguardMapSupplier proguardMapSupplier;
 
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 28aabea..5e65aa3 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -38,22 +38,17 @@
   public DexTypeList interfaces;
   public DexString sourceFile;
 
-  /**
-   * Access has to be synchronized during concurrent collection/writing phase.
-   */
-  protected DexEncodedField[] staticFields;
-  /**
-   * Access has to be synchronized during concurrent collection/writing phase.
-   */
-  protected DexEncodedField[] instanceFields;
-  /**
-   * Access has to be synchronized during concurrent collection/writing phase.
-   */
-  protected DexEncodedMethod[] directMethods;
-  /**
-   * Access has to be synchronized during concurrent collection/writing phase.
-   */
-  protected DexEncodedMethod[] virtualMethods;
+  /** Access has to be synchronized during concurrent collection/writing phase. */
+  protected DexEncodedField[] staticFields = NO_FIELDS;
+
+  /** Access has to be synchronized during concurrent collection/writing phase. */
+  protected DexEncodedField[] instanceFields = NO_FIELDS;
+
+  /** Access has to be synchronized during concurrent collection/writing phase. */
+  protected DexEncodedMethod[] directMethods = NO_METHODS;
+
+  /** Access has to be synchronized during concurrent collection/writing phase. */
+  protected DexEncodedMethod[] virtualMethods = NO_METHODS;
 
   /** Enclosing context of this class if it is an inner class, null otherwise. */
   private EnclosingMethodAttribute enclosingMethod;
@@ -146,7 +141,8 @@
     System.arraycopy(directMethods, 0, newMethods, 0, directMethods.length);
     newMethods[directMethods.length] = method;
     directMethods = newMethods;
-    assert verifyNoDuplicateMethods(directMethods);
+    assert verifyCorrectnessOfMethodHolder(method);
+    assert verifyNoDuplicateMethods();
   }
 
   public void appendDirectMethods(Collection<DexEncodedMethod> methods) {
@@ -158,7 +154,8 @@
       i++;
     }
     directMethods = newMethods;
-    assert verifyNoDuplicateMethods(directMethods);
+    assert verifyCorrectnessOfMethodHolders(methods);
+    assert verifyNoDuplicateMethods();
   }
 
   public void removeDirectMethod(int index) {
@@ -170,12 +167,14 @@
 
   public void setDirectMethod(int index, DexEncodedMethod method) {
     directMethods[index] = method;
-    assert verifyNoDuplicateMethods(directMethods);
+    assert verifyCorrectnessOfMethodHolder(method);
+    assert verifyNoDuplicateMethods();
   }
 
   public void setDirectMethods(DexEncodedMethod[] values) {
     directMethods = MoreObjects.firstNonNull(values, NO_METHODS);
-    assert verifyNoDuplicateMethods(directMethods);
+    assert verifyCorrectnessOfMethodHolders(directMethods());
+    assert verifyNoDuplicateMethods();
   }
 
   public List<DexEncodedMethod> virtualMethods() {
@@ -191,7 +190,8 @@
     System.arraycopy(virtualMethods, 0, newMethods, 0, virtualMethods.length);
     newMethods[virtualMethods.length] = method;
     virtualMethods = newMethods;
-    assert verifyNoDuplicateMethods(virtualMethods);
+    assert verifyCorrectnessOfMethodHolder(method);
+    assert verifyNoDuplicateMethods();
   }
 
   public void appendVirtualMethods(Collection<DexEncodedMethod> methods) {
@@ -203,7 +203,8 @@
       i++;
     }
     virtualMethods = newMethods;
-    assert verifyNoDuplicateMethods(virtualMethods);
+    assert verifyCorrectnessOfMethodHolders(methods);
+    assert verifyNoDuplicateMethods();
   }
 
   public void removeVirtualMethod(int index) {
@@ -216,22 +217,39 @@
 
   public void setVirtualMethod(int index, DexEncodedMethod method) {
     virtualMethods[index] = method;
-    assert verifyNoDuplicateMethods(virtualMethods);
+    assert verifyCorrectnessOfMethodHolder(method);
+    assert verifyNoDuplicateMethods();
   }
 
   public void setVirtualMethods(DexEncodedMethod[] values) {
     virtualMethods = MoreObjects.firstNonNull(values, NO_METHODS);
-    assert verifyNoDuplicateMethods(virtualMethods);
+    assert verifyCorrectnessOfMethodHolders(virtualMethods());
+    assert verifyNoDuplicateMethods();
   }
 
-  private boolean verifyNoDuplicateMethods(DexEncodedMethod[] methods) {
+  private boolean verifyCorrectnessOfMethodHolder(DexEncodedMethod method) {
+    assert method.method.holder == type
+        : "Expected method `"
+            + method.method.toSourceString()
+            + "` to have holder `"
+            + type.toSourceString()
+            + "`";
+    return true;
+  }
+
+  private boolean verifyCorrectnessOfMethodHolders(Iterable<DexEncodedMethod> methods) {
+    for (DexEncodedMethod method : methods) {
+      assert verifyCorrectnessOfMethodHolder(method);
+    }
+    return true;
+  }
+
+  private boolean verifyNoDuplicateMethods() {
     Set<DexMethod> unique = Sets.newIdentityHashSet();
-    Arrays.stream(methods)
-        .forEach(
-            method -> {
-              boolean changed = unique.add(method.method);
-              assert changed : "Duplicate method `" + method.method.toSourceString() + "`";
-            });
+    for (DexEncodedMethod method : methods()) {
+      boolean changed = unique.add(method.method);
+      assert changed : "Duplicate method `" + method.method.toSourceString() + "`";
+    }
     return true;
   }
 
@@ -651,6 +669,8 @@
   public boolean isValid() {
     assert !isInterface()
         || Arrays.stream(virtualMethods).noneMatch(method -> method.accessFlags.isFinal());
+    assert verifyCorrectnessOfMethodHolders(methods());
+    assert verifyNoDuplicateMethods();
     return true;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
index bbb3391..90dbbdb 100644
--- a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
@@ -12,6 +12,7 @@
 import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Timing;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
 import java.util.Map;
 import java.util.function.Function;
@@ -33,7 +34,7 @@
     }
   }
 
-  Map<DexField, DexString> computeRenaming(Timing timing) {
+  FieldRenaming computeRenaming(Timing timing) {
     // Reserve names in all classes first. We do this in subtyping order so we do not
     // shadow a reserved field in subclasses. While there is no concept of virtual field
     // dispatch in Java, field resolution still traverses the super type chain and external
@@ -55,7 +56,20 @@
     timing.begin("rename-references");
     renameNonReboundReferences();
     timing.end();
-    return renaming;
+    return new FieldRenaming(renaming);
+  }
+
+  static class FieldRenaming {
+
+    final Map<DexField, DexString> renaming;
+
+    private FieldRenaming(Map<DexField, DexString> renaming) {
+      this.renaming = renaming;
+    }
+
+    public static FieldRenaming empty() {
+      return new FieldRenaming(ImmutableMap.of());
+    }
   }
 
   private void reserveNamesInSubtypes(DexType type, NamingState<DexType, ?> state) {
diff --git a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
index 5f990ac..21e6bf9 100644
--- a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.utils.Timing;
 import com.google.common.base.Equivalence;
 import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -96,6 +97,8 @@
   private final Equivalence<DexMethod> equivalence;
   private final Map<DexCallSite, DexString> callSiteRenaming = new IdentityHashMap<>();
 
+  private final Map<DexType, DexType> frontierMap = new IdentityHashMap<>();
+
   MethodNameMinifier(
       AppInfoWithLiveness appInfo,
       RootSet rootSet,
@@ -121,6 +124,7 @@
   }
 
   static class MethodRenaming {
+
     final Map<DexMethod, DexString> renaming;
     final Map<DexCallSite, DexString> callSiteRenaming;
 
@@ -129,26 +133,27 @@
       this.renaming = renaming;
       this.callSiteRenaming = callSiteRenaming;
     }
+
+    public static MethodRenaming empty() {
+      return new MethodRenaming(ImmutableMap.of(), ImmutableMap.of());
+    }
   }
 
   MethodRenaming computeRenaming(Timing timing) {
     // Phase 1: Reserve all the names that need to be kept and allocate linked state in the
     //          library part.
     timing.begin("Phase 1");
-    Map<DexType, DexType> frontierMap = new IdentityHashMap<>();
-    reserveNamesInClasses(appInfo.dexItemFactory.objectType,
-        appInfo.dexItemFactory.objectType,
-        null, frontierMap);
+    reserveNamesInClasses(
+        appInfo.dexItemFactory.objectType, appInfo.dexItemFactory.objectType, null);
     timing.end();
     // Phase 2: Reserve all the names that are required for interfaces.
     timing.begin("Phase 2");
-    DexType.forAllInterfaces(
-        appInfo.dexItemFactory, iface -> reserveNamesInInterfaces(iface, frontierMap));
+    DexType.forAllInterfaces(appInfo.dexItemFactory, this::reserveNamesInInterfaces);
     timing.end();
     // Phase 3: Assign names to interface methods. These are assigned by finding a name that is
     //          free in all naming states that may hold an implementation.
     timing.begin("Phase 3");
-    assignNamesToInterfaceMethods(frontierMap, timing);
+    assignNamesToInterfaceMethods(timing);
     timing.end();
     // Phase 4: Assign names top-down by traversing the subtype hierarchy.
     timing.begin("Phase 4");
@@ -201,8 +206,7 @@
     }
   }
 
-  private Set<NamingState<DexProto, ?>> getReachableStates(DexType type,
-      Map<DexType, DexType> frontierMap) {
+  private Set<NamingState<DexProto, ?>> getReachableStates(DexType type) {
     Set<DexType> interfaces = Sets.newIdentityHashSet();
     interfaces.add(type);
     collectSuperInterfaces(type, interfaces);
@@ -221,7 +225,7 @@
     return reachableStates;
   }
 
-  private void assignNamesToInterfaceMethods(Map<DexType, DexType> frontierMap, Timing timing) {
+  private void assignNamesToInterfaceMethods(Timing timing) {
     // First compute a map from method signatures to a set of naming states for interfaces and
     // frontier states of classes that implement them. We add the frontier states so that we can
     // reserve the names for later method naming.
@@ -232,17 +236,20 @@
     Map<Wrapper<DexMethod>, Set<DexMethod>> sourceMethodsMap = new HashMap<>();
     // A map from DexMethods to the first interface state it was seen in. Used to pick good names.
     Map<Wrapper<DexMethod>, NamingState<DexProto, ?>> originStates = new HashMap<>();
-    DexType.forAllInterfaces(appInfo.dexItemFactory, iface -> {
-      assert iface.isInterface();
-      DexClass clazz = appInfo.definitionFor(iface);
-      if (clazz != null) {
-        Set<NamingState<DexProto, ?>> collectedStates = getReachableStates(iface, frontierMap);
-        for (DexEncodedMethod method : shuffleMethods(clazz.methods())) {
-          addStatesToGlobalMapForMethod(
-              method, collectedStates, globalStateMap, sourceMethodsMap, originStates, iface);
-        }
-      }
-    });
+    DexType.forAllInterfaces(
+        appInfo.dexItemFactory,
+        iface -> {
+          assert iface.isInterface();
+          DexClass clazz = appInfo.definitionFor(iface);
+          if (clazz != null) {
+            assert clazz.isInterface();
+            Set<NamingState<DexProto, ?>> collectedStates = getReachableStates(iface);
+            for (DexEncodedMethod method : shuffleMethods(clazz.methods())) {
+              addStatesToGlobalMapForMethod(
+                  method, collectedStates, globalStateMap, sourceMethodsMap, originStates, iface);
+            }
+          }
+        });
     // Collect the live call sites for multi-interface lambda expression renaming. For code with
     // desugared lambdas this is a conservative estimate, as we don't track if the generated
     // lambda classes survive into the output. As multi-interface lambda expressions are rare
@@ -272,7 +279,7 @@
           for (DexEncodedMethod method : implementedMethods) {
             DexType iface = method.method.holder;
             assert iface.isInterface();
-            Set<NamingState<DexProto, ?>> collectedStates = getReachableStates(iface, frontierMap);
+            Set<NamingState<DexProto, ?>> collectedStates = getReachableStates(iface);
             addStatesToGlobalMapForMethod(
                 method, collectedStates, globalStateMap, sourceMethodsMap, originStates, iface);
             callSiteMethods.add(equivalence.wrap(method.method));
@@ -434,34 +441,33 @@
     return false;
   }
 
-  private void reserveNamesInClasses(DexType type, DexType libraryFrontier,
-      NamingState<DexProto, ?> parent,
-      Map<DexType, DexType> frontierMap) {
+  private void reserveNamesInClasses(
+      DexType type, DexType libraryFrontier, NamingState<DexProto, ?> parent) {
     assert !type.isInterface();
     DexClass holder = appInfo.definitionFor(type);
-    NamingState<DexProto, ?> state = allocateNamingStateAndReserve(holder, type, libraryFrontier,
-        parent, frontierMap);
+    NamingState<DexProto, ?> state =
+        allocateNamingStateAndReserve(holder, type, libraryFrontier, parent);
     // If this is a library class (or effectively a library class as it is missing) move the
     // frontier forward.
-    type.forAllExtendsSubtypes(subtype -> {
-      assert !subtype.isInterface();
-      reserveNamesInClasses(subtype,
-          holder == null || holder.isLibraryClass() ? subtype : libraryFrontier,
-          state, frontierMap);
-    });
+    type.forAllExtendsSubtypes(
+        subtype -> {
+          assert !subtype.isInterface();
+          reserveNamesInClasses(
+              subtype,
+              holder == null || holder.isLibraryClass() ? subtype : libraryFrontier,
+              state);
+        });
   }
 
-  private void reserveNamesInInterfaces(DexType type, Map<DexType, DexType> frontierMap) {
+  private void reserveNamesInInterfaces(DexType type) {
     assert type.isInterface();
     frontierMap.put(type, type);
     DexClass holder = appInfo.definitionFor(type);
-    allocateNamingStateAndReserve(holder, type, type, null, frontierMap);
+    allocateNamingStateAndReserve(holder, type, type, null);
   }
 
-  private NamingState<DexProto, ?> allocateNamingStateAndReserve(DexClass holder, DexType type,
-      DexType libraryFrontier,
-      NamingState<DexProto, ?> parent,
-      Map<DexType, DexType> frontierMap) {
+  private NamingState<DexProto, ?> allocateNamingStateAndReserve(
+      DexClass holder, DexType type, DexType libraryFrontier, NamingState<DexProto, ?> parent) {
     frontierMap.put(type, libraryFrontier);
     NamingState<DexProto, ?> state =
         computeStateIfAbsent(
diff --git a/src/main/java/com/android/tools/r8/naming/Minifier.java b/src/main/java/com/android/tools/r8/naming/Minifier.java
index e4ccbcd..becc643 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -15,6 +15,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.naming.ClassNameMinifier.ClassRenaming;
+import com.android.tools.r8.naming.FieldNameMinifier.FieldRenaming;
 import com.android.tools.r8.naming.MethodNameMinifier.MethodRenaming;
 import com.android.tools.r8.optimize.MemberRebindingAnalysis;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
@@ -56,21 +57,28 @@
     ClassNameMinifier classNameMinifier = new ClassNameMinifier(appInfo, rootSet, options);
     ClassRenaming classRenaming = classNameMinifier.computeRenaming(timing);
     timing.end();
+
+    assert new MinifiedRenaming(
+            classRenaming, MethodRenaming.empty(), FieldRenaming.empty(), appInfo)
+        .verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);
+
     timing.begin("MinifyMethods");
     MethodRenaming methodRenaming =
         new MethodNameMinifier(appInfo, rootSet, desugaredCallSites, options)
             .computeRenaming(timing);
     timing.end();
+
+    assert new MinifiedRenaming(classRenaming, methodRenaming, FieldRenaming.empty(), appInfo)
+        .verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);
+
     timing.begin("MinifyFields");
-    Map<DexField, DexString> fieldRenaming =
+    FieldRenaming fieldRenaming =
         new FieldNameMinifier(appInfo, rootSet, options).computeRenaming(timing);
     timing.end();
-    NamingLens lens =
-        new MinifiedRenaming(
-            classRenaming,
-            methodRenaming,
-            fieldRenaming,
-            appInfo);
+
+    NamingLens lens = new MinifiedRenaming(classRenaming, methodRenaming, fieldRenaming, appInfo);
+    assert lens.verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);
+
     timing.begin("MinifyIdentifiers");
     new IdentifierMinifier(
         appInfo, options.getProguardConfiguration().getAdaptClassStrings(), lens).run();
@@ -87,14 +95,14 @@
     private MinifiedRenaming(
         ClassRenaming classRenaming,
         MethodRenaming methodRenaming,
-        Map<DexField, DexString> fieldRenaming,
+        FieldRenaming fieldRenaming,
         AppInfo appInfo) {
       this.appInfo = appInfo;
       this.packageRenaming = classRenaming.packageRenaming;
       renaming.putAll(classRenaming.classRenaming);
       renaming.putAll(methodRenaming.renaming);
       renaming.putAll(methodRenaming.callSiteRenaming);
-      renaming.putAll(fieldRenaming);
+      renaming.putAll(fieldRenaming.renaming);
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/naming/NamingLens.java b/src/main/java/com/android/tools/r8/naming/NamingLens.java
index cee867e..aecae1e 100644
--- a/src/main/java/com/android/tools/r8/naming/NamingLens.java
+++ b/src/main/java/com/android/tools/r8/naming/NamingLens.java
@@ -7,10 +7,14 @@
 import static com.android.tools.r8.utils.DescriptorUtils.descriptorToJavaType;
 
 import com.android.tools.r8.graph.DexCallSite;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItem;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
@@ -19,7 +23,10 @@
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import java.util.Arrays;
 import java.util.Map;
+import java.util.Set;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -70,6 +77,40 @@
     return lookupName(reference.asDexField());
   }
 
+  public final DexField lookupField(DexField field, DexItemFactory dexItemFactory) {
+    return dexItemFactory.createField(
+        lookupType(field.clazz, dexItemFactory),
+        lookupType(field.type, dexItemFactory),
+        lookupName(field));
+  }
+
+  public final DexMethod lookupMethod(DexMethod method, DexItemFactory dexItemFactory) {
+    return dexItemFactory.createMethod(
+        lookupType(method.holder, dexItemFactory),
+        lookupProto(method.proto, dexItemFactory),
+        lookupName(method));
+  }
+
+  private DexProto lookupProto(DexProto proto, DexItemFactory dexItemFactory) {
+    return dexItemFactory.createProto(
+        lookupType(proto.returnType, dexItemFactory),
+        Arrays.stream(proto.parameters.values)
+            .map(type -> lookupType(type, dexItemFactory))
+            .toArray(DexType[]::new));
+  }
+
+  public final DexType lookupType(DexType type, DexItemFactory dexItemFactory) {
+    if (type.isPrimitiveType() || type.isVoidType()) {
+      return type;
+    }
+    if (type.isArrayType()) {
+      DexType newBaseType = lookupType(type.toBaseType(dexItemFactory), dexItemFactory);
+      return type.replaceBaseType(newBaseType, dexItemFactory);
+    }
+    assert type.isClassType();
+    return dexItemFactory.createType(lookupDescriptor(type));
+  }
+
   public static NamingLens getIdentityLens() {
     return new IdentityLens();
   }
@@ -97,6 +138,34 @@
    */
   public abstract boolean checkTargetCanBeTranslated(DexMethod item);
 
+  public final boolean verifyNoCollisions(
+      Iterable<DexProgramClass> classes, DexItemFactory dexItemFactory) {
+    Set<DexReference> references = Sets.newIdentityHashSet();
+    for (DexProgramClass clazz : classes) {
+      {
+        DexType newType = lookupType(clazz.type, dexItemFactory);
+        boolean referencesChanged = references.add(newType);
+        assert referencesChanged
+            : "Duplicate definition of type `" + newType.toSourceString() + "`";
+      }
+
+      for (DexEncodedField field : clazz.fields()) {
+        DexField newField = lookupField(field.field, dexItemFactory);
+        boolean referencesChanged = references.add(newField);
+        assert referencesChanged
+            : "Duplicate definition of field `" + newField.toSourceString() + "`";
+      }
+
+      for (DexEncodedMethod method : clazz.methods()) {
+        DexMethod newMethod = lookupMethod(method.method, dexItemFactory);
+        boolean referencesChanged = references.add(newMethod);
+        assert referencesChanged
+            : "Duplicate definition of method `" + newMethod.toSourceString() + "`";
+      }
+    }
+    return true;
+  }
+
   private static class IdentityLens extends NamingLens {
 
     private IdentityLens() {
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index 6d34f44..5b5cf9d 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -104,7 +104,7 @@
   private static final String JCTF_COMMON_JAR = "build/libs/jctfCommon.jar";
 
   // Parent dir for on-the-fly compiled jctf dex output.
-  private static final String JCTF_TESTS_PREFIX = "build/classes/jctfTests";
+  private static final String JCTF_TESTS_PREFIX = "build/classes/java/jctfTests";
   private static final String JCTF_TESTS_LIB_PREFIX =
       JCTF_TESTS_PREFIX + "/com/google/jctf/test/lib";
   private static final String JUNIT_TEST_RUNNER = "org.junit.runner.JUnitCore";
diff --git a/src/test/java/com/android/tools/r8/naming/PackageNamingTest.java b/src/test/java/com/android/tools/r8/naming/PackageNamingTest.java
index 877ffc0..4209cb6 100644
--- a/src/test/java/com/android/tools/r8/naming/PackageNamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/PackageNamingTest.java
@@ -312,11 +312,15 @@
     assertEquals("Lnaming101/a/a;", naming.lookupDescriptor(aa).toSourceString());
     DexType ba = dexItemFactory.createType("Lnaming101/b/a;");
     assertEquals("Lnaming101/b/a;", naming.lookupDescriptor(ba).toSourceString());
-    // Due to package-private access, classes in the same package should remain as-is.
-    DexType ab = dexItemFactory.createType("Lnaming101/a/b;");
-    assertEquals("Lnaming101/a/b;", naming.lookupDescriptor(ab).toSourceString());
+    // Due to package-private access, classes in the same package should remain in the same package.
+    DexType ac = dexItemFactory.createType("Lnaming101/a/c;");
+    assertEquals(
+        getPackageNameFromDescriptor(naming.lookupDescriptor(aa).toString()),
+        getPackageNameFromDescriptor(naming.lookupDescriptor(ac).toString()));
     DexType bb = dexItemFactory.createType("Lnaming101/b/b;");
-    assertEquals("Lnaming101/b/b;", naming.lookupDescriptor(bb).toSourceString());
+    assertEquals(
+        getPackageNameFromDescriptor(naming.lookupDescriptor(ba).toString()),
+        getPackageNameFromDescriptor(naming.lookupDescriptor(bb).toString()));
 
     // All other classes can be repackaged to naming101.a, but naming101.a.a exists to make a name
     // conflict. Thus, those should not be renamed to 'a'.
@@ -340,11 +344,15 @@
     assertEquals("Lnaming101/a/a;", naming.lookupDescriptor(aa).toSourceString());
     DexType ba = dexItemFactory.createType("Lnaming101/b/a;");
     assertEquals("Lnaming101/b/a;", naming.lookupDescriptor(ba).toSourceString());
-    // Due to package-private access, classes in the same package should remain as-is.
-    DexType ab = dexItemFactory.createType("Lnaming101/a/b;");
-    assertEquals("Lnaming101/a/b;", naming.lookupDescriptor(ab).toSourceString());
+    // Due to package-private access, classes in the same package should remain in the same package.
+    DexType ac = dexItemFactory.createType("Lnaming101/a/c;");
+    assertEquals(
+        getPackageNameFromDescriptor(naming.lookupDescriptor(aa).toString()),
+        getPackageNameFromDescriptor(naming.lookupDescriptor(ac).toString()));
     DexType bb = dexItemFactory.createType("Lnaming101/b/b;");
-    assertEquals("Lnaming101/b/b;", naming.lookupDescriptor(bb).toSourceString());
+    assertEquals(
+        getPackageNameFromDescriptor(naming.lookupDescriptor(ba).toString()),
+        getPackageNameFromDescriptor(naming.lookupDescriptor(bb).toString()));
 
     // All other packages are flattened to naming101, hence all other classes will be in
     // naming101.* package. Due to naming101.a.a, prefix naming101.a is already used. So,