| // 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.consume; |
| 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 kotlinx.metadata.KmProperty; |
| import kotlinx.metadata.jvm.JvmExtensionsKt; |
| |
| // Holds information about KmProperty |
| public class KotlinPropertyInfo implements KotlinFieldLevelInfo, KotlinMethodLevelInfo { |
| |
| // Original flags. |
| private final int flags; |
| |
| // Original getter flags. E.g., for property getter. |
| private final int getterFlags; |
| |
| // Original setter flags. E.g., for property setter. |
| private final int setterFlags; |
| |
| // Original property name for (extension) property. Otherwise, null. |
| private final String name; |
| |
| // 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 KotlinVersionRequirementInfo versionRequirements; |
| |
| private final int jvmFlags; |
| |
| 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 KotlinPropertyInfo( |
| int flags, |
| int getterFlags, |
| int setterFlags, |
| String name, |
| KotlinTypeInfo returnType, |
| KotlinTypeInfo receiverParameterType, |
| KotlinValueParameterInfo setterParameter, |
| List<KotlinTypeParameterInfo> typeParameters, |
| KotlinVersionRequirementInfo versionRequirements, |
| int jvmFlags, |
| KotlinJvmFieldSignatureInfo fieldSignature, |
| KotlinJvmMethodSignatureInfo getterSignature, |
| KotlinJvmMethodSignatureInfo setterSignature, |
| KotlinJvmMethodSignatureInfo syntheticMethodForAnnotations, |
| KotlinJvmMethodSignatureInfo syntheticMethodForDelegate, |
| List<KotlinTypeInfo> contextReceiverTypes) { |
| this.flags = flags; |
| this.getterFlags = getterFlags; |
| this.setterFlags = setterFlags; |
| this.name = name; |
| this.returnType = returnType; |
| this.receiverParameterType = receiverParameterType; |
| this.setterParameter = setterParameter; |
| this.typeParameters = typeParameters; |
| this.versionRequirements = versionRequirements; |
| this.jvmFlags = jvmFlags; |
| this.fieldSignature = fieldSignature; |
| this.getterSignature = getterSignature; |
| this.setterSignature = setterSignature; |
| this.syntheticMethodForAnnotations = syntheticMethodForAnnotations; |
| this.syntheticMethodForDelegate = syntheticMethodForDelegate; |
| this.contextReceiverTypes = contextReceiverTypes; |
| } |
| |
| public static KotlinPropertyInfo create( |
| KmProperty kmProperty, DexItemFactory factory, Reporter reporter) { |
| return new KotlinPropertyInfo( |
| kmProperty.getFlags(), |
| kmProperty.getGetterFlags(), |
| kmProperty.getSetterFlags(), |
| kmProperty.getName(), |
| KotlinTypeInfo.create(kmProperty.getReturnType(), factory, reporter), |
| KotlinTypeInfo.create(kmProperty.getReceiverParameterType(), factory, reporter), |
| KotlinValueParameterInfo.create(kmProperty.getSetterParameter(), factory, reporter), |
| KotlinTypeParameterInfo.create(kmProperty.getTypeParameters(), factory, reporter), |
| KotlinVersionRequirementInfo.create(kmProperty.getVersionRequirements()), |
| JvmExtensionsKt.getJvmFlags(kmProperty), |
| 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 boolean isProperty() { |
| return true; |
| } |
| |
| @Override |
| public KotlinPropertyInfo asProperty() { |
| return this; |
| } |
| |
| public KotlinJvmFieldSignatureInfo getFieldSignature() { |
| return fieldSignature; |
| } |
| |
| public KotlinJvmMethodSignatureInfo getGetterSignature() { |
| return getterSignature; |
| } |
| |
| public KotlinJvmMethodSignatureInfo getSetterSignature() { |
| return setterSignature; |
| } |
| |
| boolean rewriteNoBacking(Consumer<KmProperty> consumer, AppView<?> appView) { |
| return rewrite(consumer, null, null, null, appView); |
| } |
| |
| boolean rewrite( |
| Consumer<KmProperty> consumer, |
| DexEncodedField field, |
| DexEncodedMethod getter, |
| DexEncodedMethod setter, |
| AppView<?> appView) { |
| // TODO(b/154348683): Flags again. |
| KmProperty kmProperty = |
| consume(new KmProperty(flags, name, getterFlags, setterFlags), consumer); |
| // TODO(b/154348149): ReturnType could have been merged to a subtype. |
| boolean rewritten = |
| rewriteIfNotNull(appView, returnType, kmProperty::setReturnType, KotlinTypeInfo::rewrite); |
| rewritten |= |
| rewriteIfNotNull( |
| appView, |
| receiverParameterType, |
| kmProperty::setReceiverParameterType, |
| KotlinTypeInfo::rewrite); |
| rewritten |= |
| rewriteIfNotNull( |
| appView, |
| setterParameter, |
| kmProperty::setSetterParameter, |
| KotlinValueParameterInfo::rewrite); |
| rewritten |= |
| rewriteList( |
| appView, |
| typeParameters, |
| kmProperty.getTypeParameters(), |
| KotlinTypeParameterInfo::rewrite); |
| rewritten |= |
| rewriteList( |
| appView, |
| contextReceiverTypes, |
| kmProperty.getContextReceiverTypes(), |
| KotlinTypeInfo::rewrite); |
| rewritten |= versionRequirements.rewrite(kmProperty.getVersionRequirements()::addAll); |
| if (fieldSignature != null) { |
| rewritten |= |
| fieldSignature.rewrite( |
| newSignature -> JvmExtensionsKt.setFieldSignature(kmProperty, newSignature), |
| field, |
| appView); |
| } |
| if (getterSignature != null) { |
| rewritten |= |
| getterSignature.rewrite( |
| newSignature -> JvmExtensionsKt.setGetterSignature(kmProperty, newSignature), |
| getter, |
| appView); |
| } |
| if (setterSignature != null) { |
| rewritten |= |
| setterSignature.rewrite( |
| newSignature -> JvmExtensionsKt.setSetterSignature(kmProperty, newSignature), |
| setter, |
| appView); |
| } |
| JvmExtensionsKt.setJvmFlags(kmProperty, jvmFlags); |
| rewritten |= |
| rewriteIfNotNull( |
| appView, |
| syntheticMethodForAnnotations, |
| newMethod -> JvmExtensionsKt.setSyntheticMethodForAnnotations(kmProperty, newMethod), |
| KotlinJvmMethodSignatureInfo::rewriteNoBacking); |
| rewritten |= |
| rewriteIfNotNull( |
| appView, |
| syntheticMethodForDelegate, |
| newMethod -> JvmExtensionsKt.setSyntheticMethodForDelegate(kmProperty, newMethod), |
| KotlinJvmMethodSignatureInfo::rewriteNoBacking); |
| return rewritten; |
| } |
| |
| @Override |
| public void trace(DexDefinitionSupplier definitionSupplier) { |
| if (returnType != null) { |
| 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); |
| } |
| } |
| } |