Prune signature attribute if not kept and not in fullmode
Bug: 170077516
Change-Id: I9c892f2624b2db5e494fc1f20865fdbeafad6775
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
index 46e4629..fc6cb56 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InnerClassAttribute;
+import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import java.util.IdentityHashMap;
@@ -27,6 +28,7 @@
public class AnnotationRemover {
private final AppView<AppInfoWithLiveness> appView;
+ private final InternalOptions options;
private final Set<DexAnnotation> annotationsToRetain;
private final Set<DexType> classesToRetainInnerClassAttributeFor;
private final ProguardKeepAttributes keep;
@@ -38,6 +40,7 @@
Set<DexAnnotation> annotationsToRetain,
Set<DexType> removedClasses) {
this.appView = appView;
+ this.options = appView.options();
this.annotationsToRetain = annotationsToRetain;
this.classesToRetainInnerClassAttributeFor = classesToRetainInnerClassAttributeFor;
this.keep = appView.options().getProguardConfiguration().getKeepAttributes();
@@ -187,25 +190,31 @@
stripAttributes(clazz);
clazz.setAnnotations(
clazz.annotations().rewrite(annotation -> rewriteAnnotation(clazz, annotation)));
- clazz.forEachMethod(this::processMethod);
- clazz.forEachField(this::processField);
+ clazz.forEachMethod(method -> processMethod(method, clazz));
+ clazz.forEachField(field -> processField(field, clazz));
}
}
- private void processMethod(DexEncodedMethod method) {
+ private void processMethod(DexEncodedMethod method, DexProgramClass clazz) {
method.setAnnotations(
method.annotations().rewrite(annotation -> rewriteAnnotation(method, annotation)));
method.parameterAnnotationsList =
method.parameterAnnotationsList.keepIf(this::filterParameterAnnotations);
- if (!keep.signature) {
+ if (appView
+ .getKeepInfo()
+ .getMethodInfo(method, clazz)
+ .isAllowSignatureAttributeRemovalAllowed(options)) {
method.clearGenericSignature();
}
}
- private void processField(DexEncodedField field) {
+ private void processField(DexEncodedField field, DexProgramClass clazz) {
field.setAnnotations(
field.annotations().rewrite(annotation -> rewriteAnnotation(field, annotation)));
- if (!keep.signature) {
+ if (appView
+ .getKeepInfo()
+ .getFieldInfo(field, clazz)
+ .isAllowSignatureAttributeRemovalAllowed(options)) {
field.clearGenericSignature();
}
}
@@ -321,8 +330,10 @@
clazz.clearEnclosingMethodAttribute();
clazz.clearInnerClasses();
}
- // TODO(b/170077516): Prune attributes.
- if (!keep.signature) {
+ if (appView
+ .getKeepInfo()
+ .getClassInfo(clazz)
+ .isAllowSignatureAttributeRemovalAllowed(options)) {
clazz.clearClassSignature();
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/gson.cfg b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/gson.cfg
index da7bcba..e7560e1f 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/gson.cfg
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/gson.cfg
@@ -14,11 +14,11 @@
-dontwarn sun.misc.Unsafe
# Application classes that will be serialized/deserialized over Gson
--keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClasses$Data { <fields>; }
--keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClasses$NullableConcurrentHashMap
--keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClasses$NullableHashMap
--keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClasses$NullableMap
--keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClasses$NullableConcurrentMap
+-keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClass$Data { <fields>; }
+-keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClass$NullableConcurrentHashMap
+-keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClass$NullableHashMap
+-keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClass$NullableMap
+-keep class com.android.tools.r8.desugar.desugaredlibrary.gson.AllMapsTestClass$NullableConcurrentMap
-keep class com.android.tools.r8.desugar.desugaredlibrary.gson.OptionalTestClass$Data { <fields>; }
# Prevent R8 from stripping interface information from TypeAdapter, TypeAdapterFactory,
@@ -28,6 +28,9 @@
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
+# Prevent R8 from removing the generic signature of TypeToken
+-keep,allowobfuscation class * extends com.google.gson.reflect.TypeToken
+
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
diff --git a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
index 6ababf1..d56503c 100644
--- a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
+++ b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
@@ -63,7 +63,7 @@
@Test
public void test() throws Exception {
R8TestCompileResult compileResult =
- testForR8(parameters.getBackend())
+ testForR8Compat(parameters.getBackend())
.addProgramClasses(Main.class, Service.class, Foo.class, FooImpl.class)
.addKeepMainRule(Main.class)
.addKeepAttributes(
diff --git a/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java b/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
index e945182..65445a7 100644
--- a/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
@@ -85,6 +85,7 @@
.addKeepAttributes(ProguardKeepAttributes.SIGNATURE)
.addKeepAttributes(ProguardKeepAttributes.INNER_CLASSES)
.addKeepAttributes(ProguardKeepAttributes.ENCLOSING_METHOD)
+ .addKeepAllClassesRuleWithAllowObfuscation()
.addKeepMainRule(Main.class)
.addProgramClasses(Main.class)
.addProgramClassesAndInnerClasses(A.class, B.class, CY.class, CYY.class)
diff --git a/src/test/java/com/android/tools/r8/shaking/attributes/ClassSignaturesTest.java b/src/test/java/com/android/tools/r8/shaking/attributes/ClassSignaturesTest.java
deleted file mode 100644
index 7ca532d..0000000
--- a/src/test/java/com/android/tools/r8/shaking/attributes/ClassSignaturesTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2020, 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.shaking.attributes;
-
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-
-import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.shaking.ProguardKeepAttributes;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import java.util.Iterator;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class ClassSignaturesTest extends TestBase {
-
- private final TestParameters parameters;
- private final String EXPECTED = "Hello World!";
-
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
- }
-
- public ClassSignaturesTest(TestParameters parameters) {
- this.parameters = parameters;
- }
-
- @Test
- public void testRuntime() throws Exception {
- testForRuntime(parameters)
- .addProgramClasses(A.class, Main.class)
- .run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutputLines(EXPECTED)
- .inspect(this::inspect);
- }
-
- @Test
- public void testR8() throws Exception {
- testForR8(parameters.getBackend())
- .addProgramClasses(A.class, Main.class)
- .addKeepMainRule(Main.class)
- .setMinApi(parameters.getApiLevel())
- .enableNeverClassInliningAnnotations()
- .enableInliningAnnotations()
- .addKeepAttributes(
- ProguardKeepAttributes.SIGNATURE,
- ProguardKeepAttributes.INNER_CLASSES,
- ProguardKeepAttributes.ENCLOSING_METHOD)
- .run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutputLines(EXPECTED)
- .inspect(this::inspect);
- }
-
- private void inspect(CodeInspector inspector) {
- ClassSubject aClass = inspector.clazz(A.class);
- assertThat(aClass, isPresent());
- assertEquals(
- "Ljava/lang/Object;Ljava/lang/Iterable<"
- + "Lcom/android/tools/r8/shaking/attributes/ClassSignaturesTest$Main;>;",
- aClass.getFinalSignatureAttribute());
- }
-
- @NeverClassInline
- public static class A implements Iterable<Main> {
-
- @Override
- @NeverInline
- public Iterator<Main> iterator() {
- throw new RuntimeException("FooBar");
- }
- }
-
- public static class Main {
-
- public static void main(String[] args) {
- try {
- new A().iterator();
- } catch (RuntimeException e) {
- if (!e.getMessage().contains("FooBar")) {
- throw e;
- }
- System.out.println("Hello World!");
- }
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/shaking/attributes/KeepSignatureTest.java b/src/test/java/com/android/tools/r8/shaking/attributes/KeepSignatureTest.java
index b441e6b..05f9731 100644
--- a/src/test/java/com/android/tools/r8/shaking/attributes/KeepSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/attributes/KeepSignatureTest.java
@@ -56,8 +56,7 @@
@Test
public void testKeptClassFieldAndMethodFull() throws Exception {
- // TODO(b/170077516): The below should pass in false.
- runTest(testForR8(parameters.getBackend()), true);
+ runTest(testForR8(parameters.getBackend()), false);
}
@Test