From a927770935b35a4d487b50d7e8f2394108f8b236 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 16 Jan 2017 12:22:52 +0300 Subject: [PATCH] JS: fix scope of function generated for primary constructor. See KT-15678 --- .../kotlin/js/inline/context/NamingContext.kt | 3 --- .../kotlin/js/inline/util/namingUtils.kt | 4 +-- .../js/test/semantics/BoxJsTestGenerated.java | 6 +++++ .../translate/declaration/ClassTranslator.kt | 3 ++- .../box/nameClashes/constructorLocalVar.kt | 25 +++++++++++++++++++ 5 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 js/js.translator/testData/box/nameClashes/constructorLocalVar.kt diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/context/NamingContext.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/context/NamingContext.kt index a0373b1441d..61d18ee44cf 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/context/NamingContext.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/context/NamingContext.kt @@ -53,9 +53,6 @@ class NamingContext( fun getTemporaryName(candidate: String): JsName = scope.declareTemporaryName(candidate) - fun getFreshName(candidate: JsName) = if (candidate.isTemporary) getTemporaryName(candidate.ident) else getFreshName(candidate.ident) - - fun newVar(name: JsName, value: JsExpression? = null) { val vars = JsAstUtils.newVar(name, value) vars.synthetic = true diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/namingUtils.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/namingUtils.kt index de29ca7467a..9314ee05d76 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/namingUtils.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/namingUtils.kt @@ -32,7 +32,7 @@ fun aliasArgumentsIfNeeded( for ((arg, param) in arguments.zip(parameters)) { val paramName = param.name - val replacement = context.getFreshName(paramName).apply { + val replacement = context.getTemporaryName(paramName.ident).apply { staticRef = arg context.newVar(this, arg.deepCopy()) }.makeRef() @@ -43,7 +43,7 @@ fun aliasArgumentsIfNeeded( val defaultParams = parameters.subList(arguments.size, parameters.size) for (defaultParam in defaultParams) { val paramName = defaultParam.name - val freshName = context.getFreshName(paramName) + val freshName = context.getTemporaryName(paramName.ident) context.newVar(freshName) context.replaceName(paramName, freshName.makeRef()) 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 e88c70b095b..c8d1f044558 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 @@ -5630,6 +5630,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("constructorLocalVar.kt") + public void testConstructorLocalVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/nameClashes/constructorLocalVar.kt"); + doTest(fileName); + } + @TestMetadata("differenceInCapitalization.kt") public void testDifferenceInCapitalization() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/nameClashes/differenceInCapitalization.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt index 1fc737738e3..f01c780304a 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt @@ -75,7 +75,8 @@ class ClassTranslator private constructor( val scope = context().getScopeForDescriptor(descriptor) val context = context().newDeclaration(descriptor) - val constructorFunction = context.createRootScopedFunction(descriptor) + val constructorFunction = descriptor.unsubstitutedPrimaryConstructor?.let { context.getFunctionObject(it) } ?: + context.createRootScopedFunction(descriptor) constructorFunction.name = context.getInnerNameForDescriptor(descriptor) context.addDeclarationStatement(constructorFunction.makeStmt()) val enumInitFunction = if (descriptor.kind == ClassKind.ENUM_CLASS) createEnumInitFunction() else null diff --git a/js/js.translator/testData/box/nameClashes/constructorLocalVar.kt b/js/js.translator/testData/box/nameClashes/constructorLocalVar.kt new file mode 100644 index 00000000000..34302520792 --- /dev/null +++ b/js/js.translator/testData/box/nameClashes/constructorLocalVar.kt @@ -0,0 +1,25 @@ +var log = "" + +inline fun f(x: Int): Int { + val result = x * 2 + log += "f($x)" + return result +} + +fun bar() = 10 + +class Test { + val value: Int + + init { + val x = 3 + val y = f(bar()) + value = x + y + } +} + +fun box(): String { + val test = Test() + if (test.value != 23) return "fail: ${test.value}" + return "OK" +} \ No newline at end of file