Enum.valueOf throws inconsistent exception across multiple platforms #KT-35116

This commit is contained in:
Abduqodiri Qurbonzoda
2023-06-11 03:14:37 +03:00
committed by Space Team
parent d6867917c9
commit 295fdc36ce
10 changed files with 34 additions and 11 deletions
@@ -206,6 +206,9 @@ abstract class Symbols(
open val throwISE: IrSimpleFunctionSymbol
get() = error("throwISE is not implemented")
open val throwIAE: IrSimpleFunctionSymbol
get() = error("throwIAE is not implemented")
abstract val stringBuilder: IrClassSymbol
abstract val defaultConstructorMarker: IrClassSymbol
@@ -219,6 +219,9 @@ class JsIrBackendContext(
override val throwISE: IrSimpleFunctionSymbol =
symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_ISE"))).single())
override val throwIAE: IrSimpleFunctionSymbol =
symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_IAE"))).single())
override val stringBuilder
get() = TODO("not implemented")
override val coroutineImpl =
@@ -325,9 +328,6 @@ class JsIrBackendContext(
val setPropertiesToThrowableInstanceSymbol =
symbolTable.referenceSimpleFunction(getJsInternalFunction("setPropertiesToThrowableInstance"))
val throwISEsymbol = symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_ISE"))).single())
val throwIAEsymbol = symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_IAE"))).single())
override val suiteFun = getFunctions(FqName("kotlin.test.suite")).singleOrNull()?.let { symbolTable.referenceSimpleFunction(it) }
override val testFun = getFunctions(FqName("kotlin.test.test")).singleOrNull()?.let { symbolTable.referenceSimpleFunction(it) }
@@ -501,7 +501,7 @@ class EnumSyntheticFunctionsAndPropertiesLowering(
return null
}
private val throwISESymbol = context.ir.symbols.throwISE
private val throwIAESymbol = context.ir.symbols.throwIAE
private fun createEnumEntriesBody(entriesGetter: IrFunction, enumClass: IrClass): IrBlockBody {
val entriesField = enumClass.buildEntriesField()
@@ -548,7 +548,9 @@ class EnumSyntheticFunctionsAndPropertiesLowering(
)
} memoryOptimizedPlus irElseBranch(irBlock {
+irCall(irClass.initEntryInstancesFun!!)
+irCall(throwISESymbol)
+irCall(throwIAESymbol).apply {
putValueArgument(0, irString("No enum constant ${nameParameter.name.identifier}."))
}
})
)
}
@@ -32,7 +32,7 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL
private val localDelegateBuilderSymbol = context.klocalDelegateBuilder
private val jsClassSymbol = context.intrinsics.jsClass
private val throwISE = context.throwISEsymbol
private val throwISE = context.ir.symbols.throwISE
override fun lower(irBody: IrBody, container: IrDeclaration) {
val currentParent = container as? IrDeclarationParent ?: container.parent
@@ -83,7 +83,7 @@ class WasmSymbols(
override val throwNullPointerException = getInternalFunction("THROW_NPE")
override val throwISE = getInternalFunction("THROW_ISE")
override val throwTypeCastException = getInternalFunction("THROW_CCE")
val throwIAE = getInternalFunction("THROW_IAE")
override val throwIAE = getInternalFunction("THROW_IAE")
val throwNoBranchMatchedException =
getInternalFunction("throwNoBranchMatchedException")
override val throwUninitializedPropertyAccessException =
+14 -1
View File
@@ -1,5 +1,18 @@
// WITH_STDLIB
import kotlin.test.assertSame
import kotlin.test.assertFailsWith
enum class E { OK }
fun <T> id(x: T) = x
fun box() = enumValueOf<E>(id("OK")).name
fun box(): String {
assertSame(E.OK, E.valueOf("OK"))
assertSame(E.OK, enumValueOf<E>("OK"))
assertFailsWith<IllegalArgumentException> { E.valueOf("NO") }
assertFailsWith<IllegalArgumentException> { enumValueOf<E>("NO") }
return enumValueOf<E>(id("OK")).name
}
@@ -95,7 +95,7 @@ public final class Namer {
public static final String ANOTHER_THIS_PARAMETER_NAME = "$this";
public static final String THROW_CLASS_CAST_EXCEPTION_FUN_NAME = "throwCCE";
public static final String THROW_ILLEGAL_STATE_EXCEPTION_FUN_NAME = "throwISE";
public static final String THROW_ILLEGAL_ARGUMENT_EXCEPTION_FUN_NAME = "throwIAE";
public static final String THROW_UNINITIALIZED_PROPERTY_ACCESS_EXCEPTION = "throwUPAE";
public static final String NULL_CHECK_INTRINSIC_NAME = "ensureNotNull";
private static final String PROTOTYPE_NAME = "prototype";
@@ -66,7 +66,7 @@ class EnumTranslator(
val message = JsBinaryOperation(JsBinaryOperator.ADD,
JsStringLiteral("No enum constant ${descriptor.fqNameSafe}."),
nameParam.makeRef())
val throwFunction = context().getReferenceToIntrinsic(Namer.THROW_ILLEGAL_STATE_EXCEPTION_FUN_NAME)
val throwFunction = context().getReferenceToIntrinsic(Namer.THROW_ILLEGAL_ARGUMENT_EXCEPTION_FUN_NAME)
val throwStatement = JsExpressionStatement(JsInvocation(throwFunction, message).source(psi))
if (clauses.isNotEmpty()) {
@@ -200,7 +200,7 @@ internal fun <T: Enum<T>> valueOfForEnum(name: String, values: Array<T>) : T {
else -> return values[middle]
}
}
throw Exception("Invalid enum value name: $name")
throw IllegalArgumentException("Invalid enum value name: $name")
}
@PublishedApi
@@ -20,6 +20,11 @@ internal fun throwISE(message: String) {
throw IllegalStateException(message)
}
@JsName("throwIAE")
internal fun throwIAE(message: String) {
throw IllegalArgumentException(message)
}
@JsName("throwUPAE")
internal fun throwUPAE(propertyName: String) {
throw UninitializedPropertyAccessException("lateinit property ${propertyName} has not been initialized")