blob: 9994ab14228c67016d5cbe169dc6fad6cdb6b697 [file] [log] [blame]
// 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;
/** Immutable keep requirements for a method. */
public final class KeepMethodInfo extends KeepMemberInfo<KeepMethodInfo.Builder, KeepMethodInfo> {
// Requires all aspects of a method to be kept.
private static final KeepMethodInfo TOP = new Builder().makeTop().build();
// Requires no aspects of a method to be kept.
private static final KeepMethodInfo BOTTOM = new Builder().makeBottom().build();
public static KeepMethodInfo top() {
return TOP;
}
public static KeepMethodInfo bottom() {
return BOTTOM;
}
public static Joiner newEmptyJoiner() {
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
// in a non-upwards direction.
@Override
Builder builder() {
return new Builder(this);
}
public boolean isArgumentPropagationAllowed(GlobalKeepInfoConfiguration configuration) {
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);
}
@Override
public boolean isTop() {
return this.equals(top());
}
@Override
public boolean isBottom() {
return this.equals(bottom());
}
public boolean isInliningAllowed(GlobalKeepInfoConfiguration configuration) {
return isOptimizationAllowed(configuration);
}
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
public Builder self() {
return this;
}
@Override
public KeepMethodInfo getTopInfo() {
return TOP;
}
@Override
public KeepMethodInfo getBottomInfo() {
return BOTTOM;
}
@Override
public boolean isEqualTo(KeepMethodInfo other) {
return internalIsEqualTo(other);
}
@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> {
public Joiner(KeepMethodInfo info) {
super(info.builder());
}
public Joiner disallowParameterTypeStrengthening() {
builder.disallowParameterTypeStrengthening();
return self();
}
@Override
public Joiner asMethodJoiner() {
return this;
}
@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)
.applyIf(
!joiner.builder.isParameterTypeStrengtheningAllowed(),
Joiner::disallowParameterTypeStrengthening);
}
@Override
Joiner self() {
return this;
}
}
}