blob: bf969b7e9088fda598e066f3d7f495652b5c4a3e [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;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.utils.InternalOptions;
import java.util.function.Function;
/** Immutable keep requirements for a class. */
public final class KeepClassInfo extends KeepInfo<KeepClassInfo.Builder, KeepClassInfo> {
// Requires all aspects of a class to be kept.
private static final KeepClassInfo TOP = new Builder().makeTop().build();
// Requires no aspects of a class to be kept.
private static final KeepClassInfo BOTTOM = new Builder().makeBottom().build();
public static KeepClassInfo top() {
return TOP;
}
public static KeepClassInfo bottom() {
return BOTTOM;
}
public static Joiner newEmptyJoiner() {
return bottom().joiner();
}
private KeepClassInfo(Builder builder) {
super(builder);
}
@Override
Builder builder() {
return new Builder(this);
}
public Joiner joiner() {
assert !isTop();
return new Joiner(this);
}
@Override
public boolean isRepackagingAllowed(
ProgramDefinition definition, GlobalKeepInfoConfiguration configuration) {
return configuration.isRepackagingEnabled()
&& internalIsMinificationAllowed()
&& (definition.getAccessFlags().isPublic()
|| !internalIsAccessModificationRequiredForRepackaging());
}
public boolean isKotlinMetadataRemovalAllowed(
GlobalKeepInfoConfiguration configuration, boolean kotlinMetadataKept) {
return !kotlinMetadataKept
|| !isPinned(configuration)
|| !configuration.isKeepRuntimeVisibleAnnotationsEnabled()
|| isAnnotationRemovalAllowed(configuration);
}
public static boolean isKotlinMetadataClassKept(
DexItemFactory factory,
InternalOptions options,
Function<DexType, DexClass> definitionForWithoutExistenceAssert,
Function<DexProgramClass, KeepClassInfo> getClassInfo) {
DexType kotlinMetadataType = factory.kotlinMetadataType;
DexClass kotlinMetadataClass = definitionForWithoutExistenceAssert.apply(kotlinMetadataType);
return kotlinMetadataClass == null
|| kotlinMetadataClass.isNotProgramClass()
|| !getClassInfo.apply(kotlinMetadataClass.asProgramClass()).isShrinkingAllowed(options);
}
@Override
public boolean isTop() {
return this.equals(top());
}
@Override
public boolean isBottom() {
return this.equals(bottom());
}
public static class Builder extends KeepInfo.Builder<Builder, KeepClassInfo> {
private Builder() {
super();
}
private Builder(KeepClassInfo original) {
super(original);
}
@Override
public KeepClassInfo getTopInfo() {
return TOP;
}
@Override
public KeepClassInfo getBottomInfo() {
return BOTTOM;
}
@Override
public Builder self() {
return this;
}
@Override
public boolean isEqualTo(KeepClassInfo other) {
return internalIsEqualTo(other);
}
@Override
public KeepClassInfo doBuild() {
return new KeepClassInfo(this);
}
}
public static class Joiner extends KeepInfo.Joiner<Joiner, Builder, KeepClassInfo> {
public Joiner(KeepClassInfo info) {
super(info.builder());
}
@Override
public Joiner asClassJoiner() {
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);
}
@Override
Joiner self() {
return this;
}
}
}