Remove descriptors from EnumClassLowering
This commit is contained in:
+123
-101
@@ -8,29 +8,31 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
|||||||
import gnu.trove.TObjectIntHashMap
|
import gnu.trove.TObjectIntHashMap
|
||||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedFieldDescriptor
|
||||||
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.createValueParameter
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.types.toIrType
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi2ir.findSingleFunction
|
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
internal val enumClassPhase = makeIrFilePhase(
|
internal val enumClassPhase = makeIrFilePhase(
|
||||||
@@ -51,30 +53,30 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
fun transform(delegatingConstructorCall: IrDelegatingConstructorCall): IrExpression
|
fun transform(delegatingConstructorCall: IrDelegatingConstructorCall): IrExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
private val arrayOfFun = context.ir.symbols.arrayOf.owner
|
private fun createArrayOfExpression(arrayElementType: IrSimpleType, arrayElements: List<IrExpression>): IrExpression {
|
||||||
private val unsubstitutedArrayOfFunDescriptor = arrayOfFun.descriptor
|
val arrayOfFun = context.ir.symbols.arrayOf.owner
|
||||||
|
|
||||||
private fun createArrayOfExpression(arrayElementType: KotlinType, arrayElements: List<IrExpression>): IrExpression {
|
/* Substituted descriptor is only needed to construct IrCall */
|
||||||
|
val unsubstitutedArrayOfFunDescriptor = arrayOfFun.descriptor
|
||||||
val typeParameter0 = unsubstitutedArrayOfFunDescriptor.typeParameters[0]
|
val typeParameter0 = unsubstitutedArrayOfFunDescriptor.typeParameters[0]
|
||||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType)))
|
val typeSubstitutor = TypeSubstitutor.create(
|
||||||
|
mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType.toKotlinType()))
|
||||||
|
)
|
||||||
val substitutedArrayOfDescriptor = unsubstitutedArrayOfFunDescriptor.substitute(typeSubstitutor)!!
|
val substitutedArrayOfDescriptor = unsubstitutedArrayOfFunDescriptor.substitute(typeSubstitutor)!!
|
||||||
|
|
||||||
|
val arrayType = context.irBuiltIns.arrayClass.typeWith(arrayElementType)
|
||||||
val valueParameter0 = substitutedArrayOfDescriptor.valueParameters[0]
|
|
||||||
val arg0VarargType = valueParameter0.type
|
|
||||||
val arg0VarargElementType = valueParameter0.varargElementType!!
|
|
||||||
val arg0 =
|
val arg0 =
|
||||||
IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arg0VarargType.toIrType()!!, arg0VarargElementType.toIrType()!!, arrayElements)
|
IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arrayType, arrayElementType, arrayElements)
|
||||||
|
|
||||||
return IrCallImpl(
|
return IrCallImpl(
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
substitutedArrayOfDescriptor.returnType!!.toIrType()!!,
|
arrayType,
|
||||||
arrayOfFun.symbol,
|
arrayOfFun.symbol,
|
||||||
substitutedArrayOfDescriptor,
|
substitutedArrayOfDescriptor,
|
||||||
arrayOfFun.typeParameters.size
|
arrayOfFun.typeParameters.size
|
||||||
).apply {
|
).apply {
|
||||||
putTypeArgument(0, arrayElementType.toIrType()!!)
|
putTypeArgument(0, arrayElementType)
|
||||||
putValueArgument(0, arg0)
|
putValueArgument(0, arg0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,8 +84,8 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
private inner class EnumClassTransformer(val irClass: IrClass) {
|
private inner class EnumClassTransformer(val irClass: IrClass) {
|
||||||
private val enumEntryOrdinals = TObjectIntHashMap<IrEnumEntry>()
|
private val enumEntryOrdinals = TObjectIntHashMap<IrEnumEntry>()
|
||||||
private val enumEntryClassToEntry = HashMap<IrClass, IrEnumEntry>()
|
private val enumEntryClassToEntry = HashMap<IrClass, IrEnumEntry>()
|
||||||
private val loweredEnumConstructors = HashMap<ClassConstructorDescriptor, IrConstructorImpl>()
|
private val loweredEnumConstructors = HashMap<IrConstructorSymbol, IrConstructorImpl>()
|
||||||
private val loweredEnumConstructorParameters = HashMap<ValueParameterDescriptor, IrValueParameter>()
|
private val loweredEnumConstructorParameters = HashMap<IrValueParameterSymbol, IrValueParameter>()
|
||||||
private val enumEntriesByField = HashMap<IrField, IrEnumEntry>()
|
private val enumEntriesByField = HashMap<IrField, IrEnumEntry>()
|
||||||
private val enumEntryFields = ArrayList<IrField>()
|
private val enumEntryFields = ArrayList<IrField>()
|
||||||
|
|
||||||
@@ -125,56 +127,73 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
enumConstructor: IrConstructor,
|
enumConstructor: IrConstructor,
|
||||||
enumClass: IrClass
|
enumClass: IrClass
|
||||||
): IrConstructor {
|
): IrConstructor {
|
||||||
val constructorDescriptor = enumConstructor.descriptor
|
val descriptor = WrappedClassConstructorDescriptor(enumConstructor.descriptor.annotations, enumConstructor.descriptor.source)
|
||||||
val loweredConstructorDescriptor = lowerEnumConstructor(constructorDescriptor)
|
|
||||||
return IrConstructorImpl(
|
return IrConstructorImpl(
|
||||||
enumConstructor.startOffset, enumConstructor.endOffset, enumConstructor.origin,
|
enumConstructor.startOffset, enumConstructor.endOffset,
|
||||||
loweredConstructorDescriptor,
|
enumConstructor.origin,
|
||||||
loweredConstructorDescriptor.returnType.toIrType()!!,
|
IrConstructorSymbolImpl(descriptor),
|
||||||
enumConstructor.body!! // will be transformed later
|
enumConstructor.name,
|
||||||
|
Visibilities.PROTECTED,
|
||||||
|
returnType = enumConstructor.returnType,
|
||||||
|
isInline = enumConstructor.isInline,
|
||||||
|
isExternal = enumConstructor.isExternal,
|
||||||
|
isPrimary = enumConstructor.isPrimary
|
||||||
).apply {
|
).apply {
|
||||||
|
val newConstructor = this
|
||||||
|
descriptor.bind(this)
|
||||||
parent = enumClass
|
parent = enumClass
|
||||||
createParameterDeclarations()
|
|
||||||
loweredEnumConstructors[constructorDescriptor] = this
|
val nameParameter = makeNameValueParameter(newConstructor)
|
||||||
constructorDescriptor.valueParameters.forEach {
|
val ordinalParameter = makeOrdinalValueParameter(newConstructor)
|
||||||
loweredEnumConstructorParameters[it] = valueParameters[2 + it.index]
|
valueParameters.add(0, nameParameter)
|
||||||
}
|
valueParameters.add(1, ordinalParameter)
|
||||||
|
valueParameters.addAll(enumConstructor.valueParameters.map { param ->
|
||||||
|
param.copyTo(newConstructor, index = param.index + 2).also { newParam ->
|
||||||
|
loweredEnumConstructorParameters[param.symbol] = newParam
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
body = enumConstructor.body // will be transformed later
|
||||||
|
|
||||||
|
loweredEnumConstructors[enumConstructor.symbol] = this
|
||||||
metadata = enumConstructor.metadata
|
metadata = enumConstructor.metadata
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun lowerEnumConstructor(constructorDescriptor: ClassConstructorDescriptor): ClassConstructorDescriptor {
|
private fun makeNameValueParameter(constructor: IrConstructor): IrValueParameter {
|
||||||
val loweredConstructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
val descriptor = WrappedValueParameterDescriptor()
|
||||||
constructorDescriptor.containingDeclaration,
|
return IrValueParameterImpl(
|
||||||
constructorDescriptor.annotations,
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
constructorDescriptor.isPrimary,
|
IrDeclarationOrigin.DEFINED,
|
||||||
constructorDescriptor.source
|
IrValueParameterSymbolImpl(descriptor),
|
||||||
)
|
Name.identifier("name"),
|
||||||
|
index = 0,
|
||||||
val valueParameters =
|
type = context.irBuiltIns.stringType,
|
||||||
listOf(
|
varargElementType = null,
|
||||||
loweredConstructorDescriptor.createValueParameter(0, "name", context.builtIns.stringType),
|
isCrossinline = false,
|
||||||
loweredConstructorDescriptor.createValueParameter(1, "ordinal", context.builtIns.intType)
|
isNoinline = false
|
||||||
) +
|
).apply {
|
||||||
constructorDescriptor.valueParameters.map {
|
descriptor.bind(this)
|
||||||
lowerConstructorValueParameter(loweredConstructorDescriptor, it)
|
parent = constructor
|
||||||
}
|
}
|
||||||
loweredConstructorDescriptor.initialize(valueParameters, Visibilities.PROTECTED)
|
|
||||||
|
|
||||||
loweredConstructorDescriptor.returnType = constructorDescriptor.returnType
|
|
||||||
|
|
||||||
return loweredConstructorDescriptor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun lowerConstructorValueParameter(
|
private fun makeOrdinalValueParameter(constructor: IrConstructor): IrValueParameter {
|
||||||
loweredConstructorDescriptor: ClassConstructorDescriptor,
|
val descriptor = WrappedValueParameterDescriptor()
|
||||||
valueParameterDescriptor: ValueParameterDescriptor
|
return IrValueParameterImpl(
|
||||||
): ValueParameterDescriptor {
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
return valueParameterDescriptor.copy(
|
IrDeclarationOrigin.DEFINED,
|
||||||
loweredConstructorDescriptor,
|
IrValueParameterSymbolImpl(descriptor),
|
||||||
valueParameterDescriptor.name,
|
Name.identifier("ordinal"),
|
||||||
valueParameterDescriptor.index + 2
|
index = 1,
|
||||||
)
|
type = context.irBuiltIns.intType,
|
||||||
|
varargElementType = null,
|
||||||
|
isCrossinline = false,
|
||||||
|
isNoinline = false
|
||||||
|
).apply {
|
||||||
|
descriptor.bind(this)
|
||||||
|
parent = constructor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun lowerEnumEntries() {
|
private fun lowerEnumEntries() {
|
||||||
@@ -224,39 +243,37 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
|
|
||||||
|
|
||||||
private fun createSyntheticValuesFieldDeclaration(): IrFieldImpl {
|
private fun createSyntheticValuesFieldDeclaration(): IrFieldImpl {
|
||||||
val valuesArrayType = context.builtIns.getArrayType(Variance.INVARIANT, irClass.descriptor.defaultType)
|
val valuesArrayType = context.irBuiltIns.arrayClass.typeWith(irClass.defaultType)
|
||||||
|
|
||||||
val irValuesInitializer = createSyntheticValuesFieldInitializerExpression()
|
val irValuesInitializer = createSyntheticValuesFieldInitializerExpression()
|
||||||
|
|
||||||
|
val descriptor = WrappedFieldDescriptor()
|
||||||
|
// TODO: mark ACC_SYNTHETIC
|
||||||
return IrFieldImpl(
|
return IrFieldImpl(
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
|
||||||
createSyntheticValuesFieldDescriptor(valuesArrayType),
|
IrFieldSymbolImpl(descriptor),
|
||||||
valuesArrayType.toIrType()!!,
|
Name.identifier("\$VALUES"),
|
||||||
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer)
|
valuesArrayType,
|
||||||
|
Visibilities.PRIVATE,
|
||||||
|
isFinal = true,
|
||||||
|
isExternal = false,
|
||||||
|
isStatic = true
|
||||||
).also {
|
).also {
|
||||||
|
descriptor.bind(it)
|
||||||
it.parent = irClass
|
it.parent = irClass
|
||||||
|
it.initializer = IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer)
|
||||||
|
|
||||||
valuesField = it
|
valuesField = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSyntheticValuesFieldInitializerExpression(): IrExpression =
|
private fun createSyntheticValuesFieldInitializerExpression(): IrExpression =
|
||||||
createArrayOfExpression(
|
createArrayOfExpression(
|
||||||
irClass.defaultType.toKotlinType(),
|
irClass.defaultType,
|
||||||
enumEntryFields.map { irField ->
|
enumEntryFields.map { irField ->
|
||||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irField.symbol, irField.symbol.owner.type)
|
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irField.symbol, irField.symbol.owner.type)
|
||||||
})
|
})
|
||||||
|
|
||||||
private fun createSyntheticValuesFieldDescriptor(valuesArrayType: SimpleType): PropertyDescriptorImpl {
|
|
||||||
return JvmPropertyDescriptorImpl.createStaticVal(
|
|
||||||
Name.identifier("\$VALUES"),
|
|
||||||
valuesArrayType,
|
|
||||||
irClass.descriptor,
|
|
||||||
Annotations.EMPTY,
|
|
||||||
Modality.FINAL, Visibilities.PRIVATE, Opcodes.ACC_SYNTHETIC,
|
|
||||||
irClass.descriptor.source
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun lowerEnumClassBody() {
|
private fun lowerEnumClassBody() {
|
||||||
irClass.transformChildrenVoid(EnumClassBodyTransformer())
|
irClass.transformChildrenVoid(EnumClassBodyTransformer())
|
||||||
}
|
}
|
||||||
@@ -277,7 +294,10 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
enumConstructorCall.typeArgumentsCount
|
enumConstructorCall.typeArgumentsCount
|
||||||
)
|
)
|
||||||
|
|
||||||
assert(result.descriptor.valueParameters.size == 2) {
|
assert(enumConstructorCall.typeArgumentsCount == 1) { "Enum<T> call expected:\n${result.dump()}" }
|
||||||
|
result.putTypeArgument(0, enumConstructorCall.getTypeArgument(0))
|
||||||
|
|
||||||
|
assert(result.symbol.owner.valueParameters.size == 2) {
|
||||||
"Enum(String, Int) constructor call expected:\n${result.dump()}"
|
"Enum(String, Int) constructor call expected:\n${result.dump()}"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,12 +316,11 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transform(delegatingConstructorCall: IrDelegatingConstructorCall): IrExpression {
|
override fun transform(delegatingConstructorCall: IrDelegatingConstructorCall): IrExpression {
|
||||||
val descriptor = delegatingConstructorCall.descriptor
|
|
||||||
val startOffset = delegatingConstructorCall.startOffset
|
val startOffset = delegatingConstructorCall.startOffset
|
||||||
val endOffset = delegatingConstructorCall.endOffset
|
val endOffset = delegatingConstructorCall.endOffset
|
||||||
|
|
||||||
val loweredDelegatedConstructor = loweredEnumConstructors.getOrElse(descriptor) {
|
val loweredDelegatedConstructor = loweredEnumConstructors.getOrElse(delegatingConstructorCall.symbol) {
|
||||||
throw AssertionError("Constructor called in enum entry initializer should've been lowered: $descriptor")
|
throw AssertionError("Constructor called in enum entry initializer should've been lowered: ${delegatingConstructorCall.symbol}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = IrDelegatingConstructorCallImpl(
|
val result = IrDelegatingConstructorCallImpl(
|
||||||
@@ -313,10 +332,12 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
loweredDelegatedConstructor.typeParameters.size
|
loweredDelegatedConstructor.typeParameters.size
|
||||||
)
|
)
|
||||||
|
|
||||||
|
assert(loweredDelegatedConstructor.typeParameters.size == 0) { "Enum delegating call expected:\n${result.dump()}" }
|
||||||
|
|
||||||
result.putValueArgument(0, IrGetValueImpl(startOffset, endOffset, irEnumConstructor.valueParameters[0].symbol))
|
result.putValueArgument(0, IrGetValueImpl(startOffset, endOffset, irEnumConstructor.valueParameters[0].symbol))
|
||||||
result.putValueArgument(1, IrGetValueImpl(startOffset, endOffset, irEnumConstructor.valueParameters[1].symbol))
|
result.putValueArgument(1, IrGetValueImpl(startOffset, endOffset, irEnumConstructor.valueParameters[1].symbol))
|
||||||
|
|
||||||
descriptor.valueParameters.forEach { valueParameter ->
|
delegatingConstructorCall.symbol.owner.valueParameters.forEach { valueParameter ->
|
||||||
val i = valueParameter.index
|
val i = valueParameter.index
|
||||||
result.putValueArgument(i + 2, delegatingConstructorCall.getValueArgument(i))
|
result.putValueArgument(i + 2, delegatingConstructorCall.getValueArgument(i))
|
||||||
}
|
}
|
||||||
@@ -330,12 +351,11 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
val name = enumEntry.name.asString()
|
val name = enumEntry.name.asString()
|
||||||
val ordinal = enumEntryOrdinals[enumEntry]
|
val ordinal = enumEntryOrdinals[enumEntry]
|
||||||
|
|
||||||
val descriptor = enumConstructorCall.descriptor
|
|
||||||
val startOffset = enumConstructorCall.startOffset
|
val startOffset = enumConstructorCall.startOffset
|
||||||
val endOffset = enumConstructorCall.endOffset
|
val endOffset = enumConstructorCall.endOffset
|
||||||
|
|
||||||
val loweredConstructor = loweredEnumConstructors.getOrElse(descriptor) {
|
val loweredConstructor = loweredEnumConstructors.getOrElse(enumConstructorCall.symbol) {
|
||||||
throw AssertionError("Constructor called in enum entry initializer should've been lowered: $descriptor")
|
throw AssertionError("Constructor called in enum entry initializer should've been lowered:\n${enumConstructorCall.dump()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = createConstructorCall(startOffset, endOffset, loweredConstructor)
|
val result = createConstructorCall(startOffset, endOffset, loweredConstructor)
|
||||||
@@ -343,7 +363,7 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
result.putValueArgument(0, IrConstImpl.string(startOffset, endOffset, context.irBuiltIns.stringType, name))
|
result.putValueArgument(0, IrConstImpl.string(startOffset, endOffset, context.irBuiltIns.stringType, name))
|
||||||
result.putValueArgument(1, IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, ordinal))
|
result.putValueArgument(1, IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, ordinal))
|
||||||
|
|
||||||
descriptor.valueParameters.forEach { valueParameter ->
|
enumConstructorCall.symbol.owner.valueParameters.forEach { valueParameter ->
|
||||||
val i = valueParameter.index
|
val i = valueParameter.index
|
||||||
result.putValueArgument(i + 2, enumConstructorCall.getValueArgument(i))
|
result.putValueArgument(i + 2, enumConstructorCall.getValueArgument(i))
|
||||||
}
|
}
|
||||||
@@ -440,7 +460,7 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
if (expression.descriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) {
|
if (expression.symbol.owner.parentAsClass.kind == ClassKind.ENUM_CLASS) {
|
||||||
val callTransformer = enumConstructorCallTransformer ?: throw AssertionError(
|
val callTransformer = enumConstructorCallTransformer ?: throw AssertionError(
|
||||||
"Enum constructor call outside of enum entry initialization or enum class constructor:\n" +
|
"Enum constructor call outside of enum entry initialization or enum class constructor:\n" +
|
||||||
irClass.dump()
|
irClass.dump()
|
||||||
@@ -453,7 +473,7 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
val loweredParameter = loweredEnumConstructorParameters[expression.descriptor]
|
val loweredParameter = loweredEnumConstructorParameters[expression.symbol]
|
||||||
return if (loweredParameter != null) {
|
return if (loweredParameter != null) {
|
||||||
IrGetValueImpl(expression.startOffset, expression.endOffset, loweredParameter.symbol, expression.origin)
|
IrGetValueImpl(expression.startOffset, expression.endOffset, loweredParameter.symbol, expression.origin)
|
||||||
} else {
|
} else {
|
||||||
@@ -473,22 +493,25 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createEnumValueOfBody(): IrBody {
|
private fun createEnumValueOfBody(): IrBody {
|
||||||
val unsubstitutedValueOfDescriptor = context.irBuiltIns.enumValueOf
|
val enumValueOf = context.irBuiltIns.enumValueOfFun
|
||||||
val valueOfSymbol = context.irBuiltIns.enumValueOfSymbol
|
val returnType = irClass.defaultType
|
||||||
val typeParameterT = unsubstitutedValueOfDescriptor.typeParameters[0]
|
|
||||||
|
val unsubstitutedValueOfDescriptor = enumValueOf.descriptor
|
||||||
|
val typeParameter0 = unsubstitutedValueOfDescriptor.typeParameters[0]
|
||||||
val enumClassType = irClass.descriptor.defaultType
|
val enumClassType = irClass.descriptor.defaultType
|
||||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(enumClassType)))
|
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(enumClassType)))
|
||||||
val substitutedValueOfDescriptor = unsubstitutedValueOfDescriptor.substitute(typeSubstitutor)!!
|
val substitutedValueOfDescriptor = unsubstitutedValueOfDescriptor.substitute(typeSubstitutor)!!
|
||||||
|
|
||||||
val irValueOfCall =
|
val irValueOfCall =
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
substitutedValueOfDescriptor.returnType!!.toIrType()!!,
|
returnType,
|
||||||
valueOfSymbol,
|
enumValueOf.symbol,
|
||||||
substitutedValueOfDescriptor,
|
substitutedValueOfDescriptor,
|
||||||
substitutedValueOfDescriptor.typeParametersCount
|
enumValueOf.typeParameters.size
|
||||||
)
|
)
|
||||||
|
irValueOfCall.putTypeArgument(0, irClass.defaultType)
|
||||||
irValueOfCall.putValueArgument(
|
irValueOfCall.putValueArgument(
|
||||||
0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunction.valueParameters[0].symbol)
|
0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunction.valueParameters[0].symbol)
|
||||||
)
|
)
|
||||||
@@ -499,7 +522,7 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
IrReturnImpl(
|
IrReturnImpl(
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
valueOfFunction.returnType,
|
returnType,
|
||||||
valueOfFunction.symbol,
|
valueOfFunction.symbol,
|
||||||
irValueOfCall
|
irValueOfCall
|
||||||
)
|
)
|
||||||
@@ -508,11 +531,10 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createEnumValuesBody(valuesField: IrField): IrBody {
|
private fun createEnumValuesBody(valuesField: IrField): IrBody {
|
||||||
val cloneFunDescriptor = valuesField.type.toKotlinType().memberScope.findSingleFunction(Name.identifier("clone")).original
|
val cloneFun = context.irBuiltIns.arrayClass.owner.functions.find { it.name.asString() == "clone" }!!
|
||||||
val cloneFun = context.ir.symbols.externalSymbolTable.referenceSimpleFunction(cloneFunDescriptor).owner
|
|
||||||
|
|
||||||
val irCloneValues =
|
val irCloneValues =
|
||||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, cloneFun.returnType, cloneFun.symbol, cloneFunDescriptor, 0).apply {
|
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, cloneFun.returnType, cloneFun.symbol, cloneFun.descriptor, 0).apply {
|
||||||
dispatchReceiver =
|
dispatchReceiver =
|
||||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesField.symbol, valuesField.symbol.owner.type)
|
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesField.symbol, valuesField.symbol.owner.type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,8 +286,8 @@ val IrDeclarationContainer.properties: Sequence<IrProperty>
|
|||||||
val IrFunction.explicitParameters: List<IrValueParameter>
|
val IrFunction.explicitParameters: List<IrValueParameter>
|
||||||
get() = (listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters)
|
get() = (listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters)
|
||||||
|
|
||||||
val IrClass.defaultType: IrType
|
val IrClass.defaultType: IrSimpleType
|
||||||
get() = this.thisReceiver!!.type
|
get() = this.thisReceiver!!.type as IrSimpleType
|
||||||
|
|
||||||
val IrSimpleFunction.isReal: Boolean get() = descriptor.kind.isReal
|
val IrSimpleFunction.isReal: Boolean get() = descriptor.kind.isReal
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user