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,