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