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 30f536003f4..64581c7d642 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 @@ -21,8 +21,9 @@ import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.mapValueParameters import org.jetbrains.kotlin.psi.KtClassOrObject @@ -42,7 +43,11 @@ class DataClassMembersGenerator( override val context: GeneratorContext, val irClass: IrClassImpl ) : Generator, DataClassMethodGenerator(ktClassOrObject, context.bindingContext) { - private inline fun buildMember(function: FunctionDescriptor, psiElement: PsiElement? = null, body: IrMemberFunctionBuilder.() -> Unit) { + private inline fun buildMember( + function: FunctionDescriptor, + psiElement: PsiElement? = null, + body: IrMemberFunctionBuilder.(IrFunction) -> Unit + ) { IrMemberFunctionBuilder( context, irClass, function, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER, psiElement?.startOffset ?: UNDEFINED_OFFSET, psiElement?.endOffset ?: UNDEFINED_OFFSET @@ -65,6 +70,10 @@ class DataClassMembersGenerator( throw AssertionError("Data class should have a primary constructor: $classDescriptor") buildMember(function) { + function.valueParameters.forEach { parameter -> + val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter) + putDefault(parameter, irGet(irThis(), property)) + } +irReturn(irCall(dataClassConstructor).mapValueParameters { irGet(function.valueParameters[it.index]) }) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt index b11a7bdc99a..b2b62b959b6 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt @@ -51,6 +51,9 @@ fun IrStatementsBuilder.defineTemporaryVar(value: IrExpressio return temporary.descriptor } +fun IrBuilderWithScope.irExprBody(value: IrExpression) = + IrExpressionBodyImpl(startOffset, endOffset, value) + fun IrBuilderWithScope.irReturn(value: IrExpression) = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scope.assertCastOwner(), value) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrBuilder.kt index 2612c5b475c..84798aed078 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrBuilder.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrBuilder.kt @@ -49,7 +49,7 @@ abstract class IrStatementsBuilder( } protected abstract fun addStatement(irStatement: IrStatement) - protected abstract fun doBuild(): T + abstract fun doBuild(): T } open class IrBlockBodyBuilder( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrMemberFunctionBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrMemberFunctionBuilder.kt index 74ada793237..fe0eb258ce9 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrMemberFunctionBuilder.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/IrMemberFunctionBuilder.kt @@ -17,10 +17,13 @@ package org.jetbrains.kotlin.ir.builders import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.expressions.IrExpression class IrMemberFunctionBuilder( context: IrGeneratorContext, @@ -30,10 +33,16 @@ class IrMemberFunctionBuilder( startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET ) : IrBlockBodyBuilder(context, Scope(function), startOffset, endOffset) { - inline fun addToClass(body: IrMemberFunctionBuilder.() -> Unit) { - val irFunction = IrFunctionImpl(startOffset, endOffset, origin, function) - body() + lateinit var irFunction: IrFunction + + inline fun addToClass(body: IrMemberFunctionBuilder.(IrFunction) -> Unit) { + irFunction = IrFunctionImpl(startOffset, endOffset, origin, function) + body(irFunction) irFunction.body = doBuild() irClass.addMember(irFunction) } + + fun putDefault(parameter: ValueParameterDescriptor, value: IrExpression) { + irFunction.putDefault(parameter, irExprBody(value)) + } } \ No newline at end of file diff --git a/compiler/testData/ir/irText/classes/dataClasses.txt b/compiler/testData/ir/irText/classes/dataClasses.txt index c97e0a41452..e6fe2245874 100644 --- a/compiler/testData/ir/irText/classes/dataClasses.txt +++ b/compiler/testData/ir/irText/classes/dataClasses.txt @@ -47,6 +47,15 @@ FILE /dataClasses.kt CALL '(): Any' type=kotlin.Any origin=GET_PROPERTY $this: GET_VAR '' type=Test1 origin=null FUN GENERATED_DATA_CLASS_MEMBER public final fun copy(x: kotlin.Int = ..., y: kotlin.String = ..., z: kotlin.Any = ...): Test1 + x: EXPRESSION_BODY + CALL '(): Int' type=kotlin.Int origin=GET_PROPERTY + $this: GET_VAR '' type=Test1 origin=null + y: EXPRESSION_BODY + CALL '(): String' type=kotlin.String origin=GET_PROPERTY + $this: GET_VAR '' type=Test1 origin=null + z: EXPRESSION_BODY + CALL '(): Any' type=kotlin.Any origin=GET_PROPERTY + $this: GET_VAR '' type=Test1 origin=null BLOCK_BODY RETURN type=kotlin.Nothing from='copy(Int = ..., String = ..., Any = ...): Test1' CALL 'constructor Test1(Int, String, Any)' type=Test1 origin=null