FIR: refactor member generations for data class
This commit is contained in:
committed by
Mikhail Glukhikh
parent
d4cbfcb79e
commit
948f9debdc
+88
-91
@@ -642,104 +642,101 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<Pair<T, FirProperty>>.generateComponentFunctions(
|
inner class DataClassMemberGenerator(
|
||||||
session: FirSession, firClassBuilder: AbstractFirRegularClassBuilder, packageFqName: FqName, classFqName: FqName,
|
private val session: FirSession,
|
||||||
firPrimaryConstructor: FirConstructor,
|
private val source: T,
|
||||||
|
private val classBuilder: AbstractFirRegularClassBuilder,
|
||||||
|
private val classTypeRef: FirTypeRef,
|
||||||
|
private val zippedParameters: List<Pair<T, FirProperty>>,
|
||||||
|
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 {
|
fun generateMembers() {
|
||||||
source = parameterSource
|
generateComponentFunctions()
|
||||||
result = buildQualifiedAccessExpression {
|
generateCopyFunction()
|
||||||
source = parameterSource
|
// TODO: equals, hashCode, toString
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private val copyName = Name.identifier("copy")
|
private inline fun generateComponentAccess(parameterSource: FirSourceElement?, firProperty: FirProperty) =
|
||||||
|
buildQualifiedAccessExpression {
|
||||||
fun List<Pair<T, FirProperty>>.generateCopyFunction(
|
source = parameterSource
|
||||||
session: FirSession,
|
dispatchReceiver = buildThisReceiverExpression {
|
||||||
classOrObject: T,
|
calleeReference = buildImplicitThisReference {
|
||||||
classBuilder: AbstractFirRegularClassBuilder,
|
boundSymbol = classBuilder.symbol
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
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 {
|
private fun FirVariable<*>.toQualifiedAccess(): FirQualifiedAccessExpression = buildQualifiedAccessExpression {
|
||||||
|
|||||||
+9
-7
@@ -467,13 +467,15 @@ class DeclarationsConverter(
|
|||||||
//parse data class
|
//parse data class
|
||||||
if (modifiers.isDataClass() && firPrimaryConstructor != null) {
|
if (modifiers.isDataClass() && firPrimaryConstructor != null) {
|
||||||
val zippedParameters = properties.map { it.source?.lightNode!! to it }
|
val zippedParameters = properties.map { it.source?.lightNode!! to it }
|
||||||
zippedParameters.generateComponentFunctions(
|
DataClassMemberGenerator(
|
||||||
baseSession, this, context.packageFqName, context.className, firPrimaryConstructor
|
baseSession,
|
||||||
)
|
classNode,
|
||||||
zippedParameters.generateCopyFunction(
|
this,
|
||||||
baseSession, classNode, this, context.packageFqName, context.className, firPrimaryConstructor
|
firPrimaryConstructor.returnTypeRef,
|
||||||
)
|
zippedParameters,
|
||||||
// TODO: equals, hashCode, toString
|
context.packageFqName,
|
||||||
|
context.className
|
||||||
|
).generateMembers()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifiers.isEnum()) {
|
if (modifiers.isEnum()) {
|
||||||
|
|||||||
@@ -693,13 +693,15 @@ class RawFirBuilder(
|
|||||||
val zippedParameters = classOrObject.primaryConstructorParameters.zip(
|
val zippedParameters = classOrObject.primaryConstructorParameters.zip(
|
||||||
declarations.filterIsInstance<FirProperty>(),
|
declarations.filterIsInstance<FirProperty>(),
|
||||||
)
|
)
|
||||||
zippedParameters.generateComponentFunctions(
|
DataClassMemberGenerator(
|
||||||
baseSession, this, context.packageFqName, context.className, firPrimaryConstructor,
|
baseSession,
|
||||||
)
|
classOrObject,
|
||||||
zippedParameters.generateCopyFunction(
|
this,
|
||||||
baseSession, classOrObject, this, context.packageFqName, context.className, firPrimaryConstructor,
|
firPrimaryConstructor.returnTypeRef,
|
||||||
)
|
zippedParameters,
|
||||||
// TODO: equals, hashCode, toString
|
context.packageFqName,
|
||||||
|
context.className
|
||||||
|
).generateMembers()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classOrObject.hasModifier(ENUM_KEYWORD)) {
|
if (classOrObject.hasModifier(ENUM_KEYWORD)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user