From 6bb7fc05df48ea1b50264e16af996810381588f8 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 22 Jun 2023 11:25:53 +0300 Subject: [PATCH] [IR] Split implementation of DataClassMembersGenerator to IR based and descriptor based --- .../generators/DataClassMembersGenerator.kt | 27 ++- .../MethodsFromAnyGeneratorForLowerings.kt | 19 +- .../generators/DataClassMembersGenerator.kt | 117 ++++++++-- .../ir/util/DataClassMembersGenerator.kt | 204 +++++++----------- .../dataClassWithArrayMembers.fir.ir.txt | 2 +- .../dataClassWithArrayMembers.fir.kt.txt | 2 +- .../dataClasses/dataClassesGeneric.fir.ir.txt | 6 +- .../dataClasses/dataClassesGeneric.fir.kt.txt | 6 +- .../fromKEEP/compareTo.fir.ir.txt | 4 +- .../fromKEEP/compareTo.fir.kt.txt | 2 +- .../parameters/dataClassMembers.fir.ir.txt | 2 +- .../parameters/dataClassMembers.fir.kt.txt | 2 +- .../ir/irText/firProblems/ArrayMap.fir.ir.txt | 2 +- .../ir/irText/firProblems/ArrayMap.fir.kt.txt | 2 +- .../irText/firProblems/MultiList.fir.ir.txt | 2 +- .../irText/firProblems/MultiList.fir.kt.txt | 2 +- .../ir/irText/regressions/kt45236.fir.ir.txt | 2 +- .../typeAliasWithUnsafeVariance.fir.ir.txt | 2 +- .../typeAliasWithUnsafeVariance.fir.kt.txt | 2 +- 19 files changed, 214 insertions(+), 193 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt index c0d7418bdff..07ed57d58cc 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt @@ -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) } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/MethodsFromAnyGeneratorForLowerings.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/MethodsFromAnyGeneratorForLowerings.kt index 798447e4a2c..b52046d1cb0 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/MethodsFromAnyGeneratorForLowerings.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/MethodsFromAnyGeneratorForLowerings.kt @@ -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 { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt index 0b33f181d5b..ddbf33fc77e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt @@ -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 { + 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 = + irClass.properties.associateBy { it.descriptor } + + fun generateEqualsMethod(function: FunctionDescriptor, properties: List) { + 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) { + buildMember(function) { + generateHashCodeMethodBody( + properties.map { getIrProperty(it) }, + if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0 + ) + } + } + + fun generateToStringMethod(function: FunctionDescriptor, properties: List) { + 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 + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt index a3e1df7fe63..522b3702a11 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt @@ -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 = - irClass.properties.associateBy { it.descriptor } - inline fun 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 +} + +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) { + buildMember(irFunction) { + generateEqualsMethodBody(properties) + } + } + + fun generateHashCodeMethod(irFunction: IrFunction, properties: List) { + buildMember(irFunction) { + generateHashCodeMethodBody( + properties, + if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0 + ) + } + } + + fun generateToStringMethod(irFunction: IrFunction, properties: List) { + 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 { + 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) { - buildMember(function) { - generateEqualsMethodBody(properties.map { getIrProperty(it) }) - } - } - - // Entry for fir2ir - fun generateEqualsMethod(irFunction: IrFunction, properties: List) { - 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) { - 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) { - buildMember(irFunction) { - generateHashCodeMethodBody( - properties, - if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0 - ) - } - } - - // Entry for psi2ir - fun generateToStringMethod(function: FunctionDescriptor, properties: List) { - buildMember(function) { - generateToStringMethodBody(properties.map { getIrProperty(it) }) - } - } - - // Entry for fir2ir - fun generateToStringMethod(irFunction: IrFunction, properties: List) { - buildMember(irFunction) { - generateToStringMethodBody(properties) - } - } - - open fun IrClass.classNameForToString(): String = irClass.name.asString() } diff --git a/compiler/testData/ir/irText/classes/dataClasses/dataClassWithArrayMembers.fir.ir.txt b/compiler/testData/ir/irText/classes/dataClasses/dataClassWithArrayMembers.fir.ir.txt index 4d533b8bad2..229f1d8af9a 100644 --- a/compiler/testData/ir/irText/classes/dataClasses/dataClassWithArrayMembers.fir.ir.txt +++ b/compiler/testData/ir/irText/classes/dataClasses/dataClassWithArrayMembers.fir.ir.txt @@ -493,7 +493,7 @@ FILE fqName: fileName:/dataClassWithArrayMembers.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (genericArray: kotlin.Array.Test2>): .Test2.Test2> declared in .Test2' CONSTRUCTOR_CALL 'public constructor (genericArray: kotlin.Array.Test2>) declared in .Test2' type=.Test2.Test2> origin=null - : kotlin.Any + : T of .Test2 genericArray: GET_VAR 'genericArray: kotlin.Array.Test2> declared in .Test2.copy' type=kotlin.Array.Test2> origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.Test2.Test2>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] overridden: diff --git a/compiler/testData/ir/irText/classes/dataClasses/dataClassWithArrayMembers.fir.kt.txt b/compiler/testData/ir/irText/classes/dataClasses/dataClassWithArrayMembers.fir.kt.txt index f3621cbba61..81085535665 100644 --- a/compiler/testData/ir/irText/classes/dataClasses/dataClassWithArrayMembers.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/dataClasses/dataClassWithArrayMembers.fir.kt.txt @@ -154,7 +154,7 @@ data class Test2 { } fun copy(genericArray: Array = .#genericArray): Test2 { - return Test2(genericArray = genericArray) + return Test2(genericArray = genericArray) } override operator fun equals(other: Any?): Boolean { diff --git a/compiler/testData/ir/irText/classes/dataClasses/dataClassesGeneric.fir.ir.txt b/compiler/testData/ir/irText/classes/dataClasses/dataClassesGeneric.fir.ir.txt index f60c068bf73..639850825e6 100644 --- a/compiler/testData/ir/irText/classes/dataClasses/dataClassesGeneric.fir.ir.txt +++ b/compiler/testData/ir/irText/classes/dataClasses/dataClassesGeneric.fir.ir.txt @@ -33,7 +33,7 @@ FILE fqName: fileName:/dataClassesGeneric.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (x: T of .Test1): .Test1.Test1> declared in .Test1' CONSTRUCTOR_CALL 'public constructor (x: T of .Test1) declared in .Test1' type=.Test1.Test1> origin=null - : kotlin.Any + : T of .Test1 x: GET_VAR 'x: T of .Test1 declared in .Test1.copy' type=T of .Test1 origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.Test1.Test1>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] overridden: @@ -133,7 +133,7 @@ FILE fqName: fileName:/dataClassesGeneric.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (x: T of .Test2): .Test2.Test2> declared in .Test2' CONSTRUCTOR_CALL 'public constructor (x: T of .Test2) declared in .Test2' type=.Test2.Test2> origin=null - : kotlin.Any + : T of .Test2 x: GET_VAR 'x: T of .Test2 declared in .Test2.copy' type=T of .Test2 origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.Test2.Test2>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] overridden: @@ -224,7 +224,7 @@ FILE fqName: fileName:/dataClassesGeneric.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (x: kotlin.collections.List.Test3>): .Test3.Test3> declared in .Test3' CONSTRUCTOR_CALL 'public constructor (x: kotlin.collections.List.Test3>) declared in .Test3' type=.Test3.Test3> origin=null - : kotlin.Any + : T of .Test3 x: GET_VAR 'x: kotlin.collections.List.Test3> declared in .Test3.copy' type=kotlin.collections.List.Test3> origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.Test3.Test3>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] overridden: diff --git a/compiler/testData/ir/irText/classes/dataClasses/dataClassesGeneric.fir.kt.txt b/compiler/testData/ir/irText/classes/dataClasses/dataClassesGeneric.fir.kt.txt index fd1fde42277..8c6a5bc273c 100644 --- a/compiler/testData/ir/irText/classes/dataClasses/dataClassesGeneric.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/dataClasses/dataClassesGeneric.fir.kt.txt @@ -14,7 +14,7 @@ data class Test1 { } fun copy(x: T = .#x): Test1 { - return Test1(x = x) + return Test1(x = x) } override operator fun equals(other: Any?): Boolean { @@ -60,7 +60,7 @@ data class Test2 { } fun copy(x: T = .#x): Test2 { - return Test2(x = x) + return Test2(x = x) } override operator fun equals(other: Any?): Boolean { @@ -103,7 +103,7 @@ data class Test3 { } fun copy(x: List = .#x): Test3 { - return Test3(x = x) + return Test3(x = x) } override operator fun equals(other: Any?): Boolean { diff --git a/compiler/testData/ir/irText/declarations/contextReceivers/fromKEEP/compareTo.fir.ir.txt b/compiler/testData/ir/irText/declarations/contextReceivers/fromKEEP/compareTo.fir.ir.txt index 15b7527d82c..232582b98ed 100644 --- a/compiler/testData/ir/irText/declarations/contextReceivers/fromKEEP/compareTo.fir.ir.txt +++ b/compiler/testData/ir/irText/declarations/contextReceivers/fromKEEP/compareTo.fir.ir.txt @@ -56,8 +56,8 @@ FILE fqName: fileName:/compareTo.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (first: A of .Pair, second: B of .Pair): .Pair.Pair, B of .Pair> declared in .Pair' CONSTRUCTOR_CALL 'public constructor (first: A of .Pair, second: B of .Pair) declared in .Pair' type=.Pair.Pair, B of .Pair> origin=null - : kotlin.Any - : kotlin.Any + : A of .Pair + : B of .Pair first: GET_VAR 'first: A of .Pair declared in .Pair.copy' type=A of .Pair origin=null second: GET_VAR 'second: B of .Pair declared in .Pair.copy' type=B of .Pair origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.Pair.Pair, B of .Pair>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] diff --git a/compiler/testData/ir/irText/declarations/contextReceivers/fromKEEP/compareTo.fir.kt.txt b/compiler/testData/ir/irText/declarations/contextReceivers/fromKEEP/compareTo.fir.kt.txt index 0fbf7a9b107..44c08706868 100644 --- a/compiler/testData/ir/irText/declarations/contextReceivers/fromKEEP/compareTo.fir.kt.txt +++ b/compiler/testData/ir/irText/declarations/contextReceivers/fromKEEP/compareTo.fir.kt.txt @@ -22,7 +22,7 @@ data class Pair { } fun copy(first: A = .#first, second: B = .#second): Pair { - return Pair(first = first, second = second) + return Pair(first = first, second = second) } override operator fun equals(other: Any?): Boolean { diff --git a/compiler/testData/ir/irText/declarations/parameters/dataClassMembers.fir.ir.txt b/compiler/testData/ir/irText/declarations/parameters/dataClassMembers.fir.ir.txt index ada175cbe27..fd502a0a293 100644 --- a/compiler/testData/ir/irText/declarations/parameters/dataClassMembers.fir.ir.txt +++ b/compiler/testData/ir/irText/declarations/parameters/dataClassMembers.fir.ir.txt @@ -57,7 +57,7 @@ FILE fqName: fileName:/dataClassMembers.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (x: T of .Test, y: kotlin.String): .Test.Test> declared in .Test' CONSTRUCTOR_CALL 'public constructor (x: T of .Test, y: kotlin.String) declared in .Test' type=.Test.Test> origin=null - : kotlin.Any + : T of .Test x: GET_VAR 'x: T of .Test declared in .Test.copy' type=T of .Test origin=null y: GET_VAR 'y: kotlin.String declared in .Test.copy' type=kotlin.String origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.Test.Test>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] diff --git a/compiler/testData/ir/irText/declarations/parameters/dataClassMembers.fir.kt.txt b/compiler/testData/ir/irText/declarations/parameters/dataClassMembers.fir.kt.txt index 514f5cdc0f6..f436e22b2d5 100644 --- a/compiler/testData/ir/irText/declarations/parameters/dataClassMembers.fir.kt.txt +++ b/compiler/testData/ir/irText/declarations/parameters/dataClassMembers.fir.kt.txt @@ -22,7 +22,7 @@ data class Test { } fun copy(x: T = .#x, y: String = .#y): Test { - return Test(x = x, y = y) + return Test(x = x, y = y) } override operator fun equals(other: Any?): Boolean { diff --git a/compiler/testData/ir/irText/firProblems/ArrayMap.fir.ir.txt b/compiler/testData/ir/irText/firProblems/ArrayMap.fir.ir.txt index edb30e13106..26617c1c52a 100644 --- a/compiler/testData/ir/irText/firProblems/ArrayMap.fir.ir.txt +++ b/compiler/testData/ir/irText/firProblems/ArrayMap.fir.ir.txt @@ -742,7 +742,7 @@ FILE fqName: fileName:/ArrayMap.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (key: kotlin.Int, value: T of .ArrayMapImpl.Entry): .ArrayMapImpl.Entry.ArrayMapImpl.Entry> declared in .ArrayMapImpl.Entry' CONSTRUCTOR_CALL 'public constructor (key: kotlin.Int, value: T of .ArrayMapImpl.Entry) declared in .ArrayMapImpl.Entry' type=.ArrayMapImpl.Entry.ArrayMapImpl.Entry> origin=null - : kotlin.Any + : T of .ArrayMapImpl.Entry key: GET_VAR 'key: kotlin.Int declared in .ArrayMapImpl.Entry.copy' type=kotlin.Int origin=null value: GET_VAR 'value: T of .ArrayMapImpl.Entry declared in .ArrayMapImpl.Entry.copy' type=T of .ArrayMapImpl.Entry origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.ArrayMapImpl.Entry.ArrayMapImpl.Entry>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] diff --git a/compiler/testData/ir/irText/firProblems/ArrayMap.fir.kt.txt b/compiler/testData/ir/irText/firProblems/ArrayMap.fir.kt.txt index ad7b3006226..9dd98ba68f5 100644 --- a/compiler/testData/ir/irText/firProblems/ArrayMap.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/ArrayMap.fir.kt.txt @@ -292,7 +292,7 @@ internal class ArrayMapImpl : ArrayMap { } fun copy(key: Int = .#key, value: T = .#value): Entry { - return Entry(key = key, value = value) + return Entry(key = key, value = value) } override operator fun equals(other: Any?): Boolean { diff --git a/compiler/testData/ir/irText/firProblems/MultiList.fir.ir.txt b/compiler/testData/ir/irText/firProblems/MultiList.fir.ir.txt index 47f6eb3cae4..f3ae8b50f3e 100644 --- a/compiler/testData/ir/irText/firProblems/MultiList.fir.ir.txt +++ b/compiler/testData/ir/irText/firProblems/MultiList.fir.ir.txt @@ -33,7 +33,7 @@ FILE fqName: fileName:/MultiList.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (value: T of .Some): .Some.Some> declared in .Some' CONSTRUCTOR_CALL 'public constructor (value: T of .Some) declared in .Some' type=.Some.Some> origin=null - : kotlin.Any + : T of .Some value: GET_VAR 'value: T of .Some declared in .Some.copy' type=T of .Some origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.Some.Some>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] overridden: diff --git a/compiler/testData/ir/irText/firProblems/MultiList.fir.kt.txt b/compiler/testData/ir/irText/firProblems/MultiList.fir.kt.txt index 75b8b459572..576b60d31f5 100644 --- a/compiler/testData/ir/irText/firProblems/MultiList.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/MultiList.fir.kt.txt @@ -14,7 +14,7 @@ data class Some { } fun copy(value: T = .#value): Some { - return Some(value = value) + return Some(value = value) } override operator fun equals(other: Any?): Boolean { diff --git a/compiler/testData/ir/irText/regressions/kt45236.fir.ir.txt b/compiler/testData/ir/irText/regressions/kt45236.fir.ir.txt index f785480c3d5..cfff7216c66 100644 --- a/compiler/testData/ir/irText/regressions/kt45236.fir.ir.txt +++ b/compiler/testData/ir/irText/regressions/kt45236.fir.ir.txt @@ -75,7 +75,7 @@ FILE fqName: fileName:/kt45236.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (error: kotlin.Throwable, value: T of .NetRequestStatus.Error?): .NetRequestStatus.Error.NetRequestStatus.Error> declared in .NetRequestStatus.Error' CONSTRUCTOR_CALL 'public constructor (error: kotlin.Throwable, value: T of .NetRequestStatus.Error?) declared in .NetRequestStatus.Error' type=.NetRequestStatus.Error.NetRequestStatus.Error> origin=null - : kotlin.Any + : T of .NetRequestStatus.Error error: GET_VAR 'error: kotlin.Throwable declared in .NetRequestStatus.Error.copy' type=kotlin.Throwable origin=null value: GET_VAR 'value: T of .NetRequestStatus.Error? declared in .NetRequestStatus.Error.copy' type=T of .NetRequestStatus.Error? origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.NetRequestStatus.Error.NetRequestStatus.Error>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] diff --git a/compiler/testData/ir/irText/types/typeAliasWithUnsafeVariance.fir.ir.txt b/compiler/testData/ir/irText/types/typeAliasWithUnsafeVariance.fir.ir.txt index befbc8c2486..dde3cdc69c4 100644 --- a/compiler/testData/ir/irText/types/typeAliasWithUnsafeVariance.fir.ir.txt +++ b/compiler/testData/ir/irText/types/typeAliasWithUnsafeVariance.fir.ir.txt @@ -35,7 +35,7 @@ FILE fqName: fileName:/typeAliasWithUnsafeVariance.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun copy (action: kotlin.Function1.Tag, kotlin.Unit>): .Tag.Tag> declared in .Tag' CONSTRUCTOR_CALL 'public constructor (action: kotlin.Function1.Tag, kotlin.Unit>) declared in .Tag' type=.Tag.Tag> origin=null - : kotlin.Any + : RenderingT of .Tag action: GET_VAR 'action: kotlin.Function1.Tag, kotlin.Unit> declared in .Tag.copy' type=kotlin.Function1.Tag, kotlin.Unit> origin=null FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.Tag.Tag>, other:kotlin.Any?) returnType:kotlin.Boolean [operator] overridden: diff --git a/compiler/testData/ir/irText/types/typeAliasWithUnsafeVariance.fir.kt.txt b/compiler/testData/ir/irText/types/typeAliasWithUnsafeVariance.fir.kt.txt index 2cdfff5d69f..e72122e415e 100644 --- a/compiler/testData/ir/irText/types/typeAliasWithUnsafeVariance.fir.kt.txt +++ b/compiler/testData/ir/irText/types/typeAliasWithUnsafeVariance.fir.kt.txt @@ -15,7 +15,7 @@ data class Tag { } fun copy(action: Function1 = .#action): Tag { - return Tag(action = action) + return Tag(action = action) } override operator fun equals(other: Any?): Boolean {