diff --git a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 2d891ae4909..5ff3edb052f 100644 --- a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -642,104 +642,101 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte } } - fun List>.generateComponentFunctions( - session: FirSession, firClassBuilder: AbstractFirRegularClassBuilder, packageFqName: FqName, classFqName: FqName, - firPrimaryConstructor: FirConstructor, + inner class DataClassMemberGenerator( + private val session: FirSession, + private val source: T, + private val classBuilder: AbstractFirRegularClassBuilder, + private val classTypeRef: FirTypeRef, + private val zippedParameters: List>, + private val packageFqName: FqName, + private val classFqName: FqName, ) { - var componentIndex = 1 - for ((sourceNode, firProperty) in this) { - if (!firProperty.isVal && !firProperty.isVar) continue - val name = Name.identifier("component$componentIndex") - componentIndex++ - val parameterSource = sourceNode?.toFirSourceElement() - val target = FirFunctionTarget(labelName = null, isLambda = false) - val componentFunction = buildSimpleFunction { - source = parameterSource - this.session = session - returnTypeRef = buildImplicitTypeRef { - source = parameterSource - } - receiverTypeRef = null - this.name = name - this.status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL) - this.symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, name)) - val returnExpression = buildReturnExpression { - source = parameterSource - result = buildQualifiedAccessExpression { - source = parameterSource - dispatchReceiver = buildThisReceiverExpression { - calleeReference = buildImplicitThisReference { - boundSymbol = firClassBuilder.symbol - } - typeRef = firPrimaryConstructor.returnTypeRef - } - calleeReference = buildResolvedNamedReference { - source = parameterSource - this.name = firProperty.name - resolvedSymbol = firProperty.symbol - } - } - this.target = target - } - body = buildSingleExpressionBlock(returnExpression) - }.also { - target.bind(it) - } - firClassBuilder.addDeclaration(componentFunction) + fun generateMembers() { + generateComponentFunctions() + generateCopyFunction() + // TODO: equals, hashCode, toString } - } - private val copyName = Name.identifier("copy") - - fun List>.generateCopyFunction( - session: FirSession, - classOrObject: T, - classBuilder: AbstractFirRegularClassBuilder, - packageFqName: FqName, - classFqName: FqName, - firPrimaryConstructor: FirConstructor, - ) { - classBuilder.addDeclaration( - buildSimpleFunction { - source = classOrObject?.toFirSourceElement() - this.session = session - returnTypeRef = firPrimaryConstructor.returnTypeRef - name = copyName - status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL) - symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, copyName)) - for ((ktParameter, firProperty) in this@generateCopyFunction) { - val propertyName = firProperty.name - val parameterSource = ktParameter?.toFirSourceElement() - valueParameters += buildValueParameter { - source = parameterSource - this.session = session - returnTypeRef = firProperty.returnTypeRef - name = propertyName - symbol = FirVariableSymbol(propertyName) - defaultValue = buildQualifiedAccessExpression { - source = parameterSource - dispatchReceiver = buildThisReceiverExpression { - calleeReference = buildImplicitThisReference { - boundSymbol = classBuilder.symbol - } - typeRef = firPrimaryConstructor.returnTypeRef - } - calleeReference = buildResolvedNamedReference { - source = parameterSource - this.name = propertyName - resolvedSymbol = firProperty.symbol - } - } - isCrossinline = false - isNoinline = false - isVararg = false + private inline fun generateComponentAccess(parameterSource: FirSourceElement?, firProperty: FirProperty) = + buildQualifiedAccessExpression { + source = parameterSource + dispatchReceiver = buildThisReceiverExpression { + calleeReference = buildImplicitThisReference { + boundSymbol = classBuilder.symbol } + typeRef = classTypeRef } + calleeReference = buildResolvedNamedReference { + source = parameterSource + this.name = firProperty.name + resolvedSymbol = firProperty.symbol + } + } - body = buildEmptyExpressionBlock() - }, - ) + private fun generateComponentFunctions() { + var componentIndex = 1 + for ((sourceNode, firProperty) in zippedParameters) { + if (!firProperty.isVal && !firProperty.isVar) continue + val name = Name.identifier("component$componentIndex") + componentIndex++ + val parameterSource = sourceNode?.toFirSourceElement() + val target = FirFunctionTarget(labelName = null, isLambda = false) + val componentFunction = buildSimpleFunction { + source = parameterSource + session = this@DataClassMemberGenerator.session + returnTypeRef = buildImplicitTypeRef { + source = parameterSource + } + receiverTypeRef = null + this.name = name + status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL) + symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, name)) + + val returnExpression = buildReturnExpression { + source = parameterSource + result = generateComponentAccess(parameterSource, firProperty) + this.target = target + } + body = buildSingleExpressionBlock(returnExpression) + }.also { + target.bind(it) + } + classBuilder.addDeclaration(componentFunction) + } + } + + private val copyName = Name.identifier("copy") + + private fun generateCopyFunction() { + classBuilder.addDeclaration( + buildSimpleFunction { + source = this@DataClassMemberGenerator.source.toFirSourceElement() + session = this@DataClassMemberGenerator.session + returnTypeRef = classTypeRef + name = copyName + status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL) + symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, copyName)) + for ((ktParameter, firProperty) in zippedParameters) { + val propertyName = firProperty.name + val parameterSource = ktParameter?.toFirSourceElement() + valueParameters += buildValueParameter { + source = parameterSource + session = this@DataClassMemberGenerator.session + returnTypeRef = firProperty.returnTypeRef + name = propertyName + symbol = FirVariableSymbol(propertyName) + defaultValue = generateComponentAccess(parameterSource, firProperty) + isCrossinline = false + isNoinline = false + isVararg = false + } + } + + body = buildEmptyExpressionBlock() + }, + ) + } } private fun FirVariable<*>.toQualifiedAccess(): FirQualifiedAccessExpression = buildQualifiedAccessExpression { diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 08a4ff9a868..e5087c4e785 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -467,13 +467,15 @@ class DeclarationsConverter( //parse data class if (modifiers.isDataClass() && firPrimaryConstructor != null) { val zippedParameters = properties.map { it.source?.lightNode!! to it } - zippedParameters.generateComponentFunctions( - baseSession, this, context.packageFqName, context.className, firPrimaryConstructor - ) - zippedParameters.generateCopyFunction( - baseSession, classNode, this, context.packageFqName, context.className, firPrimaryConstructor - ) - // TODO: equals, hashCode, toString + DataClassMemberGenerator( + baseSession, + classNode, + this, + firPrimaryConstructor.returnTypeRef, + zippedParameters, + context.packageFqName, + context.className + ).generateMembers() } if (modifiers.isEnum()) { diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 215a2d0a84e..94f897b6291 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -693,13 +693,15 @@ class RawFirBuilder( val zippedParameters = classOrObject.primaryConstructorParameters.zip( declarations.filterIsInstance(), ) - zippedParameters.generateComponentFunctions( - baseSession, this, context.packageFqName, context.className, firPrimaryConstructor, - ) - zippedParameters.generateCopyFunction( - baseSession, classOrObject, this, context.packageFqName, context.className, firPrimaryConstructor, - ) - // TODO: equals, hashCode, toString + DataClassMemberGenerator( + baseSession, + classOrObject, + this, + firPrimaryConstructor.returnTypeRef, + zippedParameters, + context.packageFqName, + context.className + ).generateMembers() } if (classOrObject.hasModifier(ENUM_KEYWORD)) {