Introduce @NoParameterTypeStrengthening annotation for testing
Change-Id: I3cba1e2f9002544d06914b03dee3f537c87c45a1
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java b/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
index 9938bbc..9994ab1 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
@@ -24,8 +24,11 @@
return bottom().joiner();
}
+ private final boolean allowParameterTypeStrengthening;
+
private KeepMethodInfo(Builder builder) {
super(builder);
+ this.allowParameterTypeStrengthening = builder.isParameterTypeStrengtheningAllowed();
}
// This builder is not private as there are known instances where it is safe to modify keep info
@@ -39,6 +42,16 @@
return isParameterRemovalAllowed(configuration);
}
+ public boolean isParameterTypeStrengtheningAllowed(GlobalKeepInfoConfiguration configuration) {
+ return isOptimizationAllowed(configuration)
+ && isShrinkingAllowed(configuration)
+ && internalIsParameterTypeStrengtheningAllowed();
+ }
+
+ boolean internalIsParameterTypeStrengtheningAllowed() {
+ return allowParameterTypeStrengthening;
+ }
+
public Joiner joiner() {
assert !isTop();
return new Joiner(this);
@@ -60,12 +73,32 @@
public static class Builder extends KeepInfo.Builder<Builder, KeepMethodInfo> {
+ private boolean allowParameterTypeStrengthening;
+
private Builder() {
super();
}
private Builder(KeepMethodInfo original) {
super(original);
+ allowParameterTypeStrengthening = original.internalIsParameterTypeStrengtheningAllowed();
+ }
+
+ public boolean isParameterTypeStrengtheningAllowed() {
+ return allowParameterTypeStrengthening;
+ }
+
+ public Builder setAllowParameterTypeStrengthening(boolean allowParameterTypeStrengthening) {
+ this.allowParameterTypeStrengthening = allowParameterTypeStrengthening;
+ return self();
+ }
+
+ public Builder allowParameterTypeStrengthening() {
+ return setAllowParameterTypeStrengthening(true);
+ }
+
+ public Builder disallowParameterTypeStrengthening() {
+ return setAllowParameterTypeStrengthening(false);
}
@Override
@@ -89,9 +122,26 @@
}
@Override
+ boolean internalIsEqualTo(KeepMethodInfo other) {
+ return super.internalIsEqualTo(other)
+ && isParameterTypeStrengtheningAllowed()
+ == other.internalIsParameterTypeStrengtheningAllowed();
+ }
+
+ @Override
public KeepMethodInfo doBuild() {
return new KeepMethodInfo(this);
}
+
+ @Override
+ public Builder makeTop() {
+ return super.makeTop().disallowParameterTypeStrengthening();
+ }
+
+ @Override
+ public Builder makeBottom() {
+ return super.makeBottom().allowParameterTypeStrengthening();
+ }
}
public static class Joiner extends KeepInfo.Joiner<Joiner, Builder, KeepMethodInfo> {
@@ -100,6 +150,11 @@
super(info.builder());
}
+ public Joiner disallowParameterTypeStrengthening() {
+ builder.disallowParameterTypeStrengthening();
+ return self();
+ }
+
@Override
public Joiner asMethodJoiner() {
return this;
@@ -108,7 +163,10 @@
@Override
public Joiner merge(Joiner joiner) {
// Should be extended to merge the fields of this class in case any are added.
- return super.merge(joiner);
+ return super.merge(joiner)
+ .applyIf(
+ !joiner.builder.isParameterTypeStrengtheningAllowed(),
+ Joiner::disallowParameterTypeStrengthening);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/NoParameterTypeStrengtheningRule.java b/src/main/java/com/android/tools/r8/shaking/NoParameterTypeStrengtheningRule.java
new file mode 100644
index 0000000..94cec37
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/NoParameterTypeStrengtheningRule.java
@@ -0,0 +1,84 @@
+// 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.shaking;
+
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
+import java.util.List;
+
+public class NoParameterTypeStrengtheningRule extends ProguardConfigurationRule {
+
+ public static final String RULE_NAME = "noparametertypestrengthening";
+
+ public static class Builder
+ extends ProguardConfigurationRule.Builder<NoParameterTypeStrengtheningRule, Builder> {
+
+ private Builder() {
+ super();
+ }
+
+ @Override
+ public NoParameterTypeStrengtheningRule.Builder self() {
+ return this;
+ }
+
+ @Override
+ public NoParameterTypeStrengtheningRule build() {
+ return new NoParameterTypeStrengtheningRule(
+ origin,
+ getPosition(),
+ source,
+ buildClassAnnotations(),
+ classAccessFlags,
+ negatedClassAccessFlags,
+ classTypeNegated,
+ classType,
+ classNames,
+ buildInheritanceAnnotations(),
+ inheritanceClassName,
+ inheritanceIsExtends,
+ memberRules);
+ }
+ }
+
+ private NoParameterTypeStrengtheningRule(
+ Origin origin,
+ Position position,
+ String source,
+ List<ProguardTypeMatcher> classAnnotations,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
+ boolean classTypeNegated,
+ ProguardClassType classType,
+ ProguardClassNameList classNames,
+ List<ProguardTypeMatcher> inheritanceAnnotations,
+ ProguardTypeMatcher inheritanceClassName,
+ boolean inheritanceIsExtends,
+ List<ProguardMemberRule> memberRules) {
+ super(
+ origin,
+ position,
+ source,
+ classAnnotations,
+ classAccessFlags,
+ negatedClassAccessFlags,
+ classTypeNegated,
+ classType,
+ classNames,
+ inheritanceAnnotations,
+ inheritanceClassName,
+ inheritanceIsExtends,
+ memberRules);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ String typeString() {
+ return RULE_NAME;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index b92040b..13cabf2 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -500,6 +500,11 @@
configurationBuilder.addRule(rule);
return true;
}
+ if (acceptString(NoParameterTypeStrengtheningRule.RULE_NAME)) {
+ ProguardConfigurationRule rule = parseNoParameterTypeStrengtheningRule(optionStart);
+ configurationBuilder.addRule(rule);
+ return true;
+ }
if (acceptString("neverpropagatevalue")) {
MemberValuePropagationRule rule =
parseMemberValuePropagationRule(MemberValuePropagationRule.Type.NEVER, optionStart);
@@ -828,6 +833,17 @@
return keepRuleBuilder.build();
}
+ private NoParameterTypeStrengtheningRule parseNoParameterTypeStrengtheningRule(Position start)
+ throws ProguardRuleParserException {
+ NoParameterTypeStrengtheningRule.Builder keepRuleBuilder =
+ NoParameterTypeStrengtheningRule.builder().setOrigin(origin).setStart(start);
+ parseClassSpec(keepRuleBuilder, false);
+ Position end = getPosition();
+ keepRuleBuilder.setSource(getSourceSnippet(contents, start, end));
+ keepRuleBuilder.setEnd(end);
+ return keepRuleBuilder.build();
+ }
+
private MemberValuePropagationRule parseMemberValuePropagationRule(
MemberValuePropagationRule.Type type, Position start)
throws ProguardRuleParserException {
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index 3644e3d..80756a1 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -267,6 +267,7 @@
markMatchingFields(clazz, memberKeepRules, rule, null, ifRule);
} else if (rule instanceof InlineRule
|| rule instanceof ConstantArgumentRule
+ || rule instanceof NoParameterTypeStrengtheningRule
|| rule instanceof UnusedArgumentRule
|| rule instanceof ReprocessMethodRule
|| rule instanceof WhyAreYouNotInliningRule) {
@@ -1243,6 +1244,13 @@
} else if (context instanceof NoHorizontalClassMergingRule) {
noHorizontalClassMerging.add(item.asClass().type);
context.markAsUsed();
+ } else if (context instanceof NoParameterTypeStrengtheningRule) {
+ assert item.isProgramMethod();
+ dependentMinimumKeepInfo
+ .getOrCreateUnconditionalMinimumKeepInfoFor(item.getReference())
+ .asMethodJoiner()
+ .disallowParameterTypeStrengthening();
+ context.markAsUsed();
} else if (context instanceof MemberValuePropagationRule) {
switch (((MemberValuePropagationRule) context).getType()) {
case NEVER:
diff --git a/src/test/java/com/android/tools/r8/NoParameterTypeStrengthening.java b/src/test/java/com/android/tools/r8/NoParameterTypeStrengthening.java
new file mode 100644
index 0000000..c862859
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/NoParameterTypeStrengthening.java
@@ -0,0 +1,11 @@
+// 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;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.PARAMETER})
+public @interface NoParameterTypeStrengthening {}
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 1fa7630..1a4706e 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.shaking.CollectingGraphConsumer;
import com.android.tools.r8.shaking.NoFieldTypeStrengtheningRule;
import com.android.tools.r8.shaking.NoHorizontalClassMergingRule;
+import com.android.tools.r8.shaking.NoParameterTypeStrengtheningRule;
import com.android.tools.r8.shaking.NoUnusedInterfaceRemovalRule;
import com.android.tools.r8.shaking.NoVerticalClassMergingRule;
import com.android.tools.r8.shaking.ProguardConfiguration;
@@ -436,6 +437,11 @@
"-" + name + " class * { @" + annotation.getTypeName() + " <fields>; }");
}
+ T addInternalMatchAnnotationOnMethodRule(String name, Class<? extends Annotation> annotation) {
+ return addInternalKeepRules(
+ "-" + name + " class * { @" + annotation.getTypeName() + " <methods>; }");
+ }
+
T addInternalMatchInterfaceRule(String name, Class<?> matchInterface) {
return addInternalKeepRules("-" + name + " @" + matchInterface.getTypeName() + " class *");
}
@@ -502,6 +508,12 @@
NoFieldTypeStrengtheningRule.RULE_NAME, NoFieldTypeStrengthening.class);
}
+ public T enableNoParameterTypeStrengtheningAnnotations() {
+ return addNoParameterTypeStrengtheningAnnotation()
+ .addInternalMatchAnnotationOnMethodRule(
+ NoParameterTypeStrengtheningRule.RULE_NAME, NoParameterTypeStrengthening.class);
+ }
+
public T enableNoUnusedInterfaceRemovalAnnotations() {
return addNoUnusedInterfaceRemovalAnnotations()
.addInternalMatchInterfaceRule(
diff --git a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
index 7fc1ecc..9ed8247 100644
--- a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
@@ -466,6 +466,10 @@
return addTestingAnnotation(NoHorizontalClassMerging.class);
}
+ public final T addNoParameterTypeStrengtheningAnnotation() {
+ return addTestingAnnotation(NoParameterTypeStrengthening.class);
+ }
+
public final T addNoUnusedInterfaceRemovalAnnotations() {
return addTestingAnnotation(NoUnusedInterfaceRemoval.class);
}