[KeepAnno] Enable more tests for native interpretation
This adds support for class names, access flags, annotations and fields.
Bug: b/323816623
Change-Id: I50e4557b2f6dce58cc09046084ca50c0cdf41ba5
diff --git a/src/main/java/com/android/tools/r8/shaking/rules/KeepAnnotationMatcher.java b/src/main/java/com/android/tools/r8/shaking/rules/KeepAnnotationMatcher.java
index ccac25a..0d7e1b2 100644
--- a/src/main/java/com/android/tools/r8/shaking/rules/KeepAnnotationMatcher.java
+++ b/src/main/java/com/android/tools/r8/shaking/rules/KeepAnnotationMatcher.java
@@ -239,22 +239,32 @@
return;
}
KeepClassItemPattern classPattern = schema.classes.get(classIndex);
- if (!classPattern.getClassNamePattern().isExact()) {
- throw new Unimplemented();
+ if (classPattern.getClassNamePattern().isExact()) {
+ DexType type =
+ appInfo
+ .dexItemFactory()
+ .createType(classPattern.getClassNamePattern().getExactDescriptor());
+ DexProgramClass clazz = DexProgramClass.asProgramClassOrNull(appInfo.definitionFor(type));
+ if (clazz == null) {
+ // No valid match, so the rule is discarded. This should likely be a diagnostics info.
+ return;
+ }
+ if (!predicates.matchesClass(clazz, classPattern)) {
+ // Invalid match for this class.
+ return;
+ }
+ continueWithClass(classIndex, clazz);
+ } else {
+ // TODO(b/323816623): This repeated iteration on all classes must be avoided.
+ for (DexProgramClass clazz : appInfo.classes()) {
+ if (predicates.matchesClass(clazz, classPattern)) {
+ continueWithClass(classIndex, clazz);
+ }
+ }
}
- DexType type =
- appInfo
- .dexItemFactory()
- .createType(classPattern.getClassNamePattern().getExactDescriptor());
- DexProgramClass clazz = DexProgramClass.asProgramClassOrNull(appInfo.definitionFor(type));
- if (clazz == null) {
- // No valid match, so the rule is discarded. This should likely be a diagnostics info.
- return;
- }
- if (!predicates.matchesClass(clazz, classPattern)) {
- // Invalid match for this class.
- return;
- }
+ }
+
+ private void continueWithClass(int classIndex, DexProgramClass clazz) {
assignment.setClass(classIndex, clazz);
IntList classMemberIndexList = schema.classMembers.get(classIndex);
findMatchingMember(0, classMemberIndexList, clazz, classIndex + 1);
@@ -270,48 +280,55 @@
findMatchingClass(nextClassIndex);
return;
}
- int nextMemberInHolderIndex = memberInHolderIndex + 1;
int memberIndex = memberIndexTranslation.getInt(memberInHolderIndex);
KeepMemberItemPattern memberItemPattern = schema.members.get(memberIndex);
+ Consumer<ProgramDefinition> continueWithMember =
+ m ->
+ continueWithMember(
+ m, memberIndex, memberInHolderIndex + 1, memberIndexTranslation, nextClassIndex);
memberItemPattern
.getMemberPattern()
.match(
- generalMember -> {
- if (!holder.hasMethodsOrFields()) {
+ generalMemberPattern -> {
+ if (!holder.hasMethodsOrFields() && generalMemberPattern.isAllMembers()) {
// The empty class can only match the "all member" pattern but with no assignment.
- if (generalMember.isAllMembers()) {
- assignment.setEmptyMemberMatch(memberIndex);
- findMatchingMember(
- nextMemberInHolderIndex, memberIndexTranslation, holder, nextClassIndex);
- }
- return;
+ continueWithMember.accept(holder);
+ } else {
+ holder.forEachProgramMember(
+ m -> {
+ if (predicates.matchesGeneralMember(
+ m.getDefinition(), generalMemberPattern)) {
+ continueWithMember.accept(m);
+ }
+ });
}
- if (!generalMember.isAllMembers()) {
- throw new Unimplemented();
- }
- holder.forEachProgramMember(
- f -> {
- assignment.setMember(memberIndex, f);
- findMatchingMember(
- nextMemberInHolderIndex, memberIndexTranslation, holder, nextClassIndex);
- });
},
- fieldMember -> {
- throw new Unimplemented();
- },
- methodMember -> {
- holder.forEachProgramMethod(
- m -> {
- if (predicates.matchesMethod(methodMember, m)) {
- assignment.setMember(memberIndex, m);
- findMatchingMember(
- nextMemberInHolderIndex,
- memberIndexTranslation,
- holder,
- nextClassIndex);
- }
- });
- });
+ fieldPattern ->
+ holder.forEachProgramFieldMatching(
+ f -> predicates.matchesField(f, fieldPattern), continueWithMember),
+ methodPattern ->
+ holder.forEachProgramMethodMatching(
+ m -> predicates.matchesMethod(m, methodPattern), continueWithMember));
+ }
+
+ private void continueWithMember(
+ ProgramDefinition definition,
+ int memberIndex,
+ int nextMemberInHolderIndex,
+ IntList memberIndexTranslation,
+ int nextClassIndex) {
+ if (definition.isProgramMember()) {
+ assignment.setMember(memberIndex, definition.asProgramMember());
+ } else {
+ assert definition.isProgramClass();
+ assert !definition.asProgramClass().hasMethodsOrFields();
+ assignment.setEmptyMemberMatch(memberIndex);
+ }
+ findMatchingMember(
+ nextMemberInHolderIndex,
+ memberIndexTranslation,
+ definition.getContextClass(),
+ nextClassIndex);
}
}
@@ -336,24 +353,6 @@
this.edge = edge;
edge.getPreconditions().forEach(this::addPrecondition);
edge.getConsequences().forEachTarget(this::addConsequence);
- ListUtils.forEachWithIndex(
- members,
- (member, memberIndex) -> {
- member
- .getClassReference()
- .matchClassItemReference(
- bindingReference -> {
- int classIndex = symbolToKey.getInt(bindingReference);
- classMembers.get(classIndex).add(memberIndex);
- },
- classItemPattern -> {
- // The member declares its own inline class so link it directly.
- IntArrayList memberList = new IntArrayList();
- memberList.add(memberIndex);
- classes.add(classItemPattern);
- classMembers.add(memberList);
- });
- });
}
public static boolean isClassKeyReference(int keyRef) {
@@ -393,14 +392,17 @@
private int defineItemPattern(KeepItemPattern item) {
if (item.isClassItemPattern()) {
- int key = classes.size();
+ int classIndex = classes.size();
classes.add(item.asClassItemPattern());
classMembers.add(new IntArrayList());
- return encodeClassKey(key);
+ return encodeClassKey(classIndex);
+ } else {
+ int classIndex = defineItemReference(item.asMemberItemPattern().getClassReference());
+ int memberIndex = members.size();
+ members.add(item.asMemberItemPattern());
+ classMembers.get(classIndex).add(memberIndex);
+ return encodeMemberKey(memberIndex);
}
- int key = members.size();
- members.add(item.asMemberItemPattern());
- return encodeMemberKey(key);
}
public void addPrecondition(KeepCondition condition) {
diff --git a/src/main/java/com/android/tools/r8/shaking/rules/KeepAnnotationMatcherPredicates.java b/src/main/java/com/android/tools/r8/shaking/rules/KeepAnnotationMatcherPredicates.java
index 45e8385..364a17f 100644
--- a/src/main/java/com/android/tools/r8/shaking/rules/KeepAnnotationMatcherPredicates.java
+++ b/src/main/java/com/android/tools/r8/shaking/rules/KeepAnnotationMatcherPredicates.java
@@ -5,25 +5,38 @@
package com.android.tools.r8.shaking.rules;
import com.android.tools.r8.errors.Unimplemented;
+import com.android.tools.r8.graph.AccessFlags;
+import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexEncodedMember;
+import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.MethodAccessFlags;
-import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.keepanno.ast.AccessVisibility;
import com.android.tools.r8.keepanno.ast.KeepArrayTypePattern;
import com.android.tools.r8.keepanno.ast.KeepClassItemPattern;
+import com.android.tools.r8.keepanno.ast.KeepFieldAccessPattern;
+import com.android.tools.r8.keepanno.ast.KeepFieldPattern;
import com.android.tools.r8.keepanno.ast.KeepInstanceOfPattern;
+import com.android.tools.r8.keepanno.ast.KeepMemberAccessPattern;
+import com.android.tools.r8.keepanno.ast.KeepMemberPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodAccessPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodParametersPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodReturnTypePattern;
+import com.android.tools.r8.keepanno.ast.KeepPackagePattern;
import com.android.tools.r8.keepanno.ast.KeepPrimitiveTypePattern;
import com.android.tools.r8.keepanno.ast.KeepQualifiedClassNamePattern;
import com.android.tools.r8.keepanno.ast.KeepStringPattern;
import com.android.tools.r8.keepanno.ast.KeepTypePattern;
+import com.android.tools.r8.keepanno.ast.KeepUnqualfiedClassNamePattern;
+import com.android.tools.r8.keepanno.ast.ModifierPattern;
import com.android.tools.r8.keepanno.ast.OptionalPattern;
import java.util.List;
@@ -48,7 +61,25 @@
if (pattern.isExact()) {
return type.toDescriptorString().equals(pattern.getExactDescriptor());
}
- throw new Unimplemented();
+ return matchesPackage(type.getPackageName(), pattern.getPackagePattern())
+ && matchesSimpleName(type.getSimpleName(), pattern.getNamePattern());
+ }
+
+ private boolean matchesPackage(String packageName, KeepPackagePattern pattern) {
+ if (pattern.isAny()) {
+ return true;
+ }
+ if (pattern.isTop() && packageName.equals("")) {
+ return true;
+ }
+ return packageName.equals(pattern.getExactPackageAsString());
+ }
+
+ public boolean matchesSimpleName(String simpleName, KeepUnqualfiedClassNamePattern pattern) {
+ if (pattern.isAny()) {
+ return true;
+ }
+ return pattern.asExact().getExactNameAsString().equals(simpleName);
}
private boolean matchesInstanceOfPattern(
@@ -59,30 +90,109 @@
throw new Unimplemented();
}
- public boolean matchesMethod(KeepMethodPattern methodPattern, ProgramMethod method) {
- if (methodPattern.isAnyMethod()) {
+ public boolean matchesGeneralMember(DexEncodedMember<?, ?> member, KeepMemberPattern pattern) {
+ assert pattern.isGeneralMember();
+ if (pattern.isAllMembers()) {
return true;
}
- return matchesName(method.getName(), methodPattern.getNamePattern().asStringPattern())
- && matchesReturnType(method.getReturnType(), methodPattern.getReturnTypePattern())
- && matchesParameters(method.getParameters(), methodPattern.getParametersPattern())
- && matchesAnnotatedBy(method.getAnnotations(), methodPattern.getAnnotatedByPattern())
- && matchesAccess(method.getAccessFlags(), methodPattern.getAccessPattern());
+ return matchesAnnotatedBy(member.annotations(), pattern.getAnnotatedByPattern())
+ && matchesGeneralMemberAccess(member.getAccessFlags(), pattern.getAccessPattern());
}
- public boolean matchesAccess(MethodAccessFlags access, KeepMethodAccessPattern pattern) {
+ public boolean matchesMethod(DexEncodedMethod method, KeepMethodPattern pattern) {
+ if (pattern.isAnyMethod()) {
+ return true;
+ }
+ return matchesName(method.getName(), pattern.getNamePattern().asStringPattern())
+ && matchesReturnType(method.getReturnType(), pattern.getReturnTypePattern())
+ && matchesParameters(method.getParameters(), pattern.getParametersPattern())
+ && matchesAnnotatedBy(method.annotations(), pattern.getAnnotatedByPattern())
+ && matchesMethodAccess(method.getAccessFlags(), pattern.getAccessPattern());
+ }
+
+ public boolean matchesField(DexEncodedField field, KeepFieldPattern pattern) {
+ if (pattern.isAnyField()) {
+ return true;
+ }
+ return matchesName(field.getName(), pattern.getNamePattern().asStringPattern())
+ && matchesType(field.getType(), pattern.getTypePattern().asType())
+ && matchesAnnotatedBy(field.annotations(), pattern.getAnnotatedByPattern())
+ && matchesFieldAccess(field.getAccessFlags(), pattern.getAccessPattern());
+ }
+
+ public boolean matchesGeneralMemberAccess(
+ AccessFlags<?> access, KeepMemberAccessPattern pattern) {
if (pattern.isAny()) {
return true;
}
- throw new Unimplemented();
+ if (!pattern.isAnyVisibility() && !pattern.isVisibilityAllowed(getAccessVisibility(access))) {
+ return false;
+ }
+ return matchesModifier(access.isStatic(), pattern.getStaticPattern())
+ && matchesModifier(access.isFinal(), pattern.getFinalPattern())
+ && matchesModifier(access.isSynthetic(), pattern.getSyntheticPattern());
+ }
+
+ public boolean matchesMethodAccess(MethodAccessFlags access, KeepMethodAccessPattern pattern) {
+ if (pattern.isAny()) {
+ return true;
+ }
+ return matchesGeneralMemberAccess(access, pattern)
+ && matchesModifier(access.isSynchronized(), pattern.getSynchronizedPattern())
+ && matchesModifier(access.isBridge(), pattern.getBridgePattern())
+ && matchesModifier(access.isNative(), pattern.getNativePattern())
+ && matchesModifier(access.isAbstract(), pattern.getAbstractPattern())
+ && matchesModifier(access.isStrict(), pattern.getStrictFpPattern());
+ }
+
+ public boolean matchesFieldAccess(FieldAccessFlags access, KeepFieldAccessPattern pattern) {
+ if (pattern.isAny()) {
+ return true;
+ }
+ return matchesGeneralMemberAccess(access, pattern)
+ && matchesModifier(access.isVolatile(), pattern.getVolatilePattern())
+ && matchesModifier(access.isTransient(), pattern.getTransientPattern());
+ }
+
+ private boolean matchesModifier(boolean value, ModifierPattern pattern) {
+ return pattern.isAny() || value == pattern.isOnlyPositive();
+ }
+
+ private AccessVisibility getAccessVisibility(AccessFlags<?> accessFlags) {
+ if (accessFlags.isPublic()) {
+ return AccessVisibility.PUBLIC;
+ }
+ if (accessFlags.isProtected()) {
+ return AccessVisibility.PROTECTED;
+ }
+ if (accessFlags.isPackagePrivate()) {
+ return AccessVisibility.PACKAGE_PRIVATE;
+ }
+ assert accessFlags.isPrivate();
+ return AccessVisibility.PRIVATE;
}
public boolean matchesAnnotatedBy(
DexAnnotationSet annotations, OptionalPattern<KeepQualifiedClassNamePattern> pattern) {
if (pattern.isAbsent()) {
+ // No pattern for annotations matches regardless of annotation content.
return true;
}
- throw new Unimplemented();
+ if (annotations.isEmpty()) {
+ // Fast-path if pattern is present but no annotations.
+ return false;
+ }
+ KeepQualifiedClassNamePattern classNamePattern = pattern.get();
+ if (classNamePattern.isAny()) {
+ // Fast-path the "any" case.
+ return true;
+ }
+ for (DexAnnotation annotation : annotations.getAnnotations()) {
+ if (matchesClassName(annotation.getAnnotationType(), classNamePattern)) {
+ return true;
+ }
+ }
+ return false;
}
public boolean matchesParameters(DexTypeList parameters, KeepMethodParametersPattern pattern) {
diff --git a/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternAnyRetentionTest.java b/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternAnyRetentionTest.java
index 31de01d..2dd3af2 100644
--- a/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternAnyRetentionTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternAnyRetentionTest.java
@@ -44,6 +44,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.setExcludedOuterClass(getClass())
.run(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternClassRetentionTest.java b/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternClassRetentionTest.java
index df1bee8..af205e6 100644
--- a/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternClassRetentionTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternClassRetentionTest.java
@@ -45,6 +45,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.setExcludedOuterClass(getClass())
.run(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternMultipleTest.java b/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternMultipleTest.java
index feafc7f..af1e3b0 100644
--- a/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternMultipleTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/AnnotationPatternMultipleTest.java
@@ -46,6 +46,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.setExcludedOuterClass(getClass())
.run(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/keepanno/ArrayPatternsTest.java b/src/test/java/com/android/tools/r8/keepanno/ArrayPatternsTest.java
index 2f1f572..86bf2a5 100644
--- a/src/test/java/com/android/tools/r8/keepanno/ArrayPatternsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/ArrayPatternsTest.java
@@ -41,6 +41,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.setExcludedOuterClass(getClass())
.run(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/keepanno/ClassAnnotatedByAnyAnnoPatternTest.java b/src/test/java/com/android/tools/r8/keepanno/ClassAnnotatedByAnyAnnoPatternTest.java
index 7f3840f..5c7237a 100644
--- a/src/test/java/com/android/tools/r8/keepanno/ClassAnnotatedByAnyAnnoPatternTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/ClassAnnotatedByAnyAnnoPatternTest.java
@@ -44,6 +44,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.setExcludedOuterClass(getClass())
.run(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/keepanno/ClassAnnotatedByPatternsTest.java b/src/test/java/com/android/tools/r8/keepanno/ClassAnnotatedByPatternsTest.java
index 6d0f966..ea21a44 100644
--- a/src/test/java/com/android/tools/r8/keepanno/ClassAnnotatedByPatternsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/ClassAnnotatedByPatternsTest.java
@@ -44,6 +44,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.setExcludedOuterClass(getClass())
.run(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/keepanno/FieldPatternsTest.java b/src/test/java/com/android/tools/r8/keepanno/FieldPatternsTest.java
index 669d945..61fb54c 100644
--- a/src/test/java/com/android/tools/r8/keepanno/FieldPatternsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/FieldPatternsTest.java
@@ -38,6 +38,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(TestClass.class)
.setExcludedOuterClass(getClass())
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepAccessVisibilityFlagsTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepAccessVisibilityFlagsTest.java
index a9dec7d..6e41cc0 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepAccessVisibilityFlagsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepAccessVisibilityFlagsTest.java
@@ -82,6 +82,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(TestClass.class)
.allowAccessModification()
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepAnnoTestBuilder.java b/src/test/java/com/android/tools/r8/keepanno/KeepAnnoTestBuilder.java
index 1105bd3..5e34061 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepAnnoTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepAnnoTestBuilder.java
@@ -113,8 +113,8 @@
return applyIfPG(b -> b.addDontWarn(clazz));
}
- public final KeepAnnoTestBuilder allowUnusedProguardConfigurationRules() {
- return applyIfR8Current(R8TestBuilder::allowUnusedProguardConfigurationRules);
+ public KeepAnnoTestBuilder allowUnusedProguardConfigurationRules() {
+ return this;
}
public final KeepAnnoTestBuilder allowAccessModification() {
@@ -170,6 +170,7 @@
private List<Consumer<R8TestCompileResult>> compileResultConsumers = new ArrayList<>();
private final boolean normalizeEdges;
private final boolean extractRules;
+ private boolean enableNative = false;
private R8NativeBuilder(KeepAnnoParameters params, TemporaryFolder temp) {
super(params, temp);
@@ -189,10 +190,25 @@
}
@Override
+ public KeepAnnoTestBuilder allowUnusedProguardConfigurationRules() {
+ if (!enableNative) {
+ builder.allowUnusedProguardConfigurationRules();
+ }
+ return this;
+ }
+
+ @Override
public KeepAnnoTestBuilder enableNativeInterpretation() {
if (extractRules) {
return this;
}
+ enableNative = true;
+ // TODO(b/323816623): The compiler assumes that this is known prior to tracing.
+ // We should update the compiler to always read annotations and only remove them after
+ // initial tracing regardless of -keepattributes.
+ builder.addKeepRuntimeVisibleAnnotations();
+ builder.addKeepRuntimeInvisibleAnnotations();
+
// This enables native interpretation of all keep annotations.
builder.addOptionsModification(
o -> {
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepBindingTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepBindingTest.java
index 464ee91..18bc3d5 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepBindingTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepBindingTest.java
@@ -37,6 +37,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepClassRules(A.class, B.class)
.addKeepMainRule(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepClassApiTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepClassApiTest.java
index 4abe376..8e73b21 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepClassApiTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepClassApiTest.java
@@ -59,6 +59,7 @@
assertTrue(parameters.isShrinker());
Box<Path> lib = new Box<>();
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getLibraryClasses())
.setExcludedOuterClass(getClass())
.applyIfShrinker(b -> lib.set(b.compile().inspect(this::checkLibraryOutput).writeToZip()));
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepFieldValueApiTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepFieldValueApiTest.java
index 9ac84d1..f9cd926 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepFieldValueApiTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepFieldValueApiTest.java
@@ -58,6 +58,7 @@
assertTrue(parameters.isShrinker());
Box<Path> lib = new Box<>();
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getLibraryClasses())
.setExcludedOuterClass(getClass())
.applyIfShrinker(b -> lib.set(b.compile().inspect(this::checkLibraryOutput).writeToZip()));
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepFooIfBarAnyClassTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepFooIfBarAnyClassTest.java
index bf82204..76e7a94 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepFooIfBarAnyClassTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepFooIfBarAnyClassTest.java
@@ -35,6 +35,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(TestClass.class)
.setExcludedOuterClass(getClass())
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepFooIfBarSameClassTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepFooIfBarSameClassTest.java
index 0a2e16b..6e287d6 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepFooIfBarSameClassTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepFooIfBarSameClassTest.java
@@ -39,6 +39,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(TestClass.class)
.setExcludedOuterClass(getClass())
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepMembersAccessFlagsTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepMembersAccessFlagsTest.java
index fe8eacd..8d8b397 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepMembersAccessFlagsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepMembersAccessFlagsTest.java
@@ -42,6 +42,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(TestClass.class)
.setExcludedOuterClass(getClass())
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepMembersApiTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepMembersApiTest.java
index c6d3b7d..3ad549d 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepMembersApiTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepMembersApiTest.java
@@ -58,6 +58,7 @@
assertTrue(parameters.isShrinker());
Box<Path> lib = new Box<>();
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getLibraryClasses())
.setExcludedOuterClass(getClass())
.applyIfShrinker(b -> lib.set(b.compile().inspect(this::checkLibraryOutput).writeToZip()));
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepMethodsAccessFlagsTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepMethodsAccessFlagsTest.java
index 0de2eaf..9dec3d5 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepMethodsAccessFlagsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepMethodsAccessFlagsTest.java
@@ -41,6 +41,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(TestClass.class)
.setExcludedOuterClass(getClass())
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepMethodsEmptyAccessFlagsTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepMethodsEmptyAccessFlagsTest.java
index cac4ddb..e1db615 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepMethodsEmptyAccessFlagsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepMethodsEmptyAccessFlagsTest.java
@@ -40,6 +40,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(TestClass.class)
.setExcludedOuterClass(getClass())
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepStaticBindingTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepStaticBindingTest.java
index 1fbe385..dca36c5 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepStaticBindingTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepStaticBindingTest.java
@@ -36,6 +36,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.setExcludedOuterClass(getClass())
.run(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepUsedByReflectionAnnotationTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepUsedByReflectionAnnotationTest.java
index 0bc2417..9190d30 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepUsedByReflectionAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepUsedByReflectionAnnotationTest.java
@@ -41,6 +41,7 @@
public void test() throws Exception {
Class<?> mainClass = TestClass.class;
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(mainClass)
.setExcludedOuterClass(getClass())
@@ -53,6 +54,7 @@
public void testNoRef() throws Exception {
Class<?> mainClass = TestClassNoRef.class;
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.addKeepMainRule(mainClass)
.allowUnusedProguardConfigurationRules()
diff --git a/src/test/java/com/android/tools/r8/keepanno/MembersAnnotatedByPatternsTest.java b/src/test/java/com/android/tools/r8/keepanno/MembersAnnotatedByPatternsTest.java
index 52850da..35c1494 100644
--- a/src/test/java/com/android/tools/r8/keepanno/MembersAnnotatedByPatternsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/MembersAnnotatedByPatternsTest.java
@@ -47,6 +47,7 @@
@Test
public void test() throws Exception {
testForKeepAnno(parameters)
+ .enableNativeInterpretation()
.addProgramClasses(getInputClasses())
.setExcludedOuterClass(getClass())
.run(TestClass.class)