Interpret keeppackagenames as class filter and not package filter

RELNOTES: R8 will interpret -keeppackagenames as a class filter and check against both package and class name. This will allow developers to specificy single classes to keep package names for.

Bug: b/250671873
Change-Id: Ieba1c18e0b7978f770a14cf3ad1e8bd5688ed67b
diff --git a/src/main/java/com/android/tools/r8/repackaging/Repackaging.java b/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
index f292409..15e9fdf 100644
--- a/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
+++ b/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
@@ -245,9 +245,9 @@
         continue;
       }
       // Already processed packages should have been removed.
+      assert !repackagingConfiguration.isPackageInTargetLocation(pkg);
       String newPackageDescriptor =
           repackagingConfiguration.getNewPackageDescriptor(pkg, seenPackageDescriptors);
-      assert !repackagingConfiguration.isPackageInTargetLocation(pkg);
       for (DexProgramClass classToRepackage : classesToRepackage) {
         processClass(classToRepackage, pkg, newPackageDescriptor, mappings);
       }
@@ -351,7 +351,6 @@
         // Preserve full package name under destination package when not minifying
         // (no matter which package obfuscation mode is used).
         if (newPackageDescriptor.isEmpty()
-            || proguardConfiguration.getKeepPackageNamesPatterns().matches(pkg)
             || mayHavePinnedPackagePrivateOrProtectedItem(pkg)) {
           return pkg.getPackageDescriptor();
         }
@@ -360,8 +359,7 @@
         return newPackageDescriptor;
       } else if (packageObfuscationMode.isMinification()) {
         // Always keep top-level classes since their packages can never be minified.
-        if (pkg.getPackageDescriptor().equals("")
-            || proguardConfiguration.getKeepPackageNamesPatterns().matches(pkg)
+        if (pkg.getPackageDescriptor().isEmpty()
             || mayHavePinnedPackagePrivateOrProtectedItem(pkg)) {
           return pkg.getPackageDescriptor();
         }
@@ -386,9 +384,8 @@
       if (packageObfuscationMode.isRepackageClasses()) {
         return pkg.getPackageDescriptor().equals(newPackageDescriptor);
       } else if (packageObfuscationMode.isMinification()) {
-        // Always keep top-level classes since there packages can never be minified.
-        return pkg.getPackageDescriptor().equals("")
-            || proguardConfiguration.getKeepPackageNamesPatterns().matches(pkg)
+        // Always keep top-level classes since their packages can never be minified.
+        return pkg.getPackageDescriptor().isEmpty()
             || mayHavePinnedPackagePrivateOrProtectedItem(pkg);
       } else {
         assert packageObfuscationMode.isFlattenPackageHierarchy();
diff --git a/src/main/java/com/android/tools/r8/repackaging/RepackagingUtils.java b/src/main/java/com/android/tools/r8/repackaging/RepackagingUtils.java
new file mode 100644
index 0000000..d8e571d
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/repackaging/RepackagingUtils.java
@@ -0,0 +1,30 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.repackaging;
+
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.shaking.ProguardClassFilter;
+import com.android.tools.r8.utils.InternalOptions;
+
+public class RepackagingUtils {
+
+  public static boolean isPackageNameKept(DexProgramClass clazz, InternalOptions options) {
+    String packageDescriptor = clazz.getType().getPackageDescriptor();
+    if (packageDescriptor.isEmpty()) {
+      return true;
+    }
+    ProguardClassFilter keepPackageNamesPatterns =
+        options.getProguardConfiguration().getKeepPackageNamesPatterns();
+    if (keepPackageNamesPatterns.isEmpty()) {
+      return false;
+    }
+    if (keepPackageNamesPatterns.matches(
+        options.dexItemFactory().createType("L" + packageDescriptor + ";"))) {
+      return true;
+    }
+    return !options.isForceProguardCompatibilityEnabled()
+        && keepPackageNamesPatterns.matches(clazz.getType());
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index a8058ac..405060d 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -57,6 +57,7 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPIConverter;
 import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
 import com.android.tools.r8.naming.SeedMapper;
+import com.android.tools.r8.repackaging.RepackagingUtils;
 import com.android.tools.r8.shaking.KeepInfo.Joiner;
 import com.android.tools.r8.synthesis.CommittedItems;
 import com.android.tools.r8.utils.CollectionUtils;
@@ -1092,6 +1093,9 @@
     if (!keepInfo.getInfo(clazz).isRepackagingAllowed(clazz, options())) {
       return false;
     }
+    if (RepackagingUtils.isPackageNameKept(clazz, appView.options())) {
+      return false;
+    }
     SeedMapper applyMappingSeedMapper = appView.getApplyMappingSeedMapper();
     if (applyMappingSeedMapper != null && applyMappingSeedMapper.hasMapping(clazz.type)) {
       return false;
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java b/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java
index cc5d00b..5f5ad5f 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java
@@ -295,7 +295,7 @@
 
     @Override
     public boolean matches(DexType type) {
-      return classNames.stream().anyMatch(name -> name.matches(type));
+      return Iterables.any(classNames, name -> name.matches(type));
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
index 36bd397..b4e83f7 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
@@ -42,8 +42,8 @@
     private boolean verbose;
     private String renameSourceFileAttribute;
     private final List<String> keepAttributePatterns = new ArrayList<>();
-    private final ProguardPackageNameList.Builder keepPackageNamesPatterns =
-        ProguardPackageNameList.builder();
+    private final ProguardClassFilter.Builder keepPackageNamesPatterns =
+        ProguardClassFilter.builder();
     private final ProguardClassFilter.Builder dontWarnPatterns = ProguardClassFilter.builder();
     private final ProguardClassFilter.Builder dontNotePatterns = ProguardClassFilter.builder();
     protected final Set<ProguardConfigurationRule> rules = Sets.newLinkedHashSet();
@@ -193,8 +193,8 @@
       this.rules.add(rule);
     }
 
-    public void addKeepPackageNamesPattern(boolean isNegated, ProguardPackageMatcher pattern) {
-      keepPackageNamesPatterns.addPackageName(isNegated, pattern);
+    public void addKeepPackageNamesPattern(ProguardClassNameList pattern) {
+      keepPackageNamesPatterns.addPattern(pattern);
     }
 
     public void addDontWarnPattern(ProguardClassNameList pattern) {
@@ -395,7 +395,7 @@
   private final boolean verbose;
   private final String renameSourceFileAttribute;
   private final ProguardKeepAttributes keepAttributes;
-  private final ProguardPackageNameList keepPackageNamesPatterns;
+  private final ProguardClassFilter keepPackageNamesPatterns;
   private final ProguardClassFilter dontWarnPatterns;
   private final ProguardClassFilter dontNotePatterns;
   protected final ImmutableList<ProguardConfigurationRule> rules;
@@ -437,7 +437,7 @@
       boolean verbose,
       String renameSourceFileAttribute,
       ProguardKeepAttributes keepAttributes,
-      ProguardPackageNameList keepPackageNamesPatterns,
+      ProguardClassFilter keepPackageNamesPatterns,
       ProguardClassFilter dontWarnPatterns,
       ProguardClassFilter dontNotePatterns,
       Set<ProguardConfigurationRule> rules,
@@ -594,7 +594,7 @@
     return keepAttributes;
   }
 
-  public ProguardPackageNameList getKeepPackageNamesPatterns() {
+  public ProguardClassFilter getKeepPackageNamesPatterns() {
     return keepPackageNamesPatterns;
   }
 
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 526fc5f..803c78d 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -316,7 +316,7 @@
       } else if (acceptString("keepattributes")) {
         parseKeepAttributes();
       } else if (acceptString("keeppackagenames")) {
-        parsePackageFilter(configurationBuilder::addKeepPackageNamesPattern);
+        parseClassFilter(configurationBuilder::addKeepPackageNamesPattern);
       } else if (acceptString("keepparameternames")) {
         configurationBuilder.setKeepParameterNames(true, origin, getPosition(optionStart));
       } else if (acceptString("checkdiscard")) {
@@ -1146,6 +1146,8 @@
             builder.getModifiersBuilder().setAllowsObfuscation(true);
           } else if (acceptString("accessmodification")) {
             builder.getModifiersBuilder().setAllowsAccessModification(true);
+          } else if (acceptString("repackage")) {
+            builder.getModifiersBuilder().setAllowsRepackaging(true);
           } else if (options.isTestingOptionsEnabled()) {
             if (acceptString("annotationremoval")) {
               builder.getModifiersBuilder().setAllowsAnnotationRemoval(true);
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRuleModifiers.java b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRuleModifiers.java
index 7535a3e..a2619f7 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRuleModifiers.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRuleModifiers.java
@@ -3,11 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.shaking;
 
+import java.util.Objects;
+
 public class ProguardKeepRuleModifiers {
   public static class Builder {
 
     private boolean allowsAccessModification = false;
     private boolean allowsAnnotationRemoval = false;
+    private boolean allowsRepackaging = false;
     private boolean allowsShrinking = false;
     private boolean allowsOptimization = false;
     private boolean allowsObfuscation = false;
@@ -37,6 +40,14 @@
 
     public Builder setAllowsObfuscation(boolean allowsObfuscation) {
       this.allowsObfuscation = allowsObfuscation;
+      if (allowsObfuscation) {
+        this.allowsRepackaging = true;
+      }
+      return this;
+    }
+
+    public Builder setAllowsRepackaging(boolean allowsRepackaging) {
+      this.allowsRepackaging = allowsRepackaging;
       return this;
     }
 
@@ -48,6 +59,7 @@
       return new ProguardKeepRuleModifiers(
           allowsAccessModification,
           allowsAnnotationRemoval,
+          allowsRepackaging,
           allowsShrinking,
           allowsOptimization,
           allowsObfuscation,
@@ -57,6 +69,7 @@
 
   public final boolean allowsAccessModification;
   public final boolean allowsAnnotationRemoval;
+  public final boolean allowsRepackaging;
   public final boolean allowsShrinking;
   public final boolean allowsOptimization;
   public final boolean allowsObfuscation;
@@ -65,12 +78,14 @@
   private ProguardKeepRuleModifiers(
       boolean allowsAccessModification,
       boolean allowsAnnotationRemoval,
+      boolean allowsRepackaging,
       boolean allowsShrinking,
       boolean allowsOptimization,
       boolean allowsObfuscation,
       boolean includeDescriptorClasses) {
     this.allowsAccessModification = allowsAccessModification;
     this.allowsAnnotationRemoval = allowsAnnotationRemoval;
+    this.allowsRepackaging = allowsRepackaging;
     this.allowsShrinking = allowsShrinking;
     this.allowsOptimization = allowsOptimization;
     this.allowsObfuscation = allowsObfuscation;
@@ -87,6 +102,7 @@
   public boolean isBottom() {
     return allowsAccessModification
         && allowsAnnotationRemoval
+        && allowsRepackaging
         && allowsObfuscation
         && allowsOptimization
         && allowsShrinking
@@ -101,6 +117,7 @@
     ProguardKeepRuleModifiers that = (ProguardKeepRuleModifiers) o;
     return allowsAccessModification == that.allowsAccessModification
         && allowsAnnotationRemoval == that.allowsAnnotationRemoval
+        && allowsRepackaging == that.allowsRepackaging
         && allowsShrinking == that.allowsShrinking
         && allowsOptimization == that.allowsOptimization
         && allowsObfuscation == that.allowsObfuscation
@@ -109,12 +126,14 @@
 
   @Override
   public int hashCode() {
-    return (allowsAccessModification ? 1 : 0)
-        | (allowsAnnotationRemoval ? 2 : 0)
-        | (allowsShrinking ? 4 : 0)
-        | (allowsOptimization ? 8 : 0)
-        | (allowsObfuscation ? 16 : 0)
-        | (includeDescriptorClasses ? 32 : 0);
+    return Objects.hash(
+        allowsAccessModification,
+        allowsAnnotationRemoval,
+        allowsRepackaging,
+        allowsShrinking,
+        allowsOptimization,
+        allowsObfuscation,
+        includeDescriptorClasses);
   }
 
   @Override
@@ -122,6 +141,7 @@
     StringBuilder builder = new StringBuilder();
     appendWithComma(builder, allowsAccessModification, "allowaccessmodification");
     appendWithComma(builder, allowsAnnotationRemoval, "allowannotationremoval");
+    appendWithComma(builder, allowsRepackaging, "allowrepackaging");
     appendWithComma(builder, allowsObfuscation, "allowobfuscation");
     appendWithComma(builder, allowsShrinking, "allowshrinking");
     appendWithComma(builder, allowsOptimization, "allowoptimization");
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index 3b46564..4419a40 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -54,6 +54,7 @@
 import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
 import com.android.tools.r8.ir.optimize.membervaluepropagation.assume.AssumeInfo;
 import com.android.tools.r8.logging.Log;
+import com.android.tools.r8.repackaging.RepackagingUtils;
 import com.android.tools.r8.shaking.AnnotationMatchResult.AnnotationsIgnoredMatchResult;
 import com.android.tools.r8.shaking.AnnotationMatchResult.ConcreteAnnotationMatchResult;
 import com.android.tools.r8.shaking.AnnotationMatchResult.MatchedAnnotation;
@@ -1637,12 +1638,11 @@
       if (appView.options().isMinificationEnabled() && !modifiers.allowsObfuscation) {
         dependentMinimumKeepInfo
             .getOrCreateMinimumKeepInfoFor(preconditionEvent, item.getReference())
-            .disallowMinification()
-            .disallowRepackaging();
+            .disallowMinification();
         context.markAsUsed();
       }
 
-      if (appView.options().isRepackagingEnabled() && !modifiers.allowsObfuscation) {
+      if (appView.options().isRepackagingEnabled() && isRepackagingDisallowed(item, modifiers)) {
         dependentMinimumKeepInfo
             .getOrCreateMinimumKeepInfoFor(preconditionEvent, item.getReference())
             .disallowRepackaging();
@@ -1676,6 +1676,14 @@
       }
     }
 
+    private boolean isRepackagingDisallowed(
+        ProgramDefinition item, ProguardKeepRuleModifiers modifiers) {
+      if (!modifiers.allowsRepackaging) {
+        return true;
+      }
+      return RepackagingUtils.isPackageNameKept(item.getContextClass(), options);
+    }
+
     private void evaluateIdentifierNameStringRule(
         Definition item, ProguardConfigurationRule context, ProguardIfRule ifRule) {
       // Main dex rules should not contain -identifiernamestring rules.
diff --git a/src/test/java/com/android/tools/r8/naming/KeepPackageNamesTest.java b/src/test/java/com/android/tools/r8/naming/KeepPackageNamesTest.java
index bb73c3f..5eb7783 100644
--- a/src/test/java/com/android/tools/r8/naming/KeepPackageNamesTest.java
+++ b/src/test/java/com/android/tools/r8/naming/KeepPackageNamesTest.java
@@ -99,4 +99,14 @@
         .compile()
         .inspect(config::inspect);
   }
+
+  @Test
+  public void testR8Compat() throws Exception {
+    testForR8Compat(Backend.DEX)
+        .addProgramClasses(CLASSES)
+        .addKeepAllClassesRuleWithAllowObfuscation()
+        .addKeepRules(config.getKeepRule())
+        .compile()
+        .inspect(config::inspect);
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/naming/keeppackagenames/KeepPackageNameRootTest.java b/src/test/java/com/android/tools/r8/naming/keeppackagenames/KeepPackageNameRootTest.java
index 309ab55..e7c14ff 100644
--- a/src/test/java/com/android/tools/r8/naming/keeppackagenames/KeepPackageNameRootTest.java
+++ b/src/test/java/com/android/tools/r8/naming/keeppackagenames/KeepPackageNameRootTest.java
@@ -9,7 +9,6 @@
 
 import com.android.tools.r8.ProguardVersion;
 import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestCompileResult;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.TestShrinkerBuilder;
@@ -34,22 +33,22 @@
 
   @Test
   public void testR8Compat() throws Exception {
-    run(testForR8Compat(Backend.CF));
+    run(testForR8Compat(Backend.CF), false);
   }
 
   @Test
   public void testR8Full() throws Exception {
-    run(testForR8(Backend.CF));
+    run(testForR8(Backend.CF), true);
   }
 
   @Test
   public void testR8PG() throws Exception {
-    run(testForProguard(ProguardVersion.V7_0_0).addKeepRules("-dontwarn"));
+    run(testForProguard(ProguardVersion.V7_0_0).addKeepRules("-dontwarn"), false);
   }
 
-  private TestCompileResult<?, ?> run(TestShrinkerBuilder<?, ?, ?, ?, ?> testBuilder)
+  private void run(TestShrinkerBuilder<?, ?, ?, ?, ?> testBuilder, boolean isFullMode)
       throws Exception {
-    return testBuilder
+    testBuilder
         .addProgramClassFileData(
             transformer(Main.class)
                 .setClassDescriptor("Lfoo/Main;")
@@ -64,7 +63,11 @@
               assertEquals(1, inspector.allClasses().size());
               inspector.forAllClasses(
                   clazz -> {
-                    assertNotEquals("foo", clazz.getDexProgramClass().getType().getPackageName());
+                    if (isFullMode) {
+                      assertEquals("foo", clazz.getDexProgramClass().getType().getPackageName());
+                    } else {
+                      assertNotEquals("foo", clazz.getDexProgramClass().getType().getPackageName());
+                    }
                   });
             });
   }
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageAllowRepackagingTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageAllowRepackagingTest.java
new file mode 100644
index 0000000..686be1d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageAllowRepackagingTest.java
@@ -0,0 +1,64 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.repackage;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.TestParameters;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class RepackageAllowRepackagingTest extends RepackageTestBase {
+
+  public RepackageAllowRepackagingTest(
+      String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
+    super(flattenPackageHierarchyOrRepackageClasses, parameters);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .setMinApi(parameters.getApiLevel())
+        .addKeepMainRule(Main.class)
+        .apply(this::configureRepackaging)
+        .addKeepRules(
+            "-keep,allowrepackage class " + typeName(ShouldStayInPackage.class) + " { *; }")
+        .addKeepRules(
+            "-keep,allowrepackage class " + typeName(ShouldBeRepackaged.class) + " { *; }")
+        .compile()
+        .inspect(
+            inspector -> {
+              assertThat(ShouldStayInPackage.class, isNotRepackaged(inspector));
+              assertThat(ShouldBeRepackaged.class, isRepackaged(inspector));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("ShouldStayInPackage::foo", "ShouldBeRepackaged::bar");
+  }
+
+  public static class ShouldStayInPackage {
+
+    static void foo() {
+      System.out.println("ShouldStayInPackage::foo");
+    }
+  }
+
+  public static class ShouldBeRepackaged {
+
+    public static void bar() {
+      System.out.println("ShouldBeRepackaged::bar");
+    }
+  }
+
+  public static class Main {
+
+    public static void main(String[] args) {
+      ShouldStayInPackage.foo();
+      ShouldBeRepackaged.bar();
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageKeepPackageNameTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageKeepPackageNameTest.java
new file mode 100644
index 0000000..bcffb5f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageKeepPackageNameTest.java
@@ -0,0 +1,73 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.repackage;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.R8TestCompileResult;
+import com.android.tools.r8.TestParameters;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class RepackageKeepPackageNameTest extends RepackageTestBase {
+
+  public RepackageKeepPackageNameTest(
+      String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
+    super(flattenPackageHierarchyOrRepackageClasses, parameters);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    R8TestCompileResult compileLib =
+        testForR8(parameters.getBackend())
+            .addInnerClasses(getClass())
+            .setMinApi(parameters.getApiLevel())
+            .addKeepClassAndMembersRulesWithAllowObfuscation(
+                ShouldStayInPackage.class, ShouldBeRepackaged.class)
+            .addKeepPackageNamesRule(typeName(ShouldStayInPackage.class))
+            .apply(this::configureRepackaging)
+            .compile()
+            .inspect(
+                inspector -> {
+                  assertThat(ShouldStayInPackage.class, isNotRepackaged(inspector));
+                  assertThat(ShouldBeRepackaged.class, isRepackaged(inspector));
+                });
+
+    testForR8(parameters.getBackend())
+        .addProgramClasses(Runner.class)
+        .addClasspathClasses(ShouldStayInPackage.class, ShouldBeRepackaged.class)
+        .addApplyMapping(compileLib.getProguardMap())
+        .addKeepMainRule(Runner.class)
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .addRunClasspathFiles(compileLib.writeToZip())
+        .run(parameters.getRuntime(), Runner.class)
+        .assertSuccessWithOutputLines("ShouldStayInPackage::foo", "ShouldBeRepackaged::bar");
+  }
+
+  public static class ShouldStayInPackage {
+
+    static void foo() {
+      System.out.println("ShouldStayInPackage::foo");
+    }
+  }
+
+  public static class ShouldBeRepackaged {
+
+    public static void bar() {
+      System.out.println("ShouldBeRepackaged::bar");
+    }
+  }
+
+  public static class Runner {
+
+    public static void main(String[] args) {
+      ShouldStayInPackage.foo();
+      ShouldBeRepackaged.bar();
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageWithKeepPackagePrivateTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageWithKeepPackagePrivateTest.java
index 8020e78..6f79b12 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageWithKeepPackagePrivateTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageWithKeepPackagePrivateTest.java
@@ -76,8 +76,8 @@
   }
 
   private void inspect(CodeInspector inspector) {
-    assertThat(A.class, isRepackagedIf(inspector, allowAccessModification));
-    assertThat(B.class, isRepackagedIf(inspector, allowAccessModification));
+    assertThat(A.class, isNotRepackaged(inspector));
+    assertThat(B.class, isNotRepackaged(inspector));
   }
 
   public static class TestClass {
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index 2b8d68b..8149c5b 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -1513,48 +1513,30 @@
     testKeepattributes(expected, config);
   }
 
-  private void testKeeppackagenames(ProguardPackageNameList expected, String config) {
+  private void testKeeppackagenames(String config) {
     ProguardConfigurationParser parser =
         new ProguardConfigurationParser(new DexItemFactory(), reporter);
     parser.parse(createConfigurationForTesting(ImmutableList.of(config)));
     verifyParserEndsCleanly();
-    assertEquals(expected, parser.getConfigRawForTesting().getKeepPackageNamesPatterns());
   }
 
   @Test
   public void parseKeeppackagenames() {
-    ProguardPackageNameList xxxYYY =
-        ProguardPackageNameList.builder()
-            .addPackageName(false, new ProguardPackageMatcher("xxx"))
-            .addPackageName(false, new ProguardPackageMatcher("yyy"))
-            .build();
-    testKeeppackagenames(xxxYYY, "-keeppackagenames xxx,yyy");
-    testKeeppackagenames(xxxYYY, "-keeppackagenames xxx, yyy");
-    testKeeppackagenames(xxxYYY, "-keeppackagenames xxx ,yyy");
-    testKeeppackagenames(xxxYYY, "-keeppackagenames xxx   ,   yyy");
-    testKeeppackagenames(xxxYYY, "-keeppackagenames       xxx   ,   yyy     ");
-    testKeeppackagenames(xxxYYY, "-keeppackagenames       xxx   ,   yyy     \n");
-    testKeeppackagenames(xxxYYY, "-keeppackagenames \"xxx\",\"yyy\"");
+    testKeeppackagenames("-keeppackagenames xxx,yyy");
+    testKeeppackagenames("-keeppackagenames xxx, yyy");
+    testKeeppackagenames("-keeppackagenames xxx ,yyy");
+    testKeeppackagenames("-keeppackagenames xxx   ,   yyy");
+    testKeeppackagenames("-keeppackagenames       xxx   ,   yyy     ");
+    testKeeppackagenames("-keeppackagenames       xxx   ,   yyy     \n");
+    testKeeppackagenames("-keeppackagenames \"xxx\",\"yyy\"");
 
     testKeeppackagenames(
-        ProguardPackageNameList.builder()
-            .addPackageName(false, new ProguardPackageMatcher("com.**"))
-            .addPackageName(false, new ProguardPackageMatcher("org.*"))
-            .build(),
         "-keeppackagenames com.**, org.*");
 
     testKeeppackagenames(
-        ProguardPackageNameList.builder()
-            .addPackageName(false, new ProguardPackageMatcher("c?m.**"))
-            .addPackageName(false, new ProguardPackageMatcher("?r?.*"))
-            .build(),
         "-keeppackagenames c?m.**, ?r?.*");
 
     testKeeppackagenames(
-        ProguardPackageNameList.builder()
-            .addPackageName(true, new ProguardPackageMatcher("c?m.**"))
-            .addPackageName(true, new ProguardPackageMatcher("?r?.*"))
-            .build(),
         "-keeppackagenames !c?m.**, !?r?.*");
   }