Removed creation of descriptors for Enum.valueOf() & values()
Those descriptors are already presented in enum's declaration and are perfectly fine. We just need to replace their synthetic bodies with real implementations.
This commit is contained in:
+1
-56
@@ -19,8 +19,6 @@ import org.jetbrains.kotlin.types.replace
|
||||
internal data class LoweredEnum(val implObjectDescriptor: ClassDescriptor,
|
||||
val valuesProperty: PropertyDescriptor,
|
||||
val valuesGetter: FunctionDescriptor,
|
||||
val valuesFunction: FunctionDescriptor,
|
||||
val valueOfFunction: FunctionDescriptor,
|
||||
val itemGetter: FunctionDescriptor,
|
||||
val entriesMap: Map<Name, Int>)
|
||||
|
||||
@@ -30,8 +28,6 @@ internal class EnumSpecialDescriptorsFactory(val context: Context) {
|
||||
ClassKind.OBJECT, listOf(context.builtIns.anyType), SourceElement.NO_SOURCE, false)
|
||||
|
||||
val valuesProperty = createEnumValuesField(enumClassDescriptor, implObjectDescriptor)
|
||||
val valuesFunction = createValuesFunctionDescriptor(enumClassDescriptor, implObjectDescriptor)
|
||||
val valueOfFunction = createValueOfFunctionDescriptor(enumClassDescriptor, implObjectDescriptor)
|
||||
val valuesGetter = createValuesGetterDescriptor(enumClassDescriptor, implObjectDescriptor)
|
||||
|
||||
val memberScope = MemberScope.Empty
|
||||
@@ -42,30 +38,10 @@ internal class EnumSpecialDescriptorsFactory(val context: Context) {
|
||||
|
||||
implObjectDescriptor.initialize(memberScope, setOf(constructorDescriptor), constructorDescriptor)
|
||||
|
||||
return LoweredEnum(implObjectDescriptor, valuesProperty, valuesGetter, valuesFunction, valueOfFunction,
|
||||
return LoweredEnum(implObjectDescriptor, valuesProperty, valuesGetter,
|
||||
getEnumItemGetter(enumClassDescriptor), createEnumEntriesMap(enumClassDescriptor))
|
||||
}
|
||||
|
||||
private fun createValuesFunctionDescriptor(enumClassDescriptor: ClassDescriptor, implObjectDescriptor: ClassDescriptor)
|
||||
: FunctionDescriptor {
|
||||
val returnType = genericArrayType.defaultType.replace(listOf(TypeProjectionImpl(enumClassDescriptor.defaultType)))
|
||||
val result = SimpleFunctionDescriptorImpl.create(
|
||||
/* containingDeclaration = */ implObjectDescriptor,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* name = */ "values".synthesizedName,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
/* source = */ SourceElement.NO_SOURCE)
|
||||
result.initialize(
|
||||
/* receiverParameterType = */ null,
|
||||
/* dispatchReceiverParameter = */ null,
|
||||
/* typeParameters = */ listOf(),
|
||||
/* unsubstitutedValueParameters = */ listOf(),
|
||||
/* unsubstitutedReturnType = */ returnType,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ Visibilities.PUBLIC)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createValuesGetterDescriptor(enumClassDescriptor: ClassDescriptor, implObjectDescriptor: ClassDescriptor)
|
||||
: FunctionDescriptor {
|
||||
val returnType = genericArrayType.defaultType.replace(listOf(TypeProjectionImpl(enumClassDescriptor.defaultType)))
|
||||
@@ -86,37 +62,6 @@ internal class EnumSpecialDescriptorsFactory(val context: Context) {
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createValueOfFunctionDescriptor(enumClassDescriptor: ClassDescriptor, implObjectDescriptor: ClassDescriptor)
|
||||
: FunctionDescriptor {
|
||||
val result = SimpleFunctionDescriptorImpl.create(
|
||||
/* containingDeclaration = */ implObjectDescriptor,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* name = */ "valueOf".synthesizedName,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
/* source = */ SourceElement.NO_SOURCE)
|
||||
val nameParameterDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration = result,
|
||||
original = null,
|
||||
index = 0,
|
||||
annotations = Annotations.EMPTY,
|
||||
name = Name.identifier("name"),
|
||||
outType = context.builtIns.stringType,
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
varargElementType = null,
|
||||
source = SourceElement.NO_SOURCE)
|
||||
result.initialize(
|
||||
/* receiverParameterType = */ null,
|
||||
/* dispatchReceiverParameter = */ null,
|
||||
/* typeParameters = */ listOf(),
|
||||
/* unsubstitutedValueParameters = */ listOf(nameParameterDescriptor),
|
||||
/* unsubstitutedReturnType = */ enumClassDescriptor.defaultType,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ Visibilities.PUBLIC)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createEnumValuesField(enumClassDescriptor: ClassDescriptor, implObjectDescriptor: ClassDescriptor): PropertyDescriptor {
|
||||
val valuesArrayType = context.builtIns.getArrayType(Variance.INVARIANT, enumClassDescriptor.defaultType)
|
||||
val receiver = ReceiverParameterDescriptorImpl(implObjectDescriptor, ImplicitClassReceiver(implObjectDescriptor))
|
||||
|
||||
+18
-32
@@ -58,24 +58,6 @@ internal class EnumUsageLowering(val context: Context)
|
||||
putValueArgument(0, IrConstImpl.int(startOffset, endOffset, enumClassDescriptor.module.builtIns.intType, ordinal))
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val functionDescriptor = expression.descriptor as? FunctionDescriptor
|
||||
if (functionDescriptor == null) return expression
|
||||
if (functionDescriptor.kind != CallableMemberDescriptor.Kind.SYNTHESIZED) return expression
|
||||
val classDescriptor = functionDescriptor.containingDeclaration as? ClassDescriptor
|
||||
if (classDescriptor == null || classDescriptor.kind != ClassKind.ENUM_CLASS) return expression
|
||||
val loweredEnum = context.specialDescriptorsFactory.getLoweredEnum(classDescriptor)
|
||||
val loweredFunction = when (functionDescriptor.name.asString()) {
|
||||
"values" -> loweredEnum.valuesFunction
|
||||
"valueOf" -> loweredEnum.valueOfFunction
|
||||
else -> throw AssertionError("Unexpected synthetic enum function: $functionDescriptor")
|
||||
}
|
||||
return IrCallImpl(expression.startOffset, expression.endOffset, loweredFunction).apply {
|
||||
expression.descriptor.valueParameters.forEach { p -> putValueArgument(p, expression.getValueArgument(p)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
@@ -125,7 +107,8 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
override fun visitConstructor(declaration: IrConstructor): IrStatement {
|
||||
declaration.transformChildrenVoid(this)
|
||||
|
||||
val blockBody = declaration.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${declaration.body}")
|
||||
val blockBody = declaration.body as? IrBlockBody
|
||||
?: throw AssertionError("Unexpected constructor body: ${declaration.body}")
|
||||
if (blockBody.statements.all { it !is IrInstanceInitializerCall }) {
|
||||
blockBody.statements.transformFlat {
|
||||
if (it is IrEnumConstructorCall)
|
||||
@@ -220,8 +203,15 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
delete = true
|
||||
}
|
||||
is IrFunction -> {
|
||||
if (declaration.body is IrSyntheticBody)
|
||||
delete = true
|
||||
val body = declaration.body
|
||||
if (body is IrSyntheticBody) {
|
||||
when (body.kind) {
|
||||
IrSyntheticBodyKind.ENUM_VALUEOF ->
|
||||
declaration.body = createSyntheticValueOfMethodBody(declaration.descriptor)
|
||||
IrSyntheticBodyKind.ENUM_VALUES ->
|
||||
declaration.body = createSyntheticValuesMethodBody(declaration.descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (delete)
|
||||
@@ -237,8 +227,6 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
|
||||
implObject.declarations.add(constructor)
|
||||
implObject.declarations.add(createSyntheticValuesPropertyDeclaration(enumEntries))
|
||||
implObject.declarations.add(createSyntheticValuesMethodDeclaration())
|
||||
implObject.declarations.add(createSyntheticValueOfMethodDeclaration())
|
||||
|
||||
irClass.declarations.add(implObject)
|
||||
}
|
||||
@@ -273,7 +261,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
|
||||
private val genericValuesFun = context.builtIns.getKonanInternalFunctions("valuesForEnum").single()
|
||||
|
||||
private fun createSyntheticValuesMethodDeclaration(): IrFunction {
|
||||
private fun createSyntheticValuesMethodBody(descriptor: FunctionDescriptor): IrBody {
|
||||
val startOffset = irClass.startOffset
|
||||
val endOffset = irClass.endOffset
|
||||
val typeParameterT = genericValuesFun.typeParameters[0]
|
||||
@@ -288,14 +276,13 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
putValueArgument(0, IrGetFieldImpl(startOffset, endOffset, loweredEnum.valuesProperty, receiver))
|
||||
}
|
||||
|
||||
val body = IrBlockBodyImpl(
|
||||
return IrBlockBodyImpl(
|
||||
startOffset, endOffset,
|
||||
listOf(IrReturnImpl(startOffset, endOffset, loweredEnum.valuesFunction, irValuesCall))
|
||||
listOf(IrReturnImpl(startOffset, endOffset, descriptor, irValuesCall))
|
||||
)
|
||||
return IrFunctionImpl(startOffset, endOffset, DECLARATION_ORIGIN_ENUM, loweredEnum.valuesFunction, body)
|
||||
}
|
||||
|
||||
private fun createSyntheticValueOfMethodDeclaration(): IrFunction {
|
||||
private fun createSyntheticValueOfMethodBody(descriptor: FunctionDescriptor): IrBody {
|
||||
val startOffset = irClass.startOffset
|
||||
val endOffset = irClass.endOffset
|
||||
val typeParameterT = genericValueOfFun.typeParameters[0]
|
||||
@@ -305,17 +292,16 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
|
||||
val irValueOfCall = IrCallImpl(startOffset, endOffset, substitutedValueOf, mapOf(typeParameterT to enumClassType))
|
||||
.apply {
|
||||
putValueArgument(0, IrGetValueImpl(startOffset, endOffset, loweredEnum.valueOfFunction.valueParameters[0]))
|
||||
putValueArgument(0, IrGetValueImpl(startOffset, endOffset, descriptor.valueParameters[0]))
|
||||
val receiver = IrGetObjectValueImpl(startOffset, endOffset,
|
||||
loweredEnum.implObjectDescriptor.defaultType, loweredEnum.implObjectDescriptor)
|
||||
putValueArgument(1, IrGetFieldImpl(startOffset, endOffset, loweredEnum.valuesProperty, receiver))
|
||||
}
|
||||
|
||||
val body = IrBlockBodyImpl(
|
||||
return IrBlockBodyImpl(
|
||||
startOffset, endOffset,
|
||||
listOf(IrReturnImpl(startOffset, endOffset, loweredEnum.valueOfFunction, irValueOfCall))
|
||||
listOf(IrReturnImpl(startOffset, endOffset, descriptor, irValueOfCall))
|
||||
)
|
||||
return IrFunctionImpl(startOffset, endOffset, DECLARATION_ORIGIN_ENUM, loweredEnum.valueOfFunction, body)
|
||||
}
|
||||
|
||||
private fun lowerEnumConstructors(irClass: IrClass) {
|
||||
|
||||
Reference in New Issue
Block a user