[K/JS, K/Wasm] Implement enumEntries top-level function ^KT-59712 Fixed

This commit is contained in:
Artem Kobzar
2023-07-27 09:43:01 +00:00
committed by Space Team
parent 34b271b13d
commit 029c71ebb1
10 changed files with 41 additions and 12 deletions
@@ -15,10 +15,7 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.isLong
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.findDeclaration
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.kotlinPackageFqn
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.findSingleFunction
@@ -142,6 +139,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
val enumValueOfIntrinsic = getInternalFunction("enumValueOfIntrinsic")
val enumValuesIntrinsic = getInternalFunction("enumValuesIntrinsic")
val enumEntriesIntrinsic = getFunctionInEnumPackage("enumEntriesIntrinsic")
// Other:
@@ -396,6 +394,11 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
return context.symbolTable.descriptorExtension.referenceSimpleFunction(descriptor)
}
private fun getFunctionInEnumPackage(name: String) =
context.symbolTable.descriptorExtension.referenceSimpleFunction(
context.getFunctions(kotlinEnumsPackageFqn.child(Name.identifier(name))).single()
)
private fun getFunctionInKotlinPackage(name: String) =
context.symbolTable.descriptorExtension.referenceSimpleFunction(
context.getFunctions(kotlinPackageFqn.child(Name.identifier(name))).single()
@@ -45,12 +45,17 @@ object EnumIntrinsicsUtils {
fun transformEnumValuesIntrinsic(call: IrFunctionAccessExpression) = transformEnumTopLevelIntrinsic(call) {
it.name == Name.identifier("values") && it.valueParameters.count() == 0
}
fun transformEnumEntriesIntrinsic(call: IrFunctionAccessExpression) = transformEnumTopLevelIntrinsic(call) {
it.name == Name.special("<get-entries>")
}
}
class EnumIntrinsicsTransformer(private val context: JsIrBackendContext) : CallsTransformer {
override fun transformFunctionAccess(call: IrFunctionAccessExpression, doNotIntrinsify: Boolean) = when (call.symbol) {
context.intrinsics.enumValueOfIntrinsic -> EnumIntrinsicsUtils.transformEnumValueOfIntrinsic(call)
context.intrinsics.enumValuesIntrinsic -> EnumIntrinsicsUtils.transformEnumValuesIntrinsic(call)
context.intrinsics.enumEntriesIntrinsic -> EnumIntrinsicsUtils.transformEnumEntriesIntrinsic(call)
else -> call
}
}
@@ -29,11 +29,14 @@ internal class SaveInlineFunctionsBeforeInlining(context: JsIrBackendContext) :
}
internal class JsInlineFunctionResolver(context: JsIrBackendContext) : DefaultInlineFunctionResolver(context) {
private val enumEntriesIntrinsic = context.intrinsics.enumEntriesIntrinsic
private val inlineFunctionsBeforeInlining = context.mapping.inlineFunctionsBeforeInlining
private val inlineFunctionsBeforeInliningSymbols = hashMapOf<IrFunction, IrFunctionSymbol>()
override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
val function = super.getFunctionDeclaration(symbol)
// TODO: After the expect fun enumEntriesIntrinsic become non-inline function, the code will be removed
if (function.symbol == enumEntriesIntrinsic) return function.apply { body = null }
val functionBeforeInlining = inlineFunctionsBeforeInlining[function] ?: return function
inlineFunctionsBeforeInliningSymbols[functionBeforeInlining] = function.symbol
return functionBeforeInlining
@@ -118,6 +118,7 @@ class WasmSymbols(
val enumValueOfIntrinsic = getInternalFunction("enumValueOfIntrinsic")
val enumValuesIntrinsic = getInternalFunction("enumValuesIntrinsic")
val enumEntriesIntrinsic = getEnumsFunction("enumEntriesIntrinsic")
val coroutineEmptyContinuation: IrPropertySymbol = symbolTable.descriptorExtension.referenceProperty(
getProperty(FqName.fromSegments(listOf("kotlin", "wasm", "internal", "EmptyContinuation")))
@@ -382,6 +383,8 @@ class WasmSymbols(
private fun getInternalFunction(name: String) = getFunction(name, wasmInternalPackage)
private fun getEnumsFunction(name: String) = getFunction(name, enumsInternalPackage)
private fun getIrClass(fqName: FqName): IrClassSymbol = symbolTable.descriptorExtension.referenceClass(getClass(fqName))
private fun getInternalClass(name: String): IrClassSymbol = getIrClass(FqName("kotlin.wasm.internal.$name"))
fun getKFunctionType(type: IrType, list: List<IrType>): IrType {
@@ -182,6 +182,8 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
return EnumIntrinsicsUtils.transformEnumValueOfIntrinsic(call)
symbols.enumValuesIntrinsic ->
return EnumIntrinsicsUtils.transformEnumValuesIntrinsic(call)
symbols.enumEntriesIntrinsic ->
return EnumIntrinsicsUtils.transformEnumEntriesIntrinsic(call)
}
return call
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.memoryOptimizedMap
val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin"))
val kotlinEnumsPackageFqn = kotlinPackageFqn.child(Name.identifier("enums"))
private val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect"))
private val kotlinCoroutinesPackageFqn = kotlinPackageFqn.child(Name.identifier("coroutines"))
@@ -1,5 +1,5 @@
// !LANGUAGE: -EnumEntries
// IGNORE_BACKEND: JS
// IGNORE_BACKEND: JS_IR, JS_IR_ES6, WASM
// WITH_STDLIB
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")