diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/LocalLookup.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/LocalLookup.java index eb2331375d1..43eff476b21 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/LocalLookup.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/LocalLookup.java @@ -106,14 +106,21 @@ public interface LocalLookup { BindingContext bindingContext = state.getBindingContext(); Type localType = asmTypeForAnonymousClass(bindingContext, vd); - MutableClosure localFunClosure = bindingContext.get(CLOSURE, bindingContext.get(CLASS_FOR_CALLABLE, vd)); + ClassDescriptor callableClass = bindingContext.get(CLASS_FOR_CALLABLE, vd); + assert callableClass != null : "No CLASS_FOR_CALLABLE:" + vd; + + MutableClosure localFunClosure = bindingContext.get(CLOSURE, callableClass); if (localFunClosure != null && JvmCodegenUtil.isConst(localFunClosure)) { // This is an optimization: we can obtain an instance of a const closure simply by GETSTATIC ...$instance // (instead of passing this instance to the constructor and storing as a field) return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true, StackValue.LOCAL_0, vd); } - String fieldName = "$" + vd.getName(); + String localFunClassName = callableClass.getName().asString(); + int localClassIndexStart = localFunClassName.lastIndexOf('$'); + String localFunSuffix = localClassIndexStart >= 0 ? localFunClassName.substring(localClassIndexStart) : ""; + + String fieldName = "$" + vd.getName() + localFunSuffix; StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(localType, classType, fieldName, false, StackValue.LOCAL_0, vd); diff --git a/compiler/testData/codegen/box/functions/localFunctions/localFunctionVsLocalVariable.kt b/compiler/testData/codegen/box/functions/localFunctions/localFunctionVsLocalVariable.kt new file mode 100644 index 00000000000..df58363773a --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/localFunctionVsLocalVariable.kt @@ -0,0 +1,19 @@ +fun box(): String { + var s = "" + var foo = "O" + + fun foo(x: String) { + s += x + } + + fun foo() { + foo("K") + } + + run { + foo(foo) // 1st foo is a local fun, second is a captured local var + foo() + } + + return s +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunWithoutClosure.kt b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunWithoutClosure.kt new file mode 100644 index 00000000000..078f029fe75 --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunWithoutClosure.kt @@ -0,0 +1,8 @@ +fun box(): String { + fun foo(x: String) = x + fun foo() = foo("K") + + return run { + foo("O") + foo() + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction.kt b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction.kt new file mode 100644 index 00000000000..6e349f27ae9 --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction.kt @@ -0,0 +1,18 @@ +fun box(): String { + var s = "" + + fun foo(x: String) { + s += x + } + + fun foo() { + foo("K") + } + + run { + foo("O") + foo() + } + + return s +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction1.kt b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction1.kt new file mode 100644 index 00000000000..79645a8716d --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction1.kt @@ -0,0 +1,23 @@ +fun box(): String { + var s = "" + var foo = "K" + + fun foo(x: String, y: Int) { + s += x + } + + fun test() { + fun foo(x: String) { + s += x + } + + run { + foo("O") + foo(foo, 1) + } + } + + test() + + return s +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction2.kt b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction2.kt new file mode 100644 index 00000000000..1cf01ce4e21 --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction2.kt @@ -0,0 +1,23 @@ +fun box(): String { + var s = "" + var foo = "K" + + fun foo(x: String, y: Int) { + s += x + } + + fun test() { + fun foo(x: String) { + s += x + } + + { + foo("O") + foo(foo, 1) + }() + } + + test() + + return s +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction3.kt b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction3.kt new file mode 100644 index 00000000000..9504e6ebfac --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction3.kt @@ -0,0 +1,21 @@ +fun box(): String { + var s = "" + var foo = "O" + + fun foo(x: String, z: Int) { + s += x + } + + run { + fun foo(x: String) { + s += x + } + + { + foo(foo, 1) + foo("K") + } () + } + + return s +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt b/compiler/testData/codegen/box/functions/localFunctions/parameterAsDefaultValue.kt similarity index 100% rename from compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt rename to compiler/testData/codegen/box/functions/localFunctions/parameterAsDefaultValue.kt diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index db686cc9a06..4596b1f4f51 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -9336,6 +9336,48 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localFunctionInConstructor.kt"); doTest(fileName); } + + @TestMetadata("localFunctionVsLocalVariable.kt") + public void testLocalFunctionVsLocalVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localFunctionVsLocalVariable.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunWithoutClosure.kt") + public void testOverloadedLocalFunWithoutClosure() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunWithoutClosure.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction.kt") + public void testOverloadedLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction1.kt") + public void testOverloadedLocalFunction1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction1.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction2.kt") + public void testOverloadedLocalFunction2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction2.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction3.kt") + public void testOverloadedLocalFunction3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction3.kt"); + doTest(fileName); + } + + @TestMetadata("parameterAsDefaultValue.kt") + public void testParameterAsDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/parameterAsDefaultValue.kt"); + doTest(fileName); + } } } @@ -11283,21 +11325,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } - @TestMetadata("compiler/testData/codegen/box/localFunctions") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class LocalFunctions extends AbstractIrBlackBoxCodegenTest { - public void testAllFilesPresentInLocalFunctions() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); - } - - @TestMetadata("parameterAsDefaultValue.kt") - public void testParameterAsDefaultValue() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt"); - doTest(fileName); - } - } - @TestMetadata("compiler/testData/codegen/box/mangling") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 9167bf056f1..55ff62ab07e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -9336,6 +9336,48 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localFunctionInConstructor.kt"); doTest(fileName); } + + @TestMetadata("localFunctionVsLocalVariable.kt") + public void testLocalFunctionVsLocalVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localFunctionVsLocalVariable.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunWithoutClosure.kt") + public void testOverloadedLocalFunWithoutClosure() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunWithoutClosure.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction.kt") + public void testOverloadedLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction1.kt") + public void testOverloadedLocalFunction1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction1.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction2.kt") + public void testOverloadedLocalFunction2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction2.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction3.kt") + public void testOverloadedLocalFunction3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction3.kt"); + doTest(fileName); + } + + @TestMetadata("parameterAsDefaultValue.kt") + public void testParameterAsDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/parameterAsDefaultValue.kt"); + doTest(fileName); + } } } @@ -11283,21 +11325,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } - @TestMetadata("compiler/testData/codegen/box/localFunctions") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class LocalFunctions extends AbstractBlackBoxCodegenTest { - public void testAllFilesPresentInLocalFunctions() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); - } - - @TestMetadata("parameterAsDefaultValue.kt") - public void testParameterAsDefaultValue() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt"); - doTest(fileName); - } - } - @TestMetadata("compiler/testData/codegen/box/mangling") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 0373b3d7d5a..2a6c275aa94 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -9336,6 +9336,48 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localFunctionInConstructor.kt"); doTest(fileName); } + + @TestMetadata("localFunctionVsLocalVariable.kt") + public void testLocalFunctionVsLocalVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localFunctionVsLocalVariable.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunWithoutClosure.kt") + public void testOverloadedLocalFunWithoutClosure() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunWithoutClosure.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction.kt") + public void testOverloadedLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction1.kt") + public void testOverloadedLocalFunction1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction1.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction2.kt") + public void testOverloadedLocalFunction2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction2.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction3.kt") + public void testOverloadedLocalFunction3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction3.kt"); + doTest(fileName); + } + + @TestMetadata("parameterAsDefaultValue.kt") + public void testParameterAsDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/parameterAsDefaultValue.kt"); + doTest(fileName); + } } } @@ -11283,21 +11325,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } - @TestMetadata("compiler/testData/codegen/box/localFunctions") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class LocalFunctions extends AbstractLightAnalysisModeTest { - public void testAllFilesPresentInLocalFunctions() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); - } - - @TestMetadata("parameterAsDefaultValue.kt") - public void testParameterAsDefaultValue() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt"); - doTest(fileName); - } - } - @TestMetadata("compiler/testData/codegen/box/mangling") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) 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 490a6df830c..3937bd793c1 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 @@ -10188,6 +10188,48 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localFunctionInConstructor.kt"); doTest(fileName); } + + @TestMetadata("localFunctionVsLocalVariable.kt") + public void testLocalFunctionVsLocalVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localFunctionVsLocalVariable.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunWithoutClosure.kt") + public void testOverloadedLocalFunWithoutClosure() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunWithoutClosure.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction.kt") + public void testOverloadedLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction1.kt") + public void testOverloadedLocalFunction1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction1.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction2.kt") + public void testOverloadedLocalFunction2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction2.kt"); + doTest(fileName); + } + + @TestMetadata("overloadedLocalFunction3.kt") + public void testOverloadedLocalFunction3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/overloadedLocalFunction3.kt"); + doTest(fileName); + } + + @TestMetadata("parameterAsDefaultValue.kt") + public void testParameterAsDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/parameterAsDefaultValue.kt"); + doTest(fileName); + } } } @@ -12483,21 +12525,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } - @TestMetadata("compiler/testData/codegen/box/localFunctions") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class LocalFunctions extends AbstractJsCodegenBoxTest { - public void testAllFilesPresentInLocalFunctions() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); - } - - @TestMetadata("parameterAsDefaultValue.kt") - public void testParameterAsDefaultValue() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt"); - doTest(fileName); - } - } - @TestMetadata("compiler/testData/codegen/box/mangling") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)