[JS] Fix typeOf for some reified type parameters
Fix getting kType metadata in cases when corresponding jsClass value is passed through temporary variable. This can happen when jsClass expression is not consided trivial by local variable optimizer. This happens for object declarations from different modules, for example kotlin.Unit
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JS
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
fun sideEffects() {
|
||||
println("Side effect")
|
||||
}
|
||||
|
||||
inline fun <reified T> foo(): String {
|
||||
sideEffects()
|
||||
val x = typeOf<T>().toString()
|
||||
return x
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (foo<kotlin.Unit>() != "Unit")
|
||||
return "FAIL"
|
||||
return "OK"
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SpecialFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.kType
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.specialFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
|
||||
|
||||
// Replaces getReifiedTypeParameterKType(<Class Constructor>) with its KType
|
||||
fun substituteKTypes(root: JsNode) {
|
||||
@@ -17,10 +18,25 @@ fun substituteKTypes(root: JsNode) {
|
||||
val qualifier = invocation.qualifier as? JsNameRef ?: return
|
||||
if (qualifier.name?.specialFunction != SpecialFunction.GET_REIFIED_TYPE_PARAMETER_KTYPE) return
|
||||
val firstArg = invocation.arguments.first()
|
||||
firstArg.kType?.let {
|
||||
getTransitiveKType(firstArg)?.let {
|
||||
ctx.replaceMe(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
visitor.accept(root)
|
||||
}
|
||||
}
|
||||
|
||||
// Get KType from expression or from staticRef of referenced name
|
||||
fun getTransitiveKType(e: JsExpression): JsExpression? {
|
||||
return when {
|
||||
e.kType != null ->
|
||||
e.kType
|
||||
|
||||
e is JsNameRef -> {
|
||||
val staticRef = e.name?.staticRef as? JsExpression ?: return null
|
||||
getTransitiveKType(staticRef)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+5
@@ -19316,6 +19316,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
public void testMultipleModules() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/js/multipleModules.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeOfReifiedUnit.kt")
|
||||
public void testTypeOfReifiedUnit() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/js/typeOfReifiedUnit.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/noReflect")
|
||||
|
||||
+5
@@ -20446,6 +20446,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
public void testMultipleModules() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/js/multipleModules.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeOfReifiedUnit.kt")
|
||||
public void testTypeOfReifiedUnit() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/js/typeOfReifiedUnit.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/noReflect")
|
||||
|
||||
Reference in New Issue
Block a user