blob: f87cd781b77e87e9d2d18001139c603496a6aea9 [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.kotlin;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.rewriteIfNotNull;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.rewriteList;
import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.function.Consumer;
import kotlin.metadata.KmConstantValue;
import kotlin.metadata.KmEffectExpression;
public class KotlinEffectExpressionInfo implements EnqueuerMetadataTraceable {
private static final List<KotlinEffectExpressionInfo> NO_EXPRESSIONS = ImmutableList.of();
private static final KotlinEffectExpressionInfo NO_EXPRESSION =
new KotlinEffectExpressionInfo(
new KmEffectExpression(), null, NO_EXPRESSIONS, NO_EXPRESSIONS);
private final KmEffectExpression kmEffectExpression;
private final KotlinTypeInfo isInstanceType;
private final List<KotlinEffectExpressionInfo> andArguments;
private final List<KotlinEffectExpressionInfo> orArguments;
private KotlinEffectExpressionInfo(
KmEffectExpression kmEffectExpression,
KotlinTypeInfo isInstanceType,
List<KotlinEffectExpressionInfo> andArguments,
List<KotlinEffectExpressionInfo> orArguments) {
this.kmEffectExpression = kmEffectExpression;
this.isInstanceType = isInstanceType;
this.andArguments = andArguments;
this.orArguments = orArguments;
}
static KotlinEffectExpressionInfo create(
KmEffectExpression kmEffectExpression, DexItemFactory factory, Reporter reporter) {
if (kmEffectExpression == null) {
return NO_EXPRESSION;
}
return new KotlinEffectExpressionInfo(
kmEffectExpression,
KotlinTypeInfo.create(kmEffectExpression.isInstanceType(), factory, reporter),
create(kmEffectExpression.getAndArguments(), factory, reporter),
create(kmEffectExpression.getOrArguments(), factory, reporter));
}
static List<KotlinEffectExpressionInfo> create(
List<KmEffectExpression> effectExpressions, DexItemFactory factory, Reporter reporter) {
if (effectExpressions.isEmpty()) {
return NO_EXPRESSIONS;
}
ImmutableList.Builder<KotlinEffectExpressionInfo> builder = ImmutableList.builder();
for (KmEffectExpression effectExpression : effectExpressions) {
builder.add(create(effectExpression, factory, reporter));
}
return builder.build();
}
@Override
public void trace(DexDefinitionSupplier definitionSupplier) {
if (this == NO_EXPRESSION) {
return;
}
if (isInstanceType != null) {
isInstanceType.trace(definitionSupplier);
}
forEachApply(andArguments, arg -> arg::trace, definitionSupplier);
forEachApply(orArguments, arg -> arg::trace, definitionSupplier);
}
boolean rewrite(Consumer<KmEffectExpression> consumer, AppView<?> appView) {
if (this == NO_EXPRESSION) {
return false;
}
KmEffectExpression rewrittenKmEffectExpression = new KmEffectExpression();
consumer.accept(rewrittenKmEffectExpression);
KotlinFlagUtils.copyAllFlags(kmEffectExpression, rewrittenKmEffectExpression);
rewrittenKmEffectExpression.setParameterIndex(kmEffectExpression.getParameterIndex());
KmConstantValue constantValue = kmEffectExpression.getConstantValue();
if (constantValue != null) {
rewrittenKmEffectExpression.setConstantValue(constantValue);
}
boolean rewritten =
rewriteIfNotNull(
appView,
isInstanceType,
rewrittenKmEffectExpression::setInstanceType,
KotlinTypeInfo::rewrite);
rewritten |=
rewriteList(
appView,
andArguments,
rewrittenKmEffectExpression.getAndArguments(),
KotlinEffectExpressionInfo::rewrite);
rewritten |=
rewriteList(
appView,
orArguments,
rewrittenKmEffectExpression.getOrArguments(),
KotlinEffectExpressionInfo::rewrite);
return rewritten;
}
}