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);
}