[IR] Split implementation of DataClassMembersGenerator to IR based and descriptor based
This commit is contained in:
committed by
Space Team
parent
27f4b53570
commit
6bb7fc05df
+12
-15
@@ -6,12 +6,16 @@
|
||||
package org.jetbrains.kotlin.fir.backend.generators
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.HASHCODE_NAME
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
|
||||
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
|
||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
@@ -67,32 +71,25 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
|
||||
val lookupTag: ConeClassLikeLookupTag,
|
||||
val origin: IrDeclarationOrigin
|
||||
) {
|
||||
private val irDataClassMembersGenerator = object : DataClassMembersGenerator(
|
||||
private val irDataClassMembersGenerator = object : IrBasedDataClassMembersGenerator(
|
||||
IrGeneratorContextBase(components.irBuiltIns),
|
||||
components.symbolTable,
|
||||
irClass,
|
||||
irClass.kotlinFqName,
|
||||
origin
|
||||
origin,
|
||||
forbidDirectFieldAccess = false
|
||||
) {
|
||||
override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction {
|
||||
throw IllegalStateException("Not expect to see function declaration.")
|
||||
}
|
||||
|
||||
override fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
override fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty? =
|
||||
override fun getProperty(irValueParameter: IrValueParameter?): IrProperty =
|
||||
irValueParameter?.let {
|
||||
irClass.properties.single { irProperty ->
|
||||
irProperty.name == irValueParameter.name && irProperty.backingField?.type == irValueParameter.type
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType {
|
||||
// TODO
|
||||
return components.irBuiltIns.anyType
|
||||
}
|
||||
} ?: error("Property for parameter $irValueParameter")
|
||||
|
||||
inner class Fir2IrHashCodeFunctionInfo(override val symbol: IrSimpleFunctionSymbol) : HashCodeFunctionInfo {
|
||||
override fun commitSubstituted(irMemberAccessExpression: IrMemberAccessExpression<*>) {
|
||||
@@ -219,7 +216,7 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
|
||||
irFunction.origin = origin
|
||||
val index = DataClassResolver.getComponentIndex(irFunction.name.asString())
|
||||
val valueParameter = irClass.primaryConstructor!!.valueParameters[index - 1]
|
||||
val irProperty = irDataClassMembersGenerator.getProperty(null, valueParameter)!!
|
||||
val irProperty = irDataClassMembersGenerator.getProperty(valueParameter)
|
||||
irDataClassMembersGenerator.generateComponentFunction(irFunction, irProperty)
|
||||
}
|
||||
|
||||
|
||||
+4
-15
@@ -6,9 +6,6 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
@@ -54,29 +51,21 @@ open class LoweringDataClassMemberGenerator(
|
||||
origin: IrDeclarationOrigin,
|
||||
forbidDirectFieldAccess: Boolean = false
|
||||
) :
|
||||
DataClassMembersGenerator(
|
||||
IrBasedDataClassMembersGenerator(
|
||||
IrGeneratorContextBase(backendContext.irBuiltIns),
|
||||
backendContext.ir.symbols.externalSymbolTable,
|
||||
irClass,
|
||||
irClass.kotlinFqName,
|
||||
origin,
|
||||
forbidDirectFieldAccess
|
||||
forbidDirectFieldAccess,
|
||||
) {
|
||||
|
||||
override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction {
|
||||
error("Descriptor API shouldn't be used in lowerings")
|
||||
}
|
||||
|
||||
override fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
||||
// no-op — irFunction from lowering should already have necessary parameters
|
||||
}
|
||||
|
||||
override fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty? {
|
||||
error("Descriptor API shouldn't be used in lowerings")
|
||||
}
|
||||
|
||||
override fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType {
|
||||
error("Descriptor API shouldn't be used in lowerings")
|
||||
override fun getProperty(irValueParameter: IrValueParameter?): IrProperty {
|
||||
error("This API shouldn't be used in lowerings")
|
||||
}
|
||||
|
||||
override fun getHashCodeFunctionInfo(type: IrType): HashCodeFunctionInfo {
|
||||
|
||||
+105
-12
@@ -20,13 +20,19 @@ import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.builders.irExprBody
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator
|
||||
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
@@ -74,8 +80,10 @@ internal class DataClassMembersGenerator(
|
||||
val origin: IrDeclarationOrigin
|
||||
) : DataClassMethodGenerator(ktClassOrObject, declarationGenerator.context.bindingContext) {
|
||||
|
||||
private val irDataClassMembersGenerator = object : DataClassMembersGenerator(
|
||||
context, context.symbolTable, irClass, ktClassOrObject.fqName, origin, generateBodies = generateBodies
|
||||
private val irDataClassMembersGenerator = object : DescriptorBasedDataClassMembersGenerator(
|
||||
context, context.symbolTable, irClass, ktClassOrObject.fqName, origin,
|
||||
forbidDirectFieldAccess = false,
|
||||
generateBodies = generateBodies
|
||||
) {
|
||||
override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction =
|
||||
declareSimpleFunction(startOffset, endOffset, origin, functionDescriptor)
|
||||
@@ -84,14 +92,10 @@ internal class DataClassMembersGenerator(
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||
}
|
||||
|
||||
override fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty? =
|
||||
parameter?.let {
|
||||
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
|
||||
return getIrProperty(property)
|
||||
}
|
||||
|
||||
override fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType =
|
||||
typeParameterDescriptor.defaultType.toIrType()
|
||||
override fun getProperty(parameter: ValueParameterDescriptor): IrProperty {
|
||||
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
|
||||
return getIrProperty(property)
|
||||
}
|
||||
|
||||
private fun MemberScope.findHashCodeFunctionOrNull() =
|
||||
getContributedFunctions(Name.identifier("hashCode"), NoLookupLocation.FROM_BACKEND)
|
||||
@@ -139,12 +143,16 @@ internal class DataClassMembersGenerator(
|
||||
}
|
||||
return Psi2IrHashCodeFunctionInfo(symbol, substituted ?: symbol.descriptor)
|
||||
}
|
||||
|
||||
override fun IrConstructorSymbol.typesOfTypeParameters(): List<IrType> {
|
||||
return descriptor.typeParameters.map { it.defaultType.toIrType() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
|
||||
if (!irClass.isData) return
|
||||
|
||||
val irProperty = irDataClassMembersGenerator.getProperty(parameter, null) ?: return
|
||||
val irProperty = irDataClassMembersGenerator.getProperty(parameter)
|
||||
irDataClassMembersGenerator.generateComponentFunction(function, irProperty)
|
||||
}
|
||||
|
||||
@@ -168,3 +176,88 @@ internal class DataClassMembersGenerator(
|
||||
irDataClassMembersGenerator.generateToStringMethod(function, properties)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
private abstract class DescriptorBasedDataClassMembersGenerator(
|
||||
context: IrGeneratorContext,
|
||||
symbolTable: ReferenceSymbolTable,
|
||||
irClass: IrClass,
|
||||
fqName: FqName?,
|
||||
origin: IrDeclarationOrigin,
|
||||
forbidDirectFieldAccess: Boolean,
|
||||
val generateBodies: Boolean
|
||||
) : DataClassMembersGenerator(context, symbolTable, irClass, fqName, origin, forbidDirectFieldAccess) {
|
||||
private val irPropertiesByDescriptor: Map<PropertyDescriptor, IrProperty> =
|
||||
irClass.properties.associateBy { it.descriptor }
|
||||
|
||||
fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function) {
|
||||
generateEqualsMethodBody(properties.map { getIrProperty(it) })
|
||||
}
|
||||
}
|
||||
|
||||
fun generateComponentFunction(function: FunctionDescriptor, irProperty: IrProperty) {
|
||||
buildMember(function) {
|
||||
generateComponentFunction(irProperty)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateCopyFunction(function: FunctionDescriptor, constructorSymbol: IrConstructorSymbol) {
|
||||
buildMember(function) {
|
||||
if (generateBodies) {
|
||||
function.valueParameters.forEach { parameter ->
|
||||
putDefault(parameter, irGetProperty(irThis(), getProperty(parameter)))
|
||||
}
|
||||
generateCopyFunction(constructorSymbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function) {
|
||||
generateHashCodeMethodBody(
|
||||
properties.map { getIrProperty(it) },
|
||||
if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function) {
|
||||
generateToStringMethodBody(properties.map { getIrProperty(it) })
|
||||
}
|
||||
}
|
||||
|
||||
fun getIrProperty(property: PropertyDescriptor): IrProperty {
|
||||
return irPropertiesByDescriptor[property]
|
||||
?: error("Class: ${irClass.descriptor}: unexpected property descriptor: $property")
|
||||
}
|
||||
|
||||
|
||||
abstract fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction
|
||||
abstract fun getProperty(parameter: ValueParameterDescriptor): IrProperty
|
||||
|
||||
// Build a member from a descriptor (psi2ir) as well as its body.
|
||||
private inline fun buildMember(
|
||||
function: FunctionDescriptor,
|
||||
startOffset: Int = SYNTHETIC_OFFSET,
|
||||
endOffset: Int = SYNTHETIC_OFFSET,
|
||||
body: MemberFunctionBuilder.(IrFunction) -> Unit
|
||||
) {
|
||||
MemberFunctionBuilder(startOffset, endOffset, declareSimpleFunction(startOffset, endOffset, function)).addToClass { irFunction ->
|
||||
irFunction.buildWithScope {
|
||||
irFunction.parent = irClass
|
||||
generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||
body(irFunction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MemberFunctionBuilder.putDefault(parameter: ValueParameterDescriptor, value: IrExpression) {
|
||||
irFunction.putDefault(parameter, irExprBody(value))
|
||||
}
|
||||
|
||||
override fun IrSimpleFunctionSymbol.hasDispatchReceiver(): Boolean {
|
||||
return descriptor.dispatchReceiverParameter != null
|
||||
}
|
||||
}
|
||||
|
||||
+73
-131
@@ -5,19 +5,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.addArgument
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.putArgument
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.isNullable
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -29,7 +32,6 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
*
|
||||
* Generating synthetic members of inline class can use this as well, in particular, members from Any: equals, hashCode, and toString.
|
||||
*/
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
abstract class DataClassMembersGenerator(
|
||||
val context: IrGeneratorContext,
|
||||
val symbolTable: ReferenceSymbolTable,
|
||||
@@ -37,11 +39,7 @@ abstract class DataClassMembersGenerator(
|
||||
val fqName: FqName?,
|
||||
val origin: IrDeclarationOrigin,
|
||||
val forbidDirectFieldAccess: Boolean = false,
|
||||
val generateBodies: Boolean = false
|
||||
) {
|
||||
private val irPropertiesByDescriptor: Map<PropertyDescriptor, IrProperty> =
|
||||
irClass.properties.associateBy { it.descriptor }
|
||||
|
||||
inline fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
|
||||
also { irDeclaration ->
|
||||
symbolTable.withReferenceScope(irDeclaration) {
|
||||
@@ -52,7 +50,7 @@ abstract class DataClassMembersGenerator(
|
||||
protected val IrProperty.type
|
||||
get() = this.backingField?.type ?: this.getter?.returnType ?: error("Can't find type of ${this.render()}")
|
||||
|
||||
private inner class MemberFunctionBuilder(
|
||||
protected inner class MemberFunctionBuilder(
|
||||
startOffset: Int = SYNTHETIC_OFFSET,
|
||||
endOffset: Int = SYNTHETIC_OFFSET,
|
||||
val irFunction: IrFunction
|
||||
@@ -79,7 +77,7 @@ abstract class DataClassMembersGenerator(
|
||||
)
|
||||
}
|
||||
|
||||
fun irOther(): IrExpression {
|
||||
private fun irOther(): IrExpression {
|
||||
val irFirstParameter = irFunction.valueParameters[0]
|
||||
return IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
@@ -102,10 +100,6 @@ abstract class DataClassMembersGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
fun putDefault(parameter: ValueParameterDescriptor, value: IrExpression) {
|
||||
irFunction.putDefault(parameter, irExprBody(value))
|
||||
}
|
||||
|
||||
fun generateComponentFunction(irProperty: IrProperty) {
|
||||
+irReturn(irGetProperty(irThis(), irProperty))
|
||||
}
|
||||
@@ -117,8 +111,8 @@ abstract class DataClassMembersGenerator(
|
||||
irClass.defaultType,
|
||||
constructedClass = irClass
|
||||
).apply {
|
||||
for ((i, typeParameter) in constructorSymbol.descriptor.typeParameters.withIndex()) {
|
||||
putTypeArgument(i, transform(typeParameter))
|
||||
for ((i, typeParameterType) in constructorSymbol.typesOfTypeParameters().withIndex()) {
|
||||
putTypeArgument(i, typeParameterType)
|
||||
}
|
||||
for ((i, valueParameter) in irFunction.valueParameters.withIndex()) {
|
||||
putValueArgument(i, irGet(valueParameter.type, valueParameter.symbol))
|
||||
@@ -246,7 +240,7 @@ abstract class DataClassMembersGenerator(
|
||||
protected fun IrBuilderWithScope.getHashCodeOf(type: IrType, irValue: IrExpression): IrExpression {
|
||||
val hashCodeFunctionInfo = getHashCodeFunctionInfo(type)
|
||||
val hashCodeFunctionSymbol = hashCodeFunctionInfo.symbol
|
||||
val hasDispatchReceiver = hashCodeFunctionSymbol.descriptor.dispatchReceiverParameter != null
|
||||
val hasDispatchReceiver = hashCodeFunctionSymbol.hasDispatchReceiver()
|
||||
return irCall(
|
||||
hashCodeFunctionSymbol,
|
||||
context.irBuiltIns.intType,
|
||||
@@ -262,35 +256,69 @@ abstract class DataClassMembersGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getIrProperty(property: PropertyDescriptor): IrProperty =
|
||||
irPropertiesByDescriptor[property]
|
||||
?: throw AssertionError("Class: ${irClass.descriptor}: unexpected property descriptor: $property")
|
||||
|
||||
val IrClassifierSymbol?.isArrayOrPrimitiveArray: Boolean
|
||||
get() = isArrayOrPrimitiveArray(context.irBuiltIns)
|
||||
|
||||
abstract fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction
|
||||
|
||||
abstract fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction)
|
||||
|
||||
// Build a member from a descriptor (psi2ir) as well as its body.
|
||||
private inline fun buildMember(
|
||||
function: FunctionDescriptor,
|
||||
startOffset: Int = SYNTHETIC_OFFSET,
|
||||
endOffset: Int = SYNTHETIC_OFFSET,
|
||||
body: MemberFunctionBuilder.(IrFunction) -> Unit
|
||||
) {
|
||||
MemberFunctionBuilder(startOffset, endOffset, declareSimpleFunction(startOffset, endOffset, function)).addToClass { irFunction ->
|
||||
irFunction.buildWithScope {
|
||||
irFunction.parent = irClass
|
||||
generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||
body(irFunction)
|
||||
}
|
||||
interface HashCodeFunctionInfo {
|
||||
val symbol: IrSimpleFunctionSymbol
|
||||
fun commitSubstituted(irMemberAccessExpression: IrMemberAccessExpression<*>)
|
||||
}
|
||||
|
||||
abstract fun getHashCodeFunctionInfo(type: IrType): HashCodeFunctionInfo
|
||||
|
||||
open fun IrClass.classNameForToString(): String = irClass.name.asString()
|
||||
|
||||
protected abstract fun IrSimpleFunctionSymbol.hasDispatchReceiver(): Boolean
|
||||
protected abstract fun IrConstructorSymbol.typesOfTypeParameters(): List<IrType>
|
||||
}
|
||||
|
||||
abstract class IrBasedDataClassMembersGenerator(
|
||||
context: IrGeneratorContext,
|
||||
symbolTable: ReferenceSymbolTable,
|
||||
irClass: IrClass,
|
||||
fqName: FqName?,
|
||||
origin: IrDeclarationOrigin,
|
||||
forbidDirectFieldAccess: Boolean,
|
||||
) : DataClassMembersGenerator(context, symbolTable, irClass, fqName, origin, forbidDirectFieldAccess) {
|
||||
fun generateComponentFunction(irFunction: IrFunction, irProperty: IrProperty) {
|
||||
buildMember(irFunction) {
|
||||
generateComponentFunction(irProperty)
|
||||
}
|
||||
}
|
||||
|
||||
// Use a prebuilt member (fir2ir) and build a member body for it.
|
||||
fun generateCopyFunction(irFunction: IrFunction, constructorSymbol: IrConstructorSymbol) {
|
||||
buildMember(irFunction) {
|
||||
irFunction.valueParameters.forEach { irValueParameter ->
|
||||
irValueParameter.defaultValue = irExprBody(irGetProperty(irThis(), getProperty(irValueParameter)))
|
||||
}
|
||||
generateCopyFunction(constructorSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateEqualsMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||
buildMember(irFunction) {
|
||||
generateEqualsMethodBody(properties)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateHashCodeMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||
buildMember(irFunction) {
|
||||
generateHashCodeMethodBody(
|
||||
properties,
|
||||
if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateToStringMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||
buildMember(irFunction) {
|
||||
generateToStringMethodBody(properties)
|
||||
}
|
||||
}
|
||||
|
||||
// Use a prebuilt member and build a member body for it.
|
||||
private inline fun buildMember(
|
||||
irFunction: IrFunction,
|
||||
startOffset: Int = SYNTHETIC_OFFSET,
|
||||
@@ -305,100 +333,14 @@ abstract class DataClassMembersGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
// Entry for psi2ir
|
||||
fun generateComponentFunction(function: FunctionDescriptor, irProperty: IrProperty) {
|
||||
buildMember(function) {
|
||||
generateComponentFunction(irProperty)
|
||||
}
|
||||
abstract fun getProperty(irValueParameter: IrValueParameter?): IrProperty
|
||||
|
||||
override fun IrSimpleFunctionSymbol.hasDispatchReceiver(): Boolean {
|
||||
return owner.dispatchReceiverParameter != null
|
||||
}
|
||||
|
||||
// Entry for fir2ir
|
||||
fun generateComponentFunction(irFunction: IrFunction, irProperty: IrProperty) {
|
||||
buildMember(irFunction) {
|
||||
generateComponentFunction(irProperty)
|
||||
}
|
||||
override fun IrConstructorSymbol.typesOfTypeParameters(): List<IrType> {
|
||||
val allParameters = owner.constructedClass.typeParameters + owner.typeParameters
|
||||
return allParameters.map { it.defaultType }
|
||||
}
|
||||
|
||||
abstract fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty?
|
||||
|
||||
abstract fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType
|
||||
|
||||
// Entry for psi2ir
|
||||
fun generateCopyFunction(function: FunctionDescriptor, constructorSymbol: IrConstructorSymbol) {
|
||||
buildMember(function) {
|
||||
if (generateBodies) {
|
||||
function.valueParameters.forEach { parameter ->
|
||||
putDefault(parameter, irGetProperty(irThis(), getProperty(parameter, null)!!))
|
||||
}
|
||||
generateCopyFunction(constructorSymbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Entry for fir2ir
|
||||
fun generateCopyFunction(irFunction: IrFunction, constructorSymbol: IrConstructorSymbol) {
|
||||
buildMember(irFunction) {
|
||||
irFunction.valueParameters.forEach { irValueParameter ->
|
||||
irValueParameter.defaultValue = irExprBody(irGetProperty(irThis(), getProperty(null, irValueParameter)!!))
|
||||
}
|
||||
generateCopyFunction(constructorSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
// Entry for psi2ir
|
||||
fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function) {
|
||||
generateEqualsMethodBody(properties.map { getIrProperty(it) })
|
||||
}
|
||||
}
|
||||
|
||||
// Entry for fir2ir
|
||||
fun generateEqualsMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||
buildMember(irFunction) {
|
||||
generateEqualsMethodBody(properties)
|
||||
}
|
||||
}
|
||||
|
||||
interface HashCodeFunctionInfo {
|
||||
val symbol: IrSimpleFunctionSymbol
|
||||
fun commitSubstituted(irMemberAccessExpression: IrMemberAccessExpression<*>)
|
||||
}
|
||||
|
||||
abstract fun getHashCodeFunctionInfo(type: IrType): HashCodeFunctionInfo
|
||||
|
||||
// Entry for psi2ir
|
||||
fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function) {
|
||||
generateHashCodeMethodBody(
|
||||
properties.map { getIrProperty(it) },
|
||||
if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Entry for fir2ir
|
||||
fun generateHashCodeMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||
buildMember(irFunction) {
|
||||
generateHashCodeMethodBody(
|
||||
properties,
|
||||
if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Entry for psi2ir
|
||||
fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function) {
|
||||
generateToStringMethodBody(properties.map { getIrProperty(it) })
|
||||
}
|
||||
}
|
||||
|
||||
// Entry for fir2ir
|
||||
fun generateToStringMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||
buildMember(irFunction) {
|
||||
generateToStringMethodBody(properties)
|
||||
}
|
||||
}
|
||||
|
||||
open fun IrClass.classNameForToString(): String = irClass.name.asString()
|
||||
}
|
||||
|
||||
+1
-1
@@ -493,7 +493,7 @@ FILE fqName:<root> fileName:/dataClassWithArrayMembers.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (genericArray: kotlin.Array<T of <root>.Test2>): <root>.Test2<T of <root>.Test2> declared in <root>.Test2'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (genericArray: kotlin.Array<T of <root>.Test2>) declared in <root>.Test2' type=<root>.Test2<T of <root>.Test2> origin=null
|
||||
<class: T>: kotlin.Any
|
||||
<class: T>: T of <root>.Test2
|
||||
genericArray: GET_VAR 'genericArray: kotlin.Array<T of <root>.Test2> declared in <root>.Test2.copy' type=kotlin.Array<T of <root>.Test2> origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test2<T of <root>.Test2>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
overridden:
|
||||
|
||||
+1
-1
@@ -154,7 +154,7 @@ data class Test2<T : Any?> {
|
||||
}
|
||||
|
||||
fun copy(genericArray: Array<T> = <this>.#genericArray): Test2<T> {
|
||||
return Test2<Any>(genericArray = genericArray)
|
||||
return Test2<T>(genericArray = genericArray)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
|
||||
+3
-3
@@ -33,7 +33,7 @@ FILE fqName:<root> fileName:/dataClassesGeneric.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test1): <root>.Test1<T of <root>.Test1> declared in <root>.Test1'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test1) declared in <root>.Test1' type=<root>.Test1<T of <root>.Test1> origin=null
|
||||
<class: T>: kotlin.Any
|
||||
<class: T>: T of <root>.Test1
|
||||
x: GET_VAR 'x: T of <root>.Test1 declared in <root>.Test1.copy' type=T of <root>.Test1 origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test1<T of <root>.Test1>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
overridden:
|
||||
@@ -133,7 +133,7 @@ FILE fqName:<root> fileName:/dataClassesGeneric.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test2): <root>.Test2<T of <root>.Test2> declared in <root>.Test2'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test2) declared in <root>.Test2' type=<root>.Test2<T of <root>.Test2> origin=null
|
||||
<class: T>: kotlin.Any
|
||||
<class: T>: T of <root>.Test2
|
||||
x: GET_VAR 'x: T of <root>.Test2 declared in <root>.Test2.copy' type=T of <root>.Test2 origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test2<T of <root>.Test2>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
overridden:
|
||||
@@ -224,7 +224,7 @@ FILE fqName:<root> fileName:/dataClassesGeneric.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (x: kotlin.collections.List<T of <root>.Test3>): <root>.Test3<T of <root>.Test3> declared in <root>.Test3'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (x: kotlin.collections.List<T of <root>.Test3>) declared in <root>.Test3' type=<root>.Test3<T of <root>.Test3> origin=null
|
||||
<class: T>: kotlin.Any
|
||||
<class: T>: T of <root>.Test3
|
||||
x: GET_VAR 'x: kotlin.collections.List<T of <root>.Test3> declared in <root>.Test3.copy' type=kotlin.collections.List<T of <root>.Test3> origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test3<T of <root>.Test3>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
overridden:
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ data class Test1<T : Any?> {
|
||||
}
|
||||
|
||||
fun copy(x: T = <this>.#x): Test1<T> {
|
||||
return Test1<Any>(x = x)
|
||||
return Test1<T>(x = x)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
@@ -60,7 +60,7 @@ data class Test2<T : Number> {
|
||||
}
|
||||
|
||||
fun copy(x: T = <this>.#x): Test2<T> {
|
||||
return Test2<Any>(x = x)
|
||||
return Test2<T>(x = x)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
@@ -103,7 +103,7 @@ data class Test3<T : Any?> {
|
||||
}
|
||||
|
||||
fun copy(x: List<T> = <this>.#x): Test3<T> {
|
||||
return Test3<Any>(x = x)
|
||||
return Test3<T>(x = x)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
|
||||
+2
-2
@@ -56,8 +56,8 @@ FILE fqName:<root> fileName:/compareTo.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (first: A of <root>.Pair, second: B of <root>.Pair): <root>.Pair<A of <root>.Pair, B of <root>.Pair> declared in <root>.Pair'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (first: A of <root>.Pair, second: B of <root>.Pair) declared in <root>.Pair' type=<root>.Pair<A of <root>.Pair, B of <root>.Pair> origin=null
|
||||
<class: A>: kotlin.Any
|
||||
<class: B>: kotlin.Any
|
||||
<class: A>: A of <root>.Pair
|
||||
<class: B>: B of <root>.Pair
|
||||
first: GET_VAR 'first: A of <root>.Pair declared in <root>.Pair.copy' type=A of <root>.Pair origin=null
|
||||
second: GET_VAR 'second: B of <root>.Pair declared in <root>.Pair.copy' type=B of <root>.Pair origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Pair<A of <root>.Pair, B of <root>.Pair>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ data class Pair<A : Any?, B : Any?> {
|
||||
}
|
||||
|
||||
fun copy(first: A = <this>.#first, second: B = <this>.#second): Pair<A, B> {
|
||||
return Pair<Any, Any>(first = first, second = second)
|
||||
return Pair<A, B>(first = first, second = second)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ FILE fqName:<root> fileName:/dataClassMembers.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test, y: kotlin.String): <root>.Test<T of <root>.Test> declared in <root>.Test'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test, y: kotlin.String) declared in <root>.Test' type=<root>.Test<T of <root>.Test> origin=null
|
||||
<class: T>: kotlin.Any
|
||||
<class: T>: T of <root>.Test
|
||||
x: GET_VAR 'x: T of <root>.Test declared in <root>.Test.copy' type=T of <root>.Test origin=null
|
||||
y: GET_VAR 'y: kotlin.String declared in <root>.Test.copy' type=kotlin.String origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test<T of <root>.Test>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ data class Test<T : Any?> {
|
||||
}
|
||||
|
||||
fun copy(x: T = <this>.#x, y: String = <this>.#y): Test<T> {
|
||||
return Test<Any>(x = x, y = y)
|
||||
return Test<T>(x = x, y = y)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
|
||||
@@ -742,7 +742,7 @@ FILE fqName:<root> fileName:/ArrayMap.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (key: kotlin.Int, value: T of <root>.ArrayMapImpl.Entry): <root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry> declared in <root>.ArrayMapImpl.Entry'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (key: kotlin.Int, value: T of <root>.ArrayMapImpl.Entry) declared in <root>.ArrayMapImpl.Entry' type=<root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry> origin=null
|
||||
<class: T>: kotlin.Any
|
||||
<class: T>: T of <root>.ArrayMapImpl.Entry
|
||||
key: GET_VAR 'key: kotlin.Int declared in <root>.ArrayMapImpl.Entry.copy' type=kotlin.Int origin=null
|
||||
value: GET_VAR 'value: T of <root>.ArrayMapImpl.Entry declared in <root>.ArrayMapImpl.Entry.copy' type=T of <root>.ArrayMapImpl.Entry origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
|
||||
@@ -292,7 +292,7 @@ internal class ArrayMapImpl<T : Any> : ArrayMap<T> {
|
||||
}
|
||||
|
||||
fun copy(key: Int = <this>.#key, value: T = <this>.#value): Entry<T> {
|
||||
return Entry<Any>(key = key, value = value)
|
||||
return Entry<T>(key = key, value = value)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
|
||||
@@ -33,7 +33,7 @@ FILE fqName:<root> fileName:/MultiList.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (value: T of <root>.Some): <root>.Some<T of <root>.Some> declared in <root>.Some'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (value: T of <root>.Some) declared in <root>.Some' type=<root>.Some<T of <root>.Some> origin=null
|
||||
<class: T>: kotlin.Any
|
||||
<class: T>: T of <root>.Some
|
||||
value: GET_VAR 'value: T of <root>.Some declared in <root>.Some.copy' type=T of <root>.Some origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Some<T of <root>.Some>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
overridden:
|
||||
|
||||
@@ -14,7 +14,7 @@ data class Some<T : Any?> {
|
||||
}
|
||||
|
||||
fun copy(value: T = <this>.#value): Some<T> {
|
||||
return Some<Any>(value = value)
|
||||
return Some<T>(value = value)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
|
||||
@@ -75,7 +75,7 @@ FILE fqName:<root> fileName:/kt45236.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (error: kotlin.Throwable, value: T of <root>.NetRequestStatus.Error?): <root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error> declared in <root>.NetRequestStatus.Error'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (error: kotlin.Throwable, value: T of <root>.NetRequestStatus.Error?) declared in <root>.NetRequestStatus.Error' type=<root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error> origin=null
|
||||
<class: T>: kotlin.Any
|
||||
<class: T>: T of <root>.NetRequestStatus.Error
|
||||
error: GET_VAR 'error: kotlin.Throwable declared in <root>.NetRequestStatus.Error.copy' type=kotlin.Throwable origin=null
|
||||
value: GET_VAR 'value: T of <root>.NetRequestStatus.Error? declared in <root>.NetRequestStatus.Error.copy' type=T of <root>.NetRequestStatus.Error? origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
|
||||
@@ -35,7 +35,7 @@ FILE fqName:<root> fileName:/typeAliasWithUnsafeVariance.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun copy (action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit>): <root>.Tag<RenderingT of <root>.Tag> declared in <root>.Tag'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit>) declared in <root>.Tag' type=<root>.Tag<RenderingT of <root>.Tag> origin=null
|
||||
<class: RenderingT>: kotlin.Any
|
||||
<class: RenderingT>: RenderingT of <root>.Tag
|
||||
action: GET_VAR 'action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit> declared in <root>.Tag.copy' type=kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit> origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Tag<RenderingT of <root>.Tag>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||
overridden:
|
||||
|
||||
@@ -15,7 +15,7 @@ data class Tag<out RenderingT : Any?> {
|
||||
}
|
||||
|
||||
fun copy(action: Function1<RenderingT, Unit> = <this>.#action): Tag<RenderingT> {
|
||||
return Tag<Any>(action = action)
|
||||
return Tag<RenderingT>(action = action)
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user