[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:
Svyatoslav Kuzmich
2019-11-11 20:44:35 +03:00
parent c4d993d14c
commit 600fb723f4
4 changed files with 50 additions and 2 deletions
@@ -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
}
}
@@ -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")
@@ -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")