[FIR2IR] Extract createIrSyntheticFunction/Parameter from data class gen

This commit is contained in:
Mikhail Glukhikh
2020-04-13 12:56:35 +03:00
parent 4f1caf24a1
commit b6cf08d097
@@ -13,16 +13,13 @@ import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedValueParameterDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator
import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -78,20 +75,44 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) {
// TODO: consolidate componentN() and copy(...) too? // TODO: consolidate componentN() and copy(...) too?
// TODO: generate equals, hashCode, and toString only if needed // TODO: generate equals, hashCode, and toString only if needed
val equalsDescriptor = WrappedSimpleFunctionDescriptor() val equalsFunction = createSyntheticIrFunction(
val equalsDispatchReceiverDescriptor = WrappedValueParameterDescriptor() Name.identifier("equals"),
val equalsValueParameterDescriptor = WrappedValueParameterDescriptor() components.irBuiltIns.booleanType,
val equalsFunction = ).apply {
components.symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, equalsDescriptor) { symbol -> valueParameters = listOf(
createSyntheticIrParameter(this, Name.identifier("other"), components.irBuiltIns.anyNType)
)
}
irDataClassMembersGenerator.generateEqualsMethod(equalsFunction, properties)
val hashCodeFunction = createSyntheticIrFunction(
Name.identifier("hashCode"),
components.irBuiltIns.intType,
)
irDataClassMembersGenerator.generateHashCodeMethod(hashCodeFunction, properties)
val toStringFunction = createSyntheticIrFunction(
Name.identifier("toString"),
components.irBuiltIns.stringType,
)
irDataClassMembersGenerator.generateToStringMethod(toStringFunction, properties)
return listOf(equalsFunction.name, hashCodeFunction.name, toStringFunction.name)
}
private fun createSyntheticIrFunction(name: Name, returnType: IrType): IrFunction {
val functionDescriptor = WrappedSimpleFunctionDescriptor()
val thisReceiverDescriptor = WrappedValueParameterDescriptor()
return components.symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, functionDescriptor) { symbol ->
IrFunctionImpl( IrFunctionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
origin, origin,
symbol, symbol,
Name.identifier("equals"), name,
Visibilities.PUBLIC, Visibilities.PUBLIC,
Modality.OPEN, Modality.OPEN,
components.irBuiltIns.booleanType, returnType,
isInline = false, isInline = false,
isExternal = false, isExternal = false,
isTailrec = false, isTailrec = false,
@@ -100,102 +121,40 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) {
isFakeOverride = false, isFakeOverride = false,
isOperator = false isOperator = false
).apply { ).apply {
metadata = MetadataSource.Function(descriptor) metadata = MetadataSource.Function(functionDescriptor)
} }
}.apply { }.apply {
parent = irClass parent = irClass
equalsDescriptor.bind(this) functionDescriptor.bind(this)
dispatchReceiverParameter = generateDispatchReceiverParameter(this, equalsDispatchReceiverDescriptor) dispatchReceiverParameter = generateDispatchReceiverParameter(this, thisReceiverDescriptor)
val irFunction = this }
valueParameters = listOf( }
components.symbolTable.declareValueParameter(
private fun createSyntheticIrParameter(irFunction: IrFunction, name: Name, type: IrType): IrValueParameter {
val descriptor = WrappedValueParameterDescriptor()
return components.symbolTable.declareValueParameter(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
origin, origin,
equalsValueParameterDescriptor, descriptor,
components.irBuiltIns.anyNType type
) { symbol -> ) { symbol ->
IrValueParameterImpl( IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
origin, origin,
symbol, symbol,
Name.identifier("other"), name,
0, 0,
components.irBuiltIns.anyNType, type,
null, null,
isCrossinline = false, isCrossinline = false,
isNoinline = false isNoinline = false
) )
}.apply { }.apply {
parent = irFunction parent = irFunction
equalsValueParameterDescriptor.bind(this) descriptor.bind(this)
} }
)
}
irDataClassMembersGenerator.generateEqualsMethod(equalsFunction, properties)
val hashCodeDescriptor = WrappedSimpleFunctionDescriptor()
val hashCodeDispatchReceiverDescriptor = WrappedValueParameterDescriptor()
val hashCodeFunction =
components.symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, hashCodeDescriptor) { symbol ->
IrFunctionImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
origin,
symbol,
Name.identifier("hashCode"),
Visibilities.PUBLIC,
Modality.OPEN,
components.irBuiltIns.intType,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false,
isExpect = false,
isFakeOverride = false,
isOperator = false
).apply {
metadata = MetadataSource.Function(descriptor)
}
}.apply {
parent = irClass
hashCodeDescriptor.bind(this)
dispatchReceiverParameter = generateDispatchReceiverParameter(this, hashCodeDispatchReceiverDescriptor)
}
irDataClassMembersGenerator.generateHashCodeMethod(hashCodeFunction, properties)
val toStringDescriptor = WrappedSimpleFunctionDescriptor()
val toStringDispatchReceiverDescriptor = WrappedValueParameterDescriptor()
val toStringFunction =
components.symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, toStringDescriptor) { symbol ->
IrFunctionImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
origin,
symbol,
Name.identifier("toString"),
Visibilities.PUBLIC,
Modality.OPEN,
components.irBuiltIns.stringType,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false,
isExpect = false,
isFakeOverride = false,
isOperator = false
).apply {
metadata = MetadataSource.Function(descriptor)
}
}.apply {
parent = irClass
toStringDescriptor.bind(this)
dispatchReceiverParameter = generateDispatchReceiverParameter(this, toStringDispatchReceiverDescriptor)
}
irDataClassMembersGenerator.generateToStringMethod(toStringFunction, properties)
return listOf(equalsFunction.name, hashCodeFunction.name, toStringFunction.name)
} }
} }
} }