blob: aa46ee20eb786a0a5258b90b1cc1959d2f6194a7 [file] [log] [blame]
// Copyright (c) 2024, 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.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Reporter;
import java.util.List;
import java.util.function.Consumer;
import kotlin.metadata.KmProperty;
import kotlin.metadata.KmPropertyAccessorAttributes;
import kotlin.metadata.jvm.JvmExtensionsKt;
// Holds information about KmProperty
public class ConcreteKotlinPropertyInfo implements KotlinPropertyInfo {
// Original property.
private final KmProperty kmProperty;
// Original return type information. This should never be NULL (even for setters without field).
private final KotlinTypeInfo returnType;
private final KotlinTypeInfo receiverParameterType;
private final KotlinValueParameterInfo setterParameter;
private final List<KotlinTypeParameterInfo> typeParameters;
private final KotlinJvmFieldSignatureInfo fieldSignature;
private final KotlinJvmMethodSignatureInfo getterSignature;
private final KotlinJvmMethodSignatureInfo setterSignature;
private final KotlinJvmMethodSignatureInfo syntheticMethodForAnnotations;
private final KotlinJvmMethodSignatureInfo syntheticMethodForDelegate;
// Collection of context receiver types
private final List<KotlinTypeInfo> contextReceiverTypes;
private ConcreteKotlinPropertyInfo(
KmProperty kmProperty,
KotlinTypeInfo returnType,
KotlinTypeInfo receiverParameterType,
KotlinValueParameterInfo setterParameter,
List<KotlinTypeParameterInfo> typeParameters,
KotlinJvmFieldSignatureInfo fieldSignature,
KotlinJvmMethodSignatureInfo getterSignature,
KotlinJvmMethodSignatureInfo setterSignature,
KotlinJvmMethodSignatureInfo syntheticMethodForAnnotations,
KotlinJvmMethodSignatureInfo syntheticMethodForDelegate,
List<KotlinTypeInfo> contextReceiverTypes) {
assert returnType != null;
this.kmProperty = kmProperty;
this.returnType = returnType;
this.receiverParameterType = receiverParameterType;
this.setterParameter = setterParameter;
this.typeParameters = typeParameters;
this.fieldSignature = fieldSignature;
this.getterSignature = getterSignature;
this.setterSignature = setterSignature;
this.syntheticMethodForAnnotations = syntheticMethodForAnnotations;
this.syntheticMethodForDelegate = syntheticMethodForDelegate;
this.contextReceiverTypes = contextReceiverTypes;
}
public static ConcreteKotlinPropertyInfo create(
KmProperty kmProperty, DexItemFactory factory, Reporter reporter) {
return new ConcreteKotlinPropertyInfo(
kmProperty,
KotlinTypeInfo.create(kmProperty.getReturnType(), factory, reporter),
KotlinTypeInfo.create(kmProperty.getReceiverParameterType(), factory, reporter),
KotlinValueParameterInfo.create(kmProperty.getSetterParameter(), factory, reporter),
KotlinTypeParameterInfo.create(kmProperty.getTypeParameters(), factory, reporter),
KotlinJvmFieldSignatureInfo.create(JvmExtensionsKt.getFieldSignature(kmProperty), factory),
KotlinJvmMethodSignatureInfo.create(
JvmExtensionsKt.getGetterSignature(kmProperty), factory),
KotlinJvmMethodSignatureInfo.create(
JvmExtensionsKt.getSetterSignature(kmProperty), factory),
KotlinJvmMethodSignatureInfo.create(
JvmExtensionsKt.getSyntheticMethodForAnnotations(kmProperty), factory),
KotlinJvmMethodSignatureInfo.create(
JvmExtensionsKt.getSyntheticMethodForDelegate(kmProperty), factory),
ListUtils.map(
kmProperty.getContextReceiverTypes(),
contextRecieverType -> KotlinTypeInfo.create(contextRecieverType, factory, reporter)));
}
@Override
public KotlinJvmFieldSignatureInfo getFieldSignature() {
return fieldSignature;
}
@Override
public KotlinJvmMethodSignatureInfo getGetterSignature() {
return getterSignature;
}
@Override
public KotlinJvmMethodSignatureInfo getSetterSignature() {
return setterSignature;
}
@Override
public boolean rewriteNoBacking(Consumer<KmProperty> consumer, AppView<?> appView) {
return rewrite(consumer, null, null, null, null, appView);
}
@Override
public boolean rewrite(
Consumer<KmProperty> consumer,
DexEncodedField field,
DexEncodedMethod getter,
DexEncodedMethod setter,
DexEncodedMethod syntheticMethodForAnnotationsMethod,
AppView<?> appView) {
KmProperty rewrittenKmProperty = new KmProperty(kmProperty.getName());
consumer.accept(rewrittenKmProperty);
KotlinFlagUtils.copyAllFlags(kmProperty, rewrittenKmProperty);
KotlinFlagUtils.copyAllFlags(kmProperty.getGetter(), rewrittenKmProperty.getGetter());
if (kmProperty.getSetter() != null) {
rewrittenKmProperty.setSetter(new KmPropertyAccessorAttributes());
KotlinFlagUtils.copyAllFlags(kmProperty.getSetter(), rewrittenKmProperty.getSetter());
}
boolean rewritten =
rewriteIfNotNull(
appView, returnType, rewrittenKmProperty::setReturnType, KotlinTypeInfo::rewrite);
rewritten |=
rewriteIfNotNull(
appView,
receiverParameterType,
rewrittenKmProperty::setReceiverParameterType,
KotlinTypeInfo::rewrite);
rewritten |=
rewriteIfNotNull(
appView,
setterParameter,
rewrittenKmProperty::setSetterParameter,
KotlinValueParameterInfo::rewrite);
rewritten |=
rewriteList(
appView,
typeParameters,
rewrittenKmProperty.getTypeParameters(),
KotlinTypeParameterInfo::rewrite);
rewritten |=
rewriteList(
appView,
contextReceiverTypes,
rewrittenKmProperty.getContextReceiverTypes(),
KotlinTypeInfo::rewrite);
rewrittenKmProperty.getVersionRequirements().addAll(kmProperty.getVersionRequirements());
if (fieldSignature != null) {
rewritten |=
fieldSignature.rewrite(
newSignature -> JvmExtensionsKt.setFieldSignature(rewrittenKmProperty, newSignature),
field,
appView);
}
if (getterSignature != null) {
rewritten |=
getterSignature.rewrite(
newSignature -> JvmExtensionsKt.setGetterSignature(rewrittenKmProperty, newSignature),
getter,
appView);
}
if (setterSignature != null) {
rewritten |=
setterSignature.rewrite(
newSignature -> JvmExtensionsKt.setSetterSignature(rewrittenKmProperty, newSignature),
setter,
appView);
}
if (syntheticMethodForAnnotations != null) {
rewritten |=
syntheticMethodForAnnotations.rewrite(
newSignature ->
JvmExtensionsKt.setSyntheticMethodForAnnotations(
rewrittenKmProperty, newSignature),
syntheticMethodForAnnotationsMethod,
appView);
}
rewritten |=
rewriteIfNotNull(
appView,
syntheticMethodForDelegate,
newMethod ->
JvmExtensionsKt.setSyntheticMethodForDelegate(rewrittenKmProperty, newMethod),
KotlinJvmMethodSignatureInfo::rewriteNoBacking);
return rewritten;
}
@Override
public void trace(DexDefinitionSupplier definitionSupplier) {
returnType.trace(definitionSupplier);
if (receiverParameterType != null) {
receiverParameterType.trace(definitionSupplier);
}
if (setterParameter != null) {
setterParameter.trace(definitionSupplier);
}
forEachApply(typeParameters, param -> param::trace, definitionSupplier);
forEachApply(contextReceiverTypes, type -> type::trace, definitionSupplier);
if (fieldSignature != null) {
fieldSignature.trace(definitionSupplier);
}
if (getterSignature != null) {
getterSignature.trace(definitionSupplier);
}
if (setterSignature != null) {
setterSignature.trace(definitionSupplier);
}
if (syntheticMethodForAnnotations != null) {
syntheticMethodForAnnotations.trace(definitionSupplier);
}
if (syntheticMethodForDelegate != null) {
syntheticMethodForDelegate.trace(definitionSupplier);
}
}
@Override
public String toString() {
return "KotlinPropertyInfo(" + kmProperty.getName() + ")";
}
}