Version 1.4.72
Cherry pick: Process annotations on live fields
CL: https://r8-review.googlesource.com/c/r8/+/35721
Cherry pick: Fix typo in AnnotationsOfFieldsTest
CL: https://r8-review.googlesource.com/c/r8/+/35780
Cherry pick: Ensure app services are always available to Enqueuer
CL: https://r8-review.googlesource.com/c/r8/+/35742
Cherry pick: Set AppServices info in tests before using Enqueuer
CL: https://r8-review.googlesource.com/c/r8/+/35782
Bug: 126597509, 128387933
Change-Id: I6c737e00318dd6d0cee4c2c2a3f2f507aab3df41
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index aafe941..da47fe2 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexReference;
@@ -47,6 +48,8 @@
AppView<? extends AppInfoWithSubtyping> appView =
new AppView<>(
new AppInfoWithSubtyping(application), GraphLense.getIdentityLense(), options);
+ appView.setAppServices(AppServices.builder(appView).build());
+
RootSet mainDexRootSet =
new RootSetBuilder(appView, application, options.mainDexKeepRules, options).run(executor);
diff --git a/src/main/java/com/android/tools/r8/PrintSeeds.java b/src/main/java/com/android/tools/r8/PrintSeeds.java
index 475ca70..060045a 100644
--- a/src/main/java/com/android/tools/r8/PrintSeeds.java
+++ b/src/main/java/com/android/tools/r8/PrintSeeds.java
@@ -5,6 +5,7 @@
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.GraphLense;
@@ -86,6 +87,7 @@
AppView<? extends AppInfoWithSubtyping> appView =
new AppView<>(
new AppInfoWithSubtyping(application), GraphLense.getIdentityLense(), options);
+ appView.setAppServices(AppServices.builder(appView).build());
RootSet rootSet =
new RootSetBuilder(
appView, application, options.getProguardConfiguration().getRules(), options)
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 2f7ec60..574be8d 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "1.4.71";
+ public static final String LABEL = "1.4.72";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 2412662..37a83bf 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -307,6 +307,7 @@
GraphConsumer keptGraphConsumer,
boolean forceProguardCompatibility,
ProguardConfiguration.Builder compatibility) {
+ assert appView.appServices() != null;
this.appInfo = appView.appInfo();
this.appView = appView;
this.compatibility = compatibility;
@@ -1146,6 +1147,7 @@
encodedField.field);
}
}
+ processAnnotations(encodedField, encodedField.annotations.annotations);
liveFields.add(encodedField, reason);
collectProguardCompatibilityRule(reason);
// Add all dependent members to the workqueue.
@@ -1159,6 +1161,7 @@
if (Log.ENABLED) {
Log.verbose(getClass(), "Adding instance field `%s` to live set.", field.field);
}
+ processAnnotations(field, field.annotations.annotations);
liveFields.add(field, reason);
collectProguardCompatibilityRule(reason);
// Add all dependent members to the workqueue.
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTestBase.java b/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTestBase.java
index 58c4237..1ae55a5 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTestBase.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.GraphLense;
@@ -34,6 +35,7 @@
AppView<AppInfoWithSubtyping> appView =
new AppView<>(
new AppInfoWithSubtyping(dexApplication), GraphLense.getIdentityLense(), TEST_OPTIONS);
+ appView.setAppServices(AppServices.builder(appView).build());
ExecutorService executorService = ThreadUtils.getExecutorService(TEST_OPTIONS);
RootSet rootSet =
new RootSetBuilder(
diff --git a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
index 4dcb52f..642864f 100644
--- a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
@@ -5,12 +5,12 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.shaking.Enqueuer;
-import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.RootSetBuilder;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
@@ -71,17 +71,15 @@
AppView<AppInfoWithSubtyping> appView =
new AppView<>(new AppInfoWithSubtyping(program), GraphLense.getIdentityLense(), options);
+ appView.setAppServices(AppServices.builder(appView).build());
+
RootSet rootSet =
new RootSetBuilder(appView, program, configuration.getRules(), options).run(executor);
Enqueuer enqueuer = new Enqueuer(appView, options, null, options.forceProguardCompatibility);
- AppInfoWithLiveness appInfo =
- enqueuer.traceApplication(rootSet, configuration.getDontWarnPatterns(), executor, timing);
- return new Minifier(
- new AppView<>(appInfo, GraphLense.getIdentityLense(), options),
- rootSet,
- Collections.emptySet())
- .run(timing);
+ appView.setAppInfo(
+ enqueuer.traceApplication(rootSet, configuration.getDontWarnPatterns(), executor, timing));
+ return new Minifier(appView.withLiveness(), rootSet, Collections.emptySet()).run(timing);
}
static <T> Collection<Object[]> createTests(List<String> tests, Map<String, T> inspections) {
diff --git a/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java b/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
index 7ec1613..7f1ec89 100644
--- a/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.AsmTestBase;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -107,7 +108,7 @@
AppView<? extends AppInfoWithSubtyping> appView =
new AppView<>(
new AppInfoWithSubtyping(application), GraphLense.getIdentityLense(), options);
-
+ appView.setAppServices(AppServices.builder(appView).build());
ExecutorService executor = Executors.newSingleThreadExecutor();
RootSet rootSet =
new RootSetBuilder(
diff --git a/src/test/java/com/android/tools/r8/shaking/annotations/AnnotationsOnFieldsTest.java b/src/test/java/com/android/tools/r8/shaking/annotations/AnnotationsOnFieldsTest.java
new file mode 100644
index 0000000..03ace58
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/annotations/AnnotationsOnFieldsTest.java
@@ -0,0 +1,106 @@
+package com.android.tools.r8.shaking.annotations;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.FieldSubject;
+import com.google.common.collect.ImmutableList;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class AnnotationsOnFieldsTest extends TestBase {
+
+ private final Backend backend;
+
+ @Parameterized.Parameters(name = "Backend: {0}")
+ public static Backend[] data() {
+ return Backend.values();
+ }
+
+ public AnnotationsOnFieldsTest(Backend backend) {
+ this.backend = backend;
+ }
+
+ List<Class<?>> CLASSES =
+ ImmutableList.of(
+ FieldAnnotation.class,
+ StaticFieldAnnotation.class,
+ FieldAnnotationUse.class,
+ StaticFieldAnnotationUse.class,
+ TestClass.class,
+ MainClass.class);
+
+ @Test
+ public void test() throws Exception {
+ testForR8Compat(backend)
+ .enableClassInliningAnnotations()
+ .addProgramClasses(CLASSES)
+ .addKeepMainRule(MainClass.class)
+ .addKeepRules("-keep @interface **.*Annotation { *; }")
+ .addKeepRules("-keepclassmembers class * { @**.*Annotation <fields>; }")
+ .addKeepRules("-keepattributes *Annotation*")
+ .compile()
+ .inspect(
+ inspector -> {
+ ClassSubject clazz = inspector.clazz(TestClass.class);
+ assertThat(clazz, isRenamed());
+
+ FieldSubject field = clazz.uniqueFieldWithName("field");
+ assertThat(field, isPresent());
+ assertThat(field.annotation(FieldAnnotation.class.getTypeName()), isPresent());
+ assertThat(inspector.clazz(FieldAnnotationUse.class), isRenamed());
+
+ FieldSubject staticField = clazz.uniqueFieldWithName("staticField");
+ assertThat(staticField, isPresent());
+ assertThat(
+ staticField.annotation(StaticFieldAnnotation.class.getTypeName()), isPresent());
+ assertThat(inspector.clazz(StaticFieldAnnotationUse.class), isRenamed());
+ })
+ .run(MainClass.class)
+ .assertSuccess();
+ }
+}
+
+@Target(FIELD)
+@Retention(RUNTIME)
+@interface FieldAnnotation {
+ Class<?> clazz();
+}
+
+@Target(FIELD)
+@Retention(RUNTIME)
+@interface StaticFieldAnnotation {
+ Class<?> clazz();
+}
+
+class FieldAnnotationUse {}
+
+class StaticFieldAnnotationUse {}
+
+@NeverClassInline
+class TestClass {
+
+ @StaticFieldAnnotation(clazz = StaticFieldAnnotationUse.class)
+ static int staticField;
+
+ @FieldAnnotation(clazz = FieldAnnotationUse.class)
+ int field;
+}
+
+class MainClass {
+
+ public static void main(String[] args) {
+ new TestClass();
+ }
+}