Merge "Reserved parent package prefix should be reserved indeed."
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index 39ca020..c363484 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -286,9 +286,15 @@
if (state == null) {
// Calculate the parent package prefix, e.g., La/b/c -> La/b
String parentPackage = getParentPackagePrefix(prefix);
- // Create a state for parent package prefix, if necessary, in a recursive manner.
- // That recursion should end when the parent package hits the top-level, "".
- Namespace superState = getStateForPackagePrefix(parentPackage);
+ Namespace superState;
+ if (noObfuscationPrefixes.contains(parentPackage)) {
+ // Restore a state for parent package prefix if it should be kept.
+ superState = states.computeIfAbsent(parentPackage, Namespace::new);
+ } else {
+ // Create a state for parent package prefix, if necessary, in a recursive manner.
+ // That recursion should end when the parent package hits the top-level, "".
+ superState = getStateForPackagePrefix(parentPackage);
+ }
// From the super state, get a renamed package prefix for the current level.
String renamedPackagePrefix = superState.nextPackagePrefix();
// Create a new state, which corresponds to a new name space, for the current level.
diff --git a/src/test/examples/naming101/keep-rules-106.txt b/src/test/examples/naming101/keep-rules-106.txt
new file mode 100644
index 0000000..69c29dd
--- /dev/null
+++ b/src/test/examples/naming101/keep-rules-106.txt
@@ -0,0 +1,16 @@
+# 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.
+
+# This will dominate the whole package hierarchy.
+-keep class naming101.c {
+ *;
+}
+
+-keep,allowobfuscation class **.c {
+ *;
+}
+
+-keep,allowobfuscation class **.d {
+ *;
+}
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 5975483..877ffc0 100644
--- a/src/test/java/com/android/tools/r8/naming/PackageNamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/PackageNamingTest.java
@@ -26,6 +26,7 @@
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -74,6 +75,7 @@
inspections.put("naming101:keep-rules-005.txt", PackageNamingTest::test101_rule005);
inspections.put("naming101:keep-rules-102.txt", PackageNamingTest::test101_rule102);
inspections.put("naming101:keep-rules-104.txt", PackageNamingTest::test101_rule104);
+ inspections.put("naming101:keep-rules-106.txt", PackageNamingTest::test101_rule106);
return createTests(tests, inspections);
}
@@ -357,4 +359,31 @@
assertNotEquals("naming101.a", getPackageNameFromDescriptor(renamedName));
}
}
+
+ private static void test101_rule106(DexItemFactory dexItemFactory, NamingLens naming) {
+ // Classes that end with either c or d will be kept and renamed.
+ List<String> klasses =
+ CLASSES_IN_NAMING101.stream()
+ .filter(className -> className.endsWith("c;") || className.endsWith("d;"))
+ .collect(Collectors.toList());
+ verifyUniqueNaming(dexItemFactory, naming, klasses);
+
+ // Check naming101.c is kept as-is.
+ DexType topC = dexItemFactory.createType("Lnaming101/c;");
+ assertEquals("Lnaming101/c;", naming.lookupDescriptor(topC).toSourceString());
+
+ // naming101.d accesses to a package-private, static field in naming101.c.
+ // Therefore, it should remain in the same package.
+ DexType topD = dexItemFactory.createType("Lnaming101/d;");
+ String renamedTopD = naming.lookupDescriptor(topD).toSourceString();
+ assertEquals("naming101", getPackageNameFromDescriptor(renamedTopD));
+
+ // Due to the keep rule for naming101.c, package prefix naming101 is reserved.
+ // That is, every renamed class should have naming101 as parent package prefix.
+ for (String klass : klasses) {
+ DexType t = dexItemFactory.createType(klass);
+ String rename = naming.lookupDescriptor(t).toSourceString();
+ assertTrue(rename.startsWith("Lnaming101/"));
+ }
+ }
}