Update repackage with keepclassmembers to include PG result

Bug: b/250671873
Change-Id: Id338900a0e261bbb2eb8da6820407b0b6b04171e
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageKeepClassMembersTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageKeepClassMembersTest.java
index a49759f..57f650e 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageKeepClassMembersTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageKeepClassMembersTest.java
@@ -6,15 +6,15 @@
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.ProguardVersion;
 import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.repackage.testclasses.RepackageForKeepClassMembers;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import java.util.Objects;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -22,64 +22,57 @@
 @RunWith(Parameterized.class)
 public class RepackageKeepClassMembersTest extends RepackageTestBase {
 
+  private final String EXPECTED = "Could not find " + typeName(RepackageForKeepClassMembers.class);
+
   public RepackageKeepClassMembersTest(
       String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
     super(flattenPackageHierarchyOrRepackageClasses, parameters);
   }
 
   @Test
-  public void testR8() throws Exception {
-    testForR8(parameters.getBackend())
-        .addInnerClasses(getClass())
+  public void testPG() throws Exception {
+    assumeTrue(parameters.isOrSimulateNoneRuntime());
+    testForProguard(ProguardVersion.V7_0_0)
+        .addProgramClasses(RepackageForKeepClassMembers.class, Main.class)
         .setMinApi(parameters.getApiLevel())
         .apply(this::configureRepackaging)
         .addKeepRules(
-            "-keepclassmembers class * extends " + typeName(Base.class) + " { <fields>; }")
+            "-keepclassmembers class " + typeName(RepackageForKeepClassMembers.class) + " { *; }")
+        .addKeepMainRule(Main.class)
+        .addDontWarn(RepackageKeepClassMembersTest.class, NeverClassInline.class)
+        .run(parameters.getRuntime(), Main.class, typeName(RepackageForKeepClassMembers.class))
+        .inspect(this::inspect)
+        .assertSuccessWithOutputLines(EXPECTED);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClasses(RepackageForKeepClassMembers.class, Main.class)
+        .setMinApi(parameters.getApiLevel())
+        .apply(this::configureRepackaging)
+        .addKeepRules(
+            "-keepclassmembers class " + typeName(RepackageForKeepClassMembers.class) + " { *; }")
         .addKeepMainRule(Main.class)
         .enableNeverClassInliningAnnotations()
-        .enableInliningAnnotations()
-        .run(parameters.getRuntime(), Main.class, typeName(Sub.class))
+        .run(parameters.getRuntime(), Main.class, typeName(RepackageForKeepClassMembers.class))
         .inspect(this::inspect)
-        // TODOD(b/250671873): Should not repackage class.
-        .assertSuccessWithOutputLines("Could not find " + typeName(Sub.class));
+        .assertSuccessWithOutputLines(EXPECTED);
   }
 
   private void inspect(CodeInspector inspector) {
-    ClassSubject clazz = inspector.clazz(Sub.class);
+    ClassSubject clazz = inspector.clazz(RepackageForKeepClassMembers.class);
     assertThat(clazz, isPresent());
-    // TODOD(b/250671873): Should not repackage class.
-    assertThat(Sub.class, isRepackaged(inspector));
+    assertThat(RepackageForKeepClassMembers.class, isRepackaged(inspector));
     assertThat(clazz.uniqueFieldWithOriginalName("hashCodeCache"), isPresentAndNotRenamed());
-    assertThat(clazz.uniqueMethodWithOriginalName("calculateHashCode"), isPresentAndRenamed());
-  }
-
-  public static class Base {}
-
-  @NeverClassInline
-  public static class Sub extends Base {
-
-    public int hashCodeCache;
-
-    @NeverInline
-    public int calculateHashCode() {
-      if (hashCodeCache != -1) {
-        return hashCodeCache;
-      }
-      hashCodeCache = Objects.hash(Sub.class);
-      return hashCodeCache;
-    }
-
-    @Override
-    public int hashCode() {
-      return calculateHashCode();
-    }
+    assertThat(clazz.uniqueMethodWithOriginalName("calculateHashCode"), isPresentAndNotRenamed());
   }
 
   public static class Main {
 
     public static void main(String[] args) {
       if (System.currentTimeMillis() == 0) {
-        System.out.println(new Sub().hashCode());
+        System.out.println(new RepackageForKeepClassMembers().hashCode());
       }
       try {
         Class<?> subClass = Class.forName(args[0]);
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageProtectedInSamePackageTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageProtectedInSamePackageTest.java
index a208857..a6c9ea3 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageProtectedInSamePackageTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageProtectedInSamePackageTest.java
@@ -5,15 +5,18 @@
 package com.android.tools.r8.repackage;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.ProguardVersion;
 import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.repackage.testclasses.RepackageForKeepClassMembers;
+import com.android.tools.r8.transformers.ClassFileTransformer.FieldPredicate;
+import com.android.tools.r8.transformers.ClassFileTransformer.MethodPredicate;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import java.util.Objects;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -22,66 +25,82 @@
 @RunWith(Parameterized.class)
 public class RepackageProtectedInSamePackageTest extends RepackageTestBase {
 
+  private final String EXPECTED = "Hello World!";
+
   public RepackageProtectedInSamePackageTest(
       String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
     super(flattenPackageHierarchyOrRepackageClasses, parameters);
   }
 
   @Test
-  public void testR8() throws Exception {
-    testForR8(parameters.getBackend())
-        .addInnerClasses(getClass())
+  public void testPG() throws Exception {
+    assumeTrue(parameters.isOrSimulateNoneRuntime());
+    testForProguard(ProguardVersion.V7_0_0)
+        .addProgramClasses(Main.class)
+        .addProgramClassFileData(getRepackageForKeepClassMembersWithProtectedAccess())
         .setMinApi(parameters.getApiLevel())
         .apply(this::configureRepackaging)
         .addKeepRules(
-            "-keepclassmembers,allowobfuscation class * extends "
-                + typeName(Base.class)
-                + " { <fields>; }")
+            "-keepclassmembers class " + typeName(RepackageForKeepClassMembers.class) + " { *; }")
+        .addKeepMainRule(Main.class)
+        .addDontWarn(RepackageProtectedInSamePackageTest.class, NeverClassInline.class)
+        .run(parameters.getRuntime(), Main.class, typeName(RepackageForKeepClassMembers.class))
+        .inspect(inspector -> inspect(inspector, true))
+        .assertSuccessWithOutputLines(EXPECTED);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClasses(Main.class)
+        .addProgramClassFileData(getRepackageForKeepClassMembersWithProtectedAccess())
+        .setMinApi(parameters.getApiLevel())
+        .apply(this::configureRepackaging)
+        .addKeepRules(
+            "-keepclassmembers class " + typeName(RepackageForKeepClassMembers.class) + " { *; }")
         .addKeepMainRule(Main.class)
         .enableNeverClassInliningAnnotations()
-        .enableInliningAnnotations()
         .run(parameters.getRuntime(), Main.class)
-        .inspect(this::inspect)
-        .assertSuccessWithOutputLines("Hello World!");
+        .inspect(inspector -> inspect(inspector, false))
+        .assertSuccessWithOutputLines(EXPECTED);
   }
 
-  private void inspect(CodeInspector inspector) {
+  private byte[] getRepackageForKeepClassMembersWithProtectedAccess() throws Exception {
+    return transformer(RepackageForKeepClassMembers.class)
+        .setAccessFlags(
+            MethodPredicate.onName("calculateHashCode"),
+            methodAccessFlags -> {
+              methodAccessFlags.unsetPublic();
+              methodAccessFlags.setProtected();
+            })
+        .setAccessFlags(
+            FieldPredicate.onName("hashCodeCache"),
+            fieldAccessFlags -> {
+              fieldAccessFlags.unsetPublic();
+              fieldAccessFlags.setProtected();
+            })
+        .transform();
+  }
+
+  private void inspect(CodeInspector inspector, boolean isProguard) {
+    ClassSubject clazz = inspector.clazz(RepackageForKeepClassMembers.class);
+    assertThat(clazz, isPresent());
     // TODO(b/250671873): We should be able to repackage the Sub class since the only reference
     //  to Sub.class is in the same package and we have allowobfuscation.
-    ClassSubject clazz = inspector.clazz(Sub.class);
-    assertThat(clazz, isPresent());
-    assertThat(Sub.class, isNotRepackaged(inspector));
-    assertThat(clazz.uniqueFieldWithOriginalName("hashCodeCache"), isPresentAndRenamed());
-    assertThat(clazz.uniqueMethodWithOriginalName("calculateHashCode"), isPresentAndRenamed());
-  }
-
-  public static class Base {}
-
-  @NeverClassInline
-  public static class Sub extends Base {
-
-    protected int hashCodeCache;
-
-    @NeverInline
-    protected int calculateHashCode() {
-      if (hashCodeCache != -1) {
-        return hashCodeCache;
-      }
-      hashCodeCache = Objects.hash(Sub.class);
-      return hashCodeCache;
+    if (isProguard) {
+      assertThat(RepackageForKeepClassMembers.class, isRepackaged(inspector));
+    } else {
+      assertThat(RepackageForKeepClassMembers.class, isNotRepackaged(inspector));
     }
-
-    @Override
-    public int hashCode() {
-      return calculateHashCode();
-    }
+    assertThat(clazz.uniqueFieldWithOriginalName("hashCodeCache"), isPresentAndNotRenamed());
+    assertThat(clazz.uniqueMethodWithOriginalName("calculateHashCode"), isPresentAndNotRenamed());
   }
 
   public static class Main {
 
     public static void main(String[] args) {
       if (System.currentTimeMillis() == 0) {
-        System.out.println(new Sub().hashCode());
+        System.out.println(new RepackageForKeepClassMembers().hashCode());
       }
       System.out.println("Hello World!");
     }
diff --git a/src/test/java/com/android/tools/r8/repackage/testclasses/RepackageForKeepClassMembers.java b/src/test/java/com/android/tools/r8/repackage/testclasses/RepackageForKeepClassMembers.java
new file mode 100644
index 0000000..48781e5
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/repackage/testclasses/RepackageForKeepClassMembers.java
@@ -0,0 +1,27 @@
+// 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.testclasses;
+
+import com.android.tools.r8.NeverClassInline;
+import java.util.Objects;
+
+@NeverClassInline
+public class RepackageForKeepClassMembers {
+
+  public int hashCodeCache;
+
+  public int calculateHashCode() {
+    if (hashCodeCache != -1) {
+      return hashCodeCache;
+    }
+    hashCodeCache = Objects.hash(RepackageForKeepClassMembers.class);
+    return hashCodeCache;
+  }
+
+  @Override
+  public int hashCode() {
+    return calculateHashCode();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java b/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
index 9dc6120..47c49fc 100644
--- a/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
+++ b/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
@@ -550,6 +550,14 @@
 
   private ClassFileTransformer setAccessFlags(
       FieldReference fieldReference, Consumer<FieldAccessFlags> setter) {
+    return setAccessFlags(
+        FieldPredicate.onNameAndDescriptor(
+            fieldReference.getFieldName(), fieldReference.getFieldType().getDescriptor()),
+        setter);
+  }
+
+  public ClassFileTransformer setAccessFlags(
+      FieldPredicate predicate, Consumer<FieldAccessFlags> setter) {
     return addClassTransformer(
         new ClassTransformer() {
 
@@ -557,8 +565,7 @@
           public FieldVisitor visitField(
               int access, String name, String descriptor, String signature, Object value) {
             FieldAccessFlags accessFlags = FieldAccessFlags.fromCfAccessFlags(access);
-            if (name.equals(fieldReference.getFieldName())
-                && descriptor.equals(fieldReference.getFieldType().getDescriptor())) {
+            if (predicate.test(access, name, descriptor, signature, value)) {
               setter.accept(accessFlags);
             }
             return super.visitField(
@@ -631,7 +638,7 @@
       return (access, name, descriptor, signature, value) -> true;
     }
 
-    static FieldPredicate onNameAndSignature(String name, String descriptor) {
+    static FieldPredicate onNameAndDescriptor(String name, String descriptor) {
       return (access, otherName, otherDescriptor, signature, value) ->
           name.equals(otherName) && descriptor.equals(otherDescriptor);
     }