From 6301e3ec30d4db11a7fc86d9112afa37beb9183c Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Thu, 1 Dec 2016 19:22:48 +0300 Subject: [PATCH] JS: Fix capturing class construction function for lambdas inside inline functions with reified type parameters (KT-13522). --- .../js/test/semantics/BoxJsTestGenerated.java | 12 ++++++++++++ .../expression/LiteralFunctionTranslator.kt | 6 ++++++ .../kotlin/js/translate/utils/utils.kt | 2 ++ .../jsClassOnReifiedTypeInLambda.kt | 15 +++++++++++++++ .../reflection/kClassOnReifiedTypeInLambda.kt | 19 +++++++++++++++++++ 5 files changed, 54 insertions(+) create mode 100644 js/js.translator/testData/box/reflection/jsClassOnReifiedTypeInLambda.kt create mode 100644 js/js.translator/testData/box/reflection/kClassOnReifiedTypeInLambda.kt diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index a248d42c7fa..6c86856d217 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -6464,6 +6464,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("jsClassOnReifiedTypeInLambda.kt") + public void testJsClassOnReifiedTypeInLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/reflection/jsClassOnReifiedTypeInLambda.kt"); + doTest(fileName); + } + @TestMetadata("jsClassSimpleName.kt") public void testJsClassSimpleName() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/reflection/jsClassSimpleName.kt"); @@ -6488,6 +6494,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("kClassOnReifiedTypeInLambda.kt") + public void testKClassOnReifiedTypeInLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/reflection/kClassOnReifiedTypeInLambda.kt"); + doTest(fileName); + } + @TestMetadata("kClassSimpleName.kt") public void testKClassSimpleName() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/reflection/kClassSimpleName.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt index 7759e836e7c..ff0c4323859 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt @@ -141,6 +141,12 @@ fun JsFunction.withCapturedParameters( var additionalArgs = listOf(capturedRef) var additionalParams = listOf(JsParameter(name)) + if (capturedDescriptor is TypeParameterDescriptor && capturedDescriptor.isReified) { + // Preserve the usual order + additionalArgs = listOf(invokingContext.getNameForDescriptor(capturedDescriptor).makeRef()) + additionalArgs + additionalParams = listOf(JsParameter(context.getNameForDescriptor(capturedDescriptor))) + additionalParams + } + if (capturedDescriptor is CallableDescriptor && isLocalInlineDeclaration(capturedDescriptor)) { val aliasRef = capturedRef as? JsNameRef val localFunAlias = aliasRef?.getStaticRef() as? JsExpression diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt index 8080c764303..b841a02b84e 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt @@ -89,6 +89,8 @@ fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpr is TypeParameterDescriptor -> { assert(classifierDescriptor.isReified) + context.usageTracker()?.used(classifierDescriptor) + context.getNameForDescriptor(classifierDescriptor).makeRef() } else -> { diff --git a/js/js.translator/testData/box/reflection/jsClassOnReifiedTypeInLambda.kt b/js/js.translator/testData/box/reflection/jsClassOnReifiedTypeInLambda.kt new file mode 100644 index 00000000000..79058e1b883 --- /dev/null +++ b/js/js.translator/testData/box/reflection/jsClassOnReifiedTypeInLambda.kt @@ -0,0 +1,15 @@ +package foo + +inline fun foo(): () -> JsClass { + val T = 1 + return { jsClass() } +} + +fun box(): String { + check(jsClass(), foo()()) + check(jsClass(), foo()()) + check(jsClass(), foo()()) + check(jsClass(), foo()()) + + return "OK" +} diff --git a/js/js.translator/testData/box/reflection/kClassOnReifiedTypeInLambda.kt b/js/js.translator/testData/box/reflection/kClassOnReifiedTypeInLambda.kt new file mode 100644 index 00000000000..1e0a56ace5d --- /dev/null +++ b/js/js.translator/testData/box/reflection/kClassOnReifiedTypeInLambda.kt @@ -0,0 +1,19 @@ +package foo + +import kotlin.reflect.KClass + +inline fun foo(b: Boolean = false): () -> KClass { + if (b) { + val T = 1 + } + return { T::class } +} + +fun box(): String { + check(A::class, foo()()) + check(B::class, foo()()) + check(O::class, foo()()) + check(E::class, foo()()) + + return "OK" +}