diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt index ec2e30e313f..ae7fcbce095 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt @@ -549,6 +549,7 @@ class LocalDeclarationsLowering( oldDeclaration: IrFunction, newDeclaration: IrFunction ) = ArrayList(capturedValues.size + oldDeclaration.valueParameters.size).apply { + val generatedNames = mutableSetOf() capturedValues.mapIndexedTo(this) { i, capturedValue -> val parameterDescriptor = WrappedValueParameterDescriptor() val p = capturedValue.owner @@ -558,7 +559,7 @@ class LocalDeclarationsLowering( if (p.descriptor is ReceiverParameterDescriptor && newDeclaration is IrConstructor) BOUND_RECEIVER_PARAMETER else BOUND_VALUE_PARAMETER, IrValueParameterSymbolImpl(parameterDescriptor), - suggestNameForCapturedValue(p), + suggestNameForCapturedValue(p, generatedNames), i, p.type, null, @@ -665,13 +666,13 @@ class LocalDeclarationsLowering( private fun createFieldsForCapturedValues(localClassContext: LocalClassContext) { val classDeclaration = localClassContext.declaration - + val generatedNames = mutableSetOf() localClassContext.closure.capturedValues.forEach { capturedValue -> val irField = createFieldForCapturedValue( classDeclaration.startOffset, classDeclaration.endOffset, - suggestNameForCapturedValue(capturedValue.owner), + suggestNameForCapturedValue(capturedValue.owner, generatedNames), Visibilities.PRIVATE, classDeclaration, capturedValue.owner.type @@ -689,12 +690,22 @@ class LocalDeclarationsLowering( } } - private fun suggestNameForCapturedValue(declaration: IrValueDeclaration): Name = - if (declaration.name.isSpecial) { - val oldNameStr = declaration.name.asString() - oldNameStr.substring(1, oldNameStr.length - 1).synthesizedName + private fun Name.stripSpecialMarkers(): String = + if (isSpecial) asString().substring(1, asString().length - 1) else asString() + + private fun suggestNameForCapturedValue(declaration: IrValueDeclaration, existing: MutableSet): Name { + val base = if (declaration.name.isSpecial) { + val oldName = declaration.name.stripSpecialMarkers() + val parentName = (declaration.parent as? IrDeclarationWithName)?.name?.stripSpecialMarkers() + if (parentName != null) "$oldName$$parentName" else oldName } else - declaration.name.asString().synthesizedName + declaration.name.asString() + var chosen = base.synthesizedName + var suffix = 0 + while (!existing.add(chosen)) + chosen = "$base$${++suffix}".synthesizedName + return chosen + } private fun collectClosureForLocalDeclarations() { diff --git a/compiler/testData/codegen/box/closures/captureExtensionReceiverX2.kt b/compiler/testData/codegen/box/closures/captureExtensionReceiverX2.kt new file mode 100644 index 00000000000..95ba048f18e --- /dev/null +++ b/compiler/testData/codegen/box/closures/captureExtensionReceiverX2.kt @@ -0,0 +1,6 @@ +fun String.f(x: String): String { + fun String.g() = { this@f + this@g }() + return x.g() +} + +fun box() = "O".f("K") diff --git a/compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/receiverClashInClass2.kt b/compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/receiverClashInClass2.kt index ee971f5b343..f497af6035a 100644 --- a/compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/receiverClashInClass2.kt +++ b/compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/receiverClashInClass2.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_MULTI_MODULE: JVM_IR // FILE: 1.kt // SKIP_INLINE_CHECK_IN: inlineFun$default package test diff --git a/compiler/testData/codegen/boxInline/innerClasses/captureThisAndOuter.kt b/compiler/testData/codegen/boxInline/innerClasses/captureThisAndOuter.kt new file mode 100644 index 00000000000..2c62de097c8 --- /dev/null +++ b/compiler/testData/codegen/boxInline/innerClasses/captureThisAndOuter.kt @@ -0,0 +1,11 @@ +// FILE: 1.kt +inline fun f(g: () -> String) = g() + +// FILE: 2.kt +class A(val x: String) { + inner class B(val y: String) { + fun h() = f { x + y } + } +} + +fun box() = A("O").B("K").h() diff --git a/compiler/testData/codegen/bytecodeText/mangling/parentheses.kt b/compiler/testData/codegen/bytecodeText/mangling/parentheses.kt index eb55d11b41d..b286e8c8fd2 100644 --- a/compiler/testData/codegen/bytecodeText/mangling/parentheses.kt +++ b/compiler/testData/codegen/bytecodeText/mangling/parentheses.kt @@ -19,4 +19,10 @@ fun box(): String { // One instance of each is in kotlin.Metadata.d2 // 1 \(X\) + +// JVM_TEMPLATES // 1 \(Y\) + +// JVM_IR_TEMPLATES +// 5 \(Y\) +// 4 \$this\$\(Y\) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index df9cc7c6583..1cb78747f98 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -3786,6 +3786,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/closures/captureExtensionReceiver.kt"); } + @TestMetadata("captureExtensionReceiverX2.kt") + public void testCaptureExtensionReceiverX2() throws Exception { + runTest("compiler/testData/codegen/box/closures/captureExtensionReceiverX2.kt"); + } + @TestMetadata("capturedLocalGenericFun.kt") public void testCapturedLocalGenericFun() throws Exception { runTest("compiler/testData/codegen/box/closures/capturedLocalGenericFun.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index b0f0282f5a9..dbf5664efca 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -1799,6 +1799,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/innerClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("captureThisAndOuter.kt") + public void testCaptureThisAndOuter() throws Exception { + runTest("compiler/testData/codegen/boxInline/innerClasses/captureThisAndOuter.kt"); + } + @TestMetadata("innerLambda.kt") public void testInnerLambda() throws Exception { runTest("compiler/testData/codegen/boxInline/innerClasses/innerLambda.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 4aca5d2f49f..997413d51fb 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1799,6 +1799,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/innerClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("captureThisAndOuter.kt") + public void testCaptureThisAndOuter() throws Exception { + runTest("compiler/testData/codegen/boxInline/innerClasses/captureThisAndOuter.kt"); + } + @TestMetadata("innerLambda.kt") public void testInnerLambda() throws Exception { runTest("compiler/testData/codegen/boxInline/innerClasses/innerLambda.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 31427e2310e..64770e2d0c9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -3786,6 +3786,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/closures/captureExtensionReceiver.kt"); } + @TestMetadata("captureExtensionReceiverX2.kt") + public void testCaptureExtensionReceiverX2() throws Exception { + runTest("compiler/testData/codegen/box/closures/captureExtensionReceiverX2.kt"); + } + @TestMetadata("capturedLocalGenericFun.kt") public void testCapturedLocalGenericFun() throws Exception { runTest("compiler/testData/codegen/box/closures/capturedLocalGenericFun.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index e4b2c946ab9..9b2e6745b14 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -3766,6 +3766,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/closures/captureExtensionReceiver.kt"); } + @TestMetadata("captureExtensionReceiverX2.kt") + public void testCaptureExtensionReceiverX2() throws Exception { + runTest("compiler/testData/codegen/box/closures/captureExtensionReceiverX2.kt"); + } + @TestMetadata("capturedLocalGenericFun.kt") public void testCapturedLocalGenericFun() throws Exception { runTest("compiler/testData/codegen/box/closures/capturedLocalGenericFun.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index 5d5ffdad7f5..98712a626fd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -1799,6 +1799,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/innerClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } + @TestMetadata("captureThisAndOuter.kt") + public void testCaptureThisAndOuter() throws Exception { + runTest("compiler/testData/codegen/boxInline/innerClasses/captureThisAndOuter.kt"); + } + @TestMetadata("innerLambda.kt") public void testInnerLambda() throws Exception { runTest("compiler/testData/codegen/boxInline/innerClasses/innerLambda.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 46e43b85490..394e3e6df72 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1799,6 +1799,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/innerClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } + @TestMetadata("captureThisAndOuter.kt") + public void testCaptureThisAndOuter() throws Exception { + runTest("compiler/testData/codegen/boxInline/innerClasses/captureThisAndOuter.kt"); + } + @TestMetadata("innerLambda.kt") public void testInnerLambda() throws Exception { runTest("compiler/testData/codegen/boxInline/innerClasses/innerLambda.kt"); 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 36aae920b3b..debf16e1498 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 @@ -3121,6 +3121,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/closures/captureExtensionReceiver.kt"); } + @TestMetadata("captureExtensionReceiverX2.kt") + public void testCaptureExtensionReceiverX2() throws Exception { + runTest("compiler/testData/codegen/box/closures/captureExtensionReceiverX2.kt"); + } + @TestMetadata("capturedLocalGenericFun.kt") public void testCapturedLocalGenericFun() throws Exception { runTest("compiler/testData/codegen/box/closures/capturedLocalGenericFun.kt"); 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 52c9e804ad4..f3a8e2c3645 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 @@ -3121,6 +3121,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/closures/captureExtensionReceiver.kt"); } + @TestMetadata("captureExtensionReceiverX2.kt") + public void testCaptureExtensionReceiverX2() throws Exception { + runTest("compiler/testData/codegen/box/closures/captureExtensionReceiverX2.kt"); + } + @TestMetadata("capturedLocalGenericFun.kt") public void testCapturedLocalGenericFun() throws Exception { runTest("compiler/testData/codegen/box/closures/capturedLocalGenericFun.kt");