From 600fb723f402a11887c60200b6bd3f44856d7f08 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Mon, 11 Nov 2019 20:44:35 +0300 Subject: [PATCH] [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 --- .../reflection/typeOf/js/typeOfReifiedUnit.kt | 22 +++++++++++++++++++ .../js/inline/clean/substituteKTypes.kt | 20 +++++++++++++++-- .../IrJsCodegenBoxTestGenerated.java | 5 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/reflection/typeOf/js/typeOfReifiedUnit.kt diff --git a/compiler/testData/codegen/box/reflection/typeOf/js/typeOfReifiedUnit.kt b/compiler/testData/codegen/box/reflection/typeOf/js/typeOfReifiedUnit.kt new file mode 100644 index 00000000000..774a4013415 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/js/typeOfReifiedUnit.kt @@ -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 foo(): String { + sideEffects() + val x = typeOf().toString() + return x +} + +fun box(): String { + if (foo() != "Unit") + return "FAIL" + return "OK" +} \ No newline at end of file diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/substituteKTypes.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/substituteKTypes.kt index 8076623c4ed..d3267f95d73 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/substituteKTypes.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/substituteKTypes.kt @@ -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() 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) -} \ No newline at end of file +} + +// 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 + } +} diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 19d1115da4e..4c58a34a34b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -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") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 6607c75b072..86824569a51 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -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")