[K/N][IR] Moved EnumsSupport to corresponding lowering
This commit is contained in:
+109
@@ -6,28 +6,137 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.lower
|
package org.jetbrains.kotlin.backend.konan.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.getOrPut
|
||||||
import org.jetbrains.kotlin.backend.common.lower.EnumWhenLowering
|
import org.jetbrains.kotlin.backend.common.lower.EnumWhenLowering
|
||||||
import org.jetbrains.kotlin.backend.common.lower.at
|
import org.jetbrains.kotlin.backend.common.lower.at
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.MemoryModel
|
import org.jetbrains.kotlin.backend.konan.MemoryModel
|
||||||
|
import org.jetbrains.kotlin.backend.konan.NativeMapping
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
||||||
|
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType
|
import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType
|
import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
|
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
|
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||||
|
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||||
|
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||||
|
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.types.typeWith
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
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
|
||||||
|
|
||||||
|
internal data class LoweredEnumEntryDescription(val ordinal: Int, val getterId: Int)
|
||||||
|
|
||||||
|
internal class EnumsSupport(
|
||||||
|
mapping: NativeMapping,
|
||||||
|
symbols: KonanSymbols,
|
||||||
|
private val irBuiltIns: IrBuiltIns,
|
||||||
|
private val irFactory: IrFactory,
|
||||||
|
) {
|
||||||
|
private val enumImplObjects = mapping.enumImplObjects
|
||||||
|
private val enumValueGetters = mapping.enumValueGetters
|
||||||
|
private val enumEntriesMaps = mapping.enumEntriesMaps
|
||||||
|
private val array = symbols.array
|
||||||
|
private val genericValueOfSymbol = symbols.valueOfForEnum
|
||||||
|
private val genericValuesSymbol = symbols.valuesForEnum
|
||||||
|
|
||||||
|
fun enumEntriesMap(enumClass: IrClass): Map<Name, LoweredEnumEntryDescription> {
|
||||||
|
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
|
||||||
|
return enumEntriesMaps.getOrPut(enumClass) {
|
||||||
|
data class NameWithOrdinal(val name: Name, val ordinal: Int)
|
||||||
|
enumClass.declarations.asSequence()
|
||||||
|
.filterIsInstance<IrEnumEntry>()
|
||||||
|
.mapIndexed { index, it -> NameWithOrdinal(it.name, index) }
|
||||||
|
.sortedBy { it.name }
|
||||||
|
.withIndex()
|
||||||
|
.associate { it.value.name to LoweredEnumEntryDescription(it.value.ordinal, it.index) }
|
||||||
|
.toMap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getImplObject(enumClass: IrClass): IrClass {
|
||||||
|
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
|
||||||
|
return enumImplObjects.getOrPut(enumClass) {
|
||||||
|
irFactory.buildClass {
|
||||||
|
startOffset = enumClass.startOffset
|
||||||
|
endOffset = enumClass.endOffset
|
||||||
|
origin = DECLARATION_ORIGIN_ENUM
|
||||||
|
name = "OBJECT".synthesizedName
|
||||||
|
kind = ClassKind.OBJECT
|
||||||
|
}.apply {
|
||||||
|
superTypes = listOf(irBuiltIns.anyType)
|
||||||
|
parent = enumClass
|
||||||
|
|
||||||
|
addChild(irFactory.buildField {
|
||||||
|
startOffset = enumClass.startOffset
|
||||||
|
endOffset = enumClass.endOffset
|
||||||
|
origin = DECLARATION_ORIGIN_ENUM
|
||||||
|
name = "VALUES".synthesizedName
|
||||||
|
type = array.typeWith(enumClass.defaultType)
|
||||||
|
visibility = DescriptorVisibilities.PRIVATE
|
||||||
|
isFinal = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getValueGetter(enumClass: IrClass): IrFunction {
|
||||||
|
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
|
||||||
|
return enumValueGetters.getOrPut(enumClass) {
|
||||||
|
irFactory.buildFun {
|
||||||
|
startOffset = enumClass.startOffset
|
||||||
|
endOffset = enumClass.endOffset
|
||||||
|
origin = DECLARATION_ORIGIN_ENUM
|
||||||
|
name = "getEnumAt".synthesizedName
|
||||||
|
returnType = enumClass.defaultType
|
||||||
|
}.apply {
|
||||||
|
parent = enumClass
|
||||||
|
|
||||||
|
addValueParameter {
|
||||||
|
name = Name.identifier("getterId")
|
||||||
|
origin = DECLARATION_ORIGIN_ENUM
|
||||||
|
type = irBuiltIns.intType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getValuesField(implObject: IrClass) = implObject.fields.single()
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irGetValuesField(enumClass: IrClass): IrExpression {
|
||||||
|
val implObject = getImplObject(enumClass)
|
||||||
|
val valuesField = getValuesField(implObject)
|
||||||
|
return irGetField(irGetObject(implObject.symbol), valuesField)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irEnumValues(enumClass: IrClass) =
|
||||||
|
irCall(genericValuesSymbol, listOf(enumClass.defaultType)).apply {
|
||||||
|
putValueArgument(0, irGetValuesField(enumClass))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irEnumValueOf(enumClass: IrClass, value: IrExpression) =
|
||||||
|
irCall(genericValueOfSymbol, listOf(enumClass.defaultType)).apply {
|
||||||
|
putValueArgument(0, value)
|
||||||
|
putValueArgument(1, irGetValuesField(enumClass))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM")
|
||||||
|
|
||||||
internal class NativeEnumWhenLowering constructor(context: Context) : EnumWhenLowering(context) {
|
internal class NativeEnumWhenLowering constructor(context: Context) : EnumWhenLowering(context) {
|
||||||
override fun mapConstEnumEntry(entry: IrEnumEntry): Int {
|
override fun mapConstEnumEntry(entry: IrEnumEntry): Int {
|
||||||
val enumEntriesMap = (context as Context).enumsSupport.enumEntriesMap(entry.parentAsClass)
|
val enumEntriesMap = (context as Context).enumsSupport.enumEntriesMap(entry.parentAsClass)
|
||||||
|
|||||||
-122
@@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.lower
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.getOrPut
|
|
||||||
import org.jetbrains.kotlin.backend.konan.NativeMapping
|
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
|
||||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|
||||||
import org.jetbrains.kotlin.ir.types.typeWith
|
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
internal class EnumsSupport(
|
|
||||||
mapping: NativeMapping,
|
|
||||||
symbols: KonanSymbols,
|
|
||||||
private val irBuiltIns: IrBuiltIns,
|
|
||||||
private val irFactory: IrFactory,
|
|
||||||
) {
|
|
||||||
private val enumImplObjects = mapping.enumImplObjects
|
|
||||||
private val enumValueGetters = mapping.enumValueGetters
|
|
||||||
private val enumEntriesMaps = mapping.enumEntriesMaps
|
|
||||||
private val array = symbols.array
|
|
||||||
private val genericValueOfSymbol = symbols.valueOfForEnum
|
|
||||||
private val genericValuesSymbol = symbols.valuesForEnum
|
|
||||||
|
|
||||||
fun enumEntriesMap(enumClass: IrClass): Map<Name, LoweredEnumEntryDescription> {
|
|
||||||
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
|
|
||||||
return enumEntriesMaps.getOrPut(enumClass) {
|
|
||||||
data class NameWithOrdinal(val name: Name, val ordinal: Int)
|
|
||||||
enumClass.declarations.asSequence()
|
|
||||||
.filterIsInstance<IrEnumEntry>()
|
|
||||||
.mapIndexed { index, it -> NameWithOrdinal(it.name, index) }
|
|
||||||
.sortedBy { it.name }
|
|
||||||
.withIndex()
|
|
||||||
.associate { it.value.name to LoweredEnumEntryDescription(it.value.ordinal, it.index) }
|
|
||||||
.toMap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getImplObject(enumClass: IrClass): IrClass {
|
|
||||||
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
|
|
||||||
return enumImplObjects.getOrPut(enumClass) {
|
|
||||||
irFactory.buildClass {
|
|
||||||
startOffset = enumClass.startOffset
|
|
||||||
endOffset = enumClass.endOffset
|
|
||||||
origin = DECLARATION_ORIGIN_ENUM
|
|
||||||
name = "OBJECT".synthesizedName
|
|
||||||
kind = ClassKind.OBJECT
|
|
||||||
}.apply {
|
|
||||||
superTypes = listOf(irBuiltIns.anyType)
|
|
||||||
parent = enumClass
|
|
||||||
|
|
||||||
addChild(irFactory.buildField {
|
|
||||||
startOffset = enumClass.startOffset
|
|
||||||
endOffset = enumClass.endOffset
|
|
||||||
origin = DECLARATION_ORIGIN_ENUM
|
|
||||||
name = "VALUES".synthesizedName
|
|
||||||
type = array.typeWith(enumClass.defaultType)
|
|
||||||
visibility = DescriptorVisibilities.PRIVATE
|
|
||||||
isFinal = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getValueGetter(enumClass: IrClass): IrFunction {
|
|
||||||
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
|
|
||||||
return enumValueGetters.getOrPut(enumClass) {
|
|
||||||
irFactory.buildFun {
|
|
||||||
startOffset = enumClass.startOffset
|
|
||||||
endOffset = enumClass.endOffset
|
|
||||||
origin = DECLARATION_ORIGIN_ENUM
|
|
||||||
name = "getEnumAt".synthesizedName
|
|
||||||
returnType = enumClass.defaultType
|
|
||||||
}.apply {
|
|
||||||
parent = enumClass
|
|
||||||
|
|
||||||
addValueParameter {
|
|
||||||
name = Name.identifier("getterId")
|
|
||||||
origin = DECLARATION_ORIGIN_ENUM
|
|
||||||
type = irBuiltIns.intType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getValuesField(implObject: IrClass) = implObject.fields.single()
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGetValuesField(enumClass: IrClass): IrExpression {
|
|
||||||
val implObject = getImplObject(enumClass)
|
|
||||||
val valuesField = getValuesField(implObject)
|
|
||||||
return irGetField(irGetObject(implObject.symbol), valuesField)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irEnumValues(enumClass: IrClass) =
|
|
||||||
irCall(genericValuesSymbol, listOf(enumClass.defaultType)).apply {
|
|
||||||
putValueArgument(0, irGetValuesField(enumClass))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irEnumValueOf(enumClass: IrClass, value: IrExpression) =
|
|
||||||
irCall(genericValueOfSymbol, listOf(enumClass.defaultType)).apply {
|
|
||||||
putValueArgument(0, value)
|
|
||||||
putValueArgument(1, irGetValuesField(enumClass))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM")
|
|
||||||
|
|
||||||
internal data class LoweredEnumEntryDescription(val ordinal: Int, val getterId: Int)
|
|
||||||
Reference in New Issue
Block a user