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 aa4ad74b6a0..df578217bcc 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 @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.CommonBackendContext -import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.runOnFilePostfix @@ -633,7 +632,7 @@ class LocalDeclarationsLowering( newDeclaration.copyAttributes(oldDeclaration) newDeclaration.valueParameters += createTransformedValueParameters( - capturedValues, localFunctionContext, oldDeclaration, newDeclaration + capturedValues, localFunctionContext, oldDeclaration, newDeclaration, isExplicitLocalFunction = oldDeclaration.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA ) newDeclaration.recordTransformedValueParameters(localFunctionContext) @@ -646,7 +645,8 @@ class LocalDeclarationsLowering( capturedValues: List, localFunctionContext: LocalContext, oldDeclaration: IrFunction, - newDeclaration: IrFunction + newDeclaration: IrFunction, + isExplicitLocalFunction: Boolean = false ) = ArrayList(capturedValues.size + oldDeclaration.valueParameters.size).apply { val generatedNames = mutableSetOf() capturedValues.mapIndexedTo(this) { i, capturedValue -> @@ -657,7 +657,7 @@ class LocalDeclarationsLowering( origin = if (p is IrValueParameter && p.index < 0 && newDeclaration is IrConstructor) BOUND_RECEIVER_PARAMETER else BOUND_VALUE_PARAMETER - name = suggestNameForCapturedValue(p, generatedNames) + name = suggestNameForCapturedValue(p, generatedNames, isExplicitLocalFunction = isExplicitLocalFunction) index = i type = localFunctionContext.remapType(p.type) isCrossInline = (capturedValue as? IrValueParameterSymbol)?.owner?.isCrossinline == true @@ -786,7 +786,7 @@ class LocalDeclarationsLowering( private fun Name.stripSpecialMarkers(): String = if (isSpecial) asString().substring(1, asString().length - 1) else asString() - private fun suggestNameForCapturedValue(declaration: IrValueDeclaration, usedNames: MutableSet): Name { + private fun suggestNameForCapturedValue(declaration: IrValueDeclaration, usedNames: MutableSet, isExplicitLocalFunction: Boolean = false): Name { if (declaration is IrValueParameter) { if (declaration.name.asString() == "" && declaration.isDispatchReceiver()) { return findFirstUnusedName("this\$0", usedNames) { @@ -804,12 +804,21 @@ class LocalDeclarationsLowering( } } } - val base = if (declaration.name.isSpecial) + + val base = if (declaration.name.isSpecial) { declaration.name.stripSpecialMarkers() - else + } else { declaration.name.asString() - return findFirstUnusedName(base.synthesizedString, usedNames) { - "$base$$it".synthesizedString + } + + return if (isExplicitLocalFunction && declaration is IrVariable) { + findFirstUnusedName(base, usedNames) { + "$base$$it" + } + } else { + findFirstUnusedName(base.synthesizedString, usedNames) { + "$base$$it".synthesizedString + } } } diff --git a/compiler/testData/checkLocalVariablesTable/copyFunction.kt b/compiler/testData/checkLocalVariablesTable/copyFunction.kt deleted file mode 100644 index 667a6cafbbf..00000000000 --- a/compiler/testData/checkLocalVariablesTable/copyFunction.kt +++ /dev/null @@ -1,6 +0,0 @@ -data class someClass(val a: Double, val b: Double) - -// METHOD : someClass.copy(DD)LsomeClass; -// VARIABLE : NAME=this TYPE=LsomeClass; INDEX=0 -// VARIABLE : NAME=a TYPE=D INDEX=1 -// VARIABLE : NAME=b TYPE=D INDEX=3 \ No newline at end of file diff --git a/compiler/testData/checkLocalVariablesTable/destructuringInFor.kt b/compiler/testData/checkLocalVariablesTable/destructuringInFor.kt deleted file mode 100644 index c68ccef4d3f..00000000000 --- a/compiler/testData/checkLocalVariablesTable/destructuringInFor.kt +++ /dev/null @@ -1,14 +0,0 @@ -// WITH_RUNTIME - -fun box() { - val map: Map = mapOf() - for ((a, b) in map) { - a + b - } -} - -// METHOD : DestructuringInForKt.box()V - -// VARIABLE : NAME=b TYPE=Ljava/lang/String; INDEX=4 -// VARIABLE : NAME=a TYPE=Ljava/lang/String; INDEX=3 -// VARIABLE : NAME=map TYPE=Ljava/util/Map; INDEX=0 \ No newline at end of file diff --git a/compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt b/compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt deleted file mode 100644 index 2026e03abc0..00000000000 --- a/compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt +++ /dev/null @@ -1,22 +0,0 @@ -inline fun foo(x: (Int, Station) -> Unit) { - x(1, Station(null, "", 1)) -} - -data class Station( - val id: String?, - val name: String, - val distance: Int) - -fun box(): String { - foo { i, (a1, a2, a3) -> i + a3 } - return "OK" -} - -// METHOD : DestructuringInlineLambdaKt.box()Ljava/lang/String; -// VARIABLE : NAME=a1 TYPE=Ljava/lang/String; INDEX=4 -// VARIABLE : NAME=a2 TYPE=Ljava/lang/String; INDEX=5 -// VARIABLE : NAME=a3 TYPE=I INDEX=6 -// VARIABLE : NAME=i TYPE=I INDEX=2 -// VARIABLE : NAME=$dstr$a1$a2$a3 TYPE=LStation; INDEX=1 -// VARIABLE : NAME=$i$a$-foo-DestructuringInlineLambdaKt$box$1 TYPE=I INDEX=3 -// VARIABLE : NAME=$i$f$foo TYPE=I INDEX=0 diff --git a/compiler/testData/checkLocalVariablesTable/localFun.kt b/compiler/testData/checkLocalVariablesTable/localFun.kt deleted file mode 100644 index b69677cfe1e..00000000000 --- a/compiler/testData/checkLocalVariablesTable/localFun.kt +++ /dev/null @@ -1,18 +0,0 @@ -fun foo() { - val x = 1 - fun bar() { - val y = x - } -} - -// Local function bodies are in a separate class (implementing FunctionN) for non-IR, and are static methods in the enclosing class for IR. - -// JVM_TEMPLATES -// METHOD : LocalFunKt$foo$1.invoke()V -// VARIABLE : NAME=y TYPE=I INDEX=1 -// VARIABLE : NAME=this TYPE=LLocalFunKt$foo$1; INDEX=0 - -// JVM_IR_TEMPLATES -// METHOD : LocalFunKt.foo$bar(I)V -// VARIABLE : NAME=y TYPE=I INDEX=1 -// VARIABLE : NAME=$x TYPE=I INDEX=0 diff --git a/compiler/testData/codegen/bytecodeListing/localFunction.kt b/compiler/testData/codegen/bytecodeListing/localFunction.kt new file mode 100644 index 00000000000..1be855eee20 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/localFunction.kt @@ -0,0 +1,5 @@ +fun foo() { + fun bar() { + + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/localFunction.txt b/compiler/testData/codegen/bytecodeListing/localFunction.txt new file mode 100644 index 00000000000..a071f7b3a38 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/localFunction.txt @@ -0,0 +1,18 @@ +@kotlin.Metadata +final class LocalFunctionKt$foo$1 { + // source: 'localFunction.kt' + enclosing method LocalFunctionKt.foo()V + public final static field INSTANCE: LocalFunctionKt$foo$1 + inner (anonymous) class LocalFunctionKt$foo$1 + static method (): void + method (): void + public synthetic bridge method invoke(): java.lang.Object + public final method invoke(): void +} + +@kotlin.Metadata +public final class LocalFunctionKt { + // source: 'localFunction.kt' + inner (anonymous) class LocalFunctionKt$foo$1 + public final static method foo(): void +} diff --git a/compiler/testData/codegen/bytecodeListing/localFunction_ir.txt b/compiler/testData/codegen/bytecodeListing/localFunction_ir.txt new file mode 100644 index 00000000000..0cc950fc7a1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/localFunction_ir.txt @@ -0,0 +1,6 @@ +@kotlin.Metadata +public final class LocalFunctionKt { + // source: 'localFunction.kt' + private final static method foo$bar(): void + public final static method foo(): void +} diff --git a/compiler/testData/debug/localVariables/destructuringInFor.kt b/compiler/testData/debug/localVariables/destructuringInFor.kt index 4d690efa9b4..82e63627456 100644 --- a/compiler/testData/debug/localVariables/destructuringInFor.kt +++ b/compiler/testData/debug/localVariables/destructuringInFor.kt @@ -1,19 +1,16 @@ + + //FILE: test.kt - -// WITH_RUNTIME - fun box() { val map: Map = mapOf("1" to "23") - for ((a, b) - in map) { + for ((a, b) in map) { a + b } } -// IGNORE_BACKEND: JVM_IR + // LOCAL VARIABLES -// test.kt:6 box: -// test.kt:8 box: map:java.util.Map=java.util.Collections$SingletonMap -// test.kt:7 box: map:java.util.Map=java.util.Collections$SingletonMap -// test.kt:9 box: map:java.util.Map=java.util.Collections$SingletonMap, a:java.lang.String="1":java.lang.String, b:java.lang.String="23":java.lang.String -// test.kt:7 box: map:java.util.Map=java.util.Collections$SingletonMap -// test.kt:11 box: map:java.util.Map=java.util.Collections$SingletonMap \ No newline at end of file +// test.kt:5 box: +// test.kt:6 box: map:java.util.Map=java.util.Collections$SingletonMap +// test.kt:7 box: map:java.util.Map=java.util.Collections$SingletonMap, a:java.lang.String="1":java.lang.String, b:java.lang.String="23":java.lang.String +// test.kt:6 box: map:java.util.Map=java.util.Collections$SingletonMap +// test.kt:9 box: map:java.util.Map=java.util.Collections$SingletonMap \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/emptyFun.kt b/compiler/testData/debug/localVariables/emptyFun.kt new file mode 100644 index 00000000000..96113cacffa --- /dev/null +++ b/compiler/testData/debug/localVariables/emptyFun.kt @@ -0,0 +1,13 @@ + + +// FILE: test.kt +fun foo() {} + +fun box() { + foo() +} + +// LOCAL VARIABLES +// test.kt:7 box: +// test.kt:4 foo: +// test.kt:8 box: \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/localFun.kt b/compiler/testData/debug/localVariables/localFun.kt index c925105848f..12816a47206 100644 --- a/compiler/testData/debug/localVariables/localFun.kt +++ b/compiler/testData/debug/localVariables/localFun.kt @@ -1,16 +1,54 @@ -//FILE: test.kt + +//FILE: test.kt fun foo() { + val x = 1 fun bar() { + val y = x } + bar() } fun box() { foo() } -// IGNORE_BACKEND: JVM_IR + +// Local functions are compiled to private static functions on the class +// containing the local funtion. This has a number of consequences observable +// from a debugging perspective, for this test specifically: +// - local functions do not figure in the LVT of the outer function, as they +// are not instantiated. +// - the _declaration_ of the local function does not figure in the byte code +// of the outer function and hence, has no line number +// - captures are treated differently, according to the implementation +// strategy: on the IR, captures are passed as arguments to the static +// function, on the old backend, they are added to fields on the lambda +// object. Hence, for debugging purposes, captures are "just" +// variables local to the function, and hence need no name mangling to +// properly figure in the debugger. + // LOCAL VARIABLES -// test.kt:9 box: -// test.kt:4 foo: -// test.kt:6 foo: $fun$bar$1:TestKt$foo$1=TestKt$foo$1 -// test.kt:10 box: \ No newline at end of file +// test.kt:13 box: +// test.kt:5 foo: + +// LOCAL VARIABLES JVM +// test.kt:6 foo: x:int=1:int + +// LOCAL VARIABLES JVM +// test.kt:9 foo: x:int=1:int, $fun$bar$1:TestKt$foo$1=TestKt$foo$1 +// LOCAL VARIABLES JVM_IR +// test.kt:9 foo: x:int=1:int + +// LOCAL VARIABLES JVM +// test.kt:7 invoke: +// test.kt:8 invoke: y:int=1:int +// LOCAL VARIABLES JVM_IR +// test.kt:7 foo$bar: x:int=1:int +// test.kt:8 foo$bar: x:int=1:int, y:int=1:int + +// LOCAL VARIABLES JVM +// test.kt:10 foo: x:int=1:int, $fun$bar$1:TestKt$foo$1=TestKt$foo$1 +// test.kt:14 box: +// LOCAL VARIABLES JVM_IR +// test.kt:10 foo: x:int=1:int +// test.kt:14 box: \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/localFunUnused.kt b/compiler/testData/debug/localVariables/localFunUnused.kt new file mode 100644 index 00000000000..594a4695a32 --- /dev/null +++ b/compiler/testData/debug/localVariables/localFunUnused.kt @@ -0,0 +1,31 @@ + + +//FILE: test.kt +fun foo() { + fun bar() { + } +} + +fun box() { + foo() +} + +// Local functions are compiled to private static functions on the class +// containing the local funtion. This has a number of consequences observable +// from a debugging perspective, for this test specically: +// - local functions do not figure in the LVT of the outer function, as they +// are not instantiated. +// - the _declaration_ of the local function does not figure in the byte code +// of the outer function and hence, has no line number + +// LOCAL VARIABLES +// LOCAL VARIABLES JVM +// test.kt:10 box: +// test.kt:5 foo: +// test.kt:7 foo: $fun$bar$1:TestKt$foo$1=TestKt$foo$1 +// test.kt:11 box: + +// LOCAL VARIABLES JVM_IR +// test.kt:10 box: +// test.kt:7 foo: +// test.kt:11 box: \ No newline at end of file diff --git a/compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt b/compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt new file mode 100644 index 00000000000..3d06594087a --- /dev/null +++ b/compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt @@ -0,0 +1,25 @@ +// FILE: test.kt + +fun box() { + "OK" + fun bar() = "OK" + "OK" + bar() + "OK" +} + +// LINENUMBERS +// test.kt:4 box +// LINENUMBERS JVM +// test.kt:5 box +// LINENUMBERS +// test.kt:6 box +// test.kt:7 box +// LINENUMBERS JVM +// test.kt:5 invoke +// LINENUMBERS JVM_IR +// test.kt:5 box$bar +// LINENUMBERS +// test.kt:7 box +// test.kt:8 box +// test.kt:9 box \ No newline at end of file diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index d54049b27e8..382d70c5f14 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -155,6 +155,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/kt43519.kt"); } + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/localFunction.kt"); + } + @TestMetadata("localFunctionInInitBlock.kt") public void testLocalFunctionInInitBlock() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/localFunctionInInitBlock.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java index 267f391e8fd..9c0bc844e66 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java @@ -30,26 +30,11 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/checkLocalVariablesTable"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } - @TestMetadata("copyFunction.kt") - public void testCopyFunction() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/copyFunction.kt"); - } - - @TestMetadata("destructuringInFor.kt") - public void testDestructuringInFor() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/destructuringInFor.kt"); - } - @TestMetadata("destructuringInLambdas.kt") public void testDestructuringInLambdas() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/destructuringInLambdas.kt"); } - @TestMetadata("destructuringInlineLambda.kt") - public void testDestructuringInlineLambda() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt"); - } - @TestMetadata("inlineLambdaWithItParam.kt") public void testInlineLambdaWithItParam() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/inlineLambdaWithItParam.kt"); @@ -90,11 +75,6 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar runTest("compiler/testData/checkLocalVariablesTable/lambdaAsVar.kt"); } - @TestMetadata("localFun.kt") - public void testLocalFun() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/localFun.kt"); - } - @TestMetadata("objectInLocalPropertyDelegate.kt") public void testObjectInLocalPropertyDelegate() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/objectInLocalPropertyDelegate.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java index 4094a1216a5..127b565293f 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java @@ -56,6 +56,12 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest { runTest("compiler/testData/debug/localVariables/destructuringInLambdas.kt"); } + @Test + @TestMetadata("emptyFun.kt") + public void testEmptyFun() throws Exception { + runTest("compiler/testData/debug/localVariables/emptyFun.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -74,6 +80,12 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest { runTest("compiler/testData/debug/localVariables/localFun.kt"); } + @Test + @TestMetadata("localFunUnused.kt") + public void testLocalFunUnused() throws Exception { + runTest("compiler/testData/debug/localVariables/localFunUnused.kt"); + } + @Test @TestMetadata("underscoreNames.kt") public void testUnderscoreNames() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java index 26c4c084cf6..3f4c484da59 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java @@ -266,6 +266,12 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest { runTest("compiler/testData/debug/stepping/localFunction.kt"); } + @Test + @TestMetadata("localFunctionWIthOnelineExpressionBody.kt") + public void testLocalFunctionWIthOnelineExpressionBody() throws Exception { + runTest("compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt"); + } + @Test @TestMetadata("multilineFunctionCall.kt") public void testMultilineFunctionCall() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java index f2d72bf62ae..dc9082c975d 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java @@ -56,6 +56,12 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest { runTest("compiler/testData/debug/localVariables/destructuringInLambdas.kt"); } + @Test + @TestMetadata("emptyFun.kt") + public void testEmptyFun() throws Exception { + runTest("compiler/testData/debug/localVariables/emptyFun.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -74,6 +80,12 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest { runTest("compiler/testData/debug/localVariables/localFun.kt"); } + @Test + @TestMetadata("localFunUnused.kt") + public void testLocalFunUnused() throws Exception { + runTest("compiler/testData/debug/localVariables/localFunUnused.kt"); + } + @Test @TestMetadata("underscoreNames.kt") public void testUnderscoreNames() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java index 648c92c215e..eacf41515d0 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java @@ -266,6 +266,12 @@ public class SteppingTestGenerated extends AbstractSteppingTest { runTest("compiler/testData/debug/stepping/localFunction.kt"); } + @Test + @TestMetadata("localFunctionWIthOnelineExpressionBody.kt") + public void testLocalFunctionWIthOnelineExpressionBody() throws Exception { + runTest("compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt"); + } + @Test @TestMetadata("multilineFunctionCall.kt") public void testMultilineFunctionCall() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index e1e072ffb74..d9e1a3e75aa 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -155,6 +155,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/kt43519.kt"); } + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/localFunction.kt"); + } + @TestMetadata("localFunctionInInitBlock.kt") public void testLocalFunctionInInitBlock() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/localFunctionInInitBlock.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java index d26c883b88e..dca584a14d3 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java @@ -30,26 +30,11 @@ public class IrCheckLocalVariablesTableTestGenerated extends AbstractIrCheckLoca KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/checkLocalVariablesTable"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } - @TestMetadata("copyFunction.kt") - public void testCopyFunction() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/copyFunction.kt"); - } - - @TestMetadata("destructuringInFor.kt") - public void testDestructuringInFor() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/destructuringInFor.kt"); - } - @TestMetadata("destructuringInLambdas.kt") public void testDestructuringInLambdas() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/destructuringInLambdas.kt"); } - @TestMetadata("destructuringInlineLambda.kt") - public void testDestructuringInlineLambda() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt"); - } - @TestMetadata("inlineLambdaWithItParam.kt") public void testInlineLambdaWithItParam() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/inlineLambdaWithItParam.kt"); @@ -90,11 +75,6 @@ public class IrCheckLocalVariablesTableTestGenerated extends AbstractIrCheckLoca runTest("compiler/testData/checkLocalVariablesTable/lambdaAsVar.kt"); } - @TestMetadata("localFun.kt") - public void testLocalFun() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/localFun.kt"); - } - @TestMetadata("objectInLocalPropertyDelegate.kt") public void testObjectInLocalPropertyDelegate() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/objectInLocalPropertyDelegate.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinEvaluateExpressionTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinEvaluateExpressionTestGenerated.java index 31b25014a26..6e643a5f381 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinEvaluateExpressionTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinEvaluateExpressionTestGenerated.java @@ -337,6 +337,11 @@ public class IrKotlinEvaluateExpressionTestGenerated extends AbstractIrKotlinEva runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localClass.kt"); } + @TestMetadata("localFunctionCapturedLocalVariable.kt") + public void testLocalFunctionCapturedLocalVariable() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt"); + } + @TestMetadata("localFunctionsWithReceivers.kt") public void testLocalFunctionsWithReceivers() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionsWithReceivers.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinSteppingTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinSteppingTestGenerated.java index 6b39eec53a2..6ac4bf55172 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinSteppingTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinSteppingTestGenerated.java @@ -503,6 +503,16 @@ public class IrKotlinSteppingTestGenerated extends AbstractIrKotlinSteppingTest runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/lambdaToInlineMapFiltersDisabled.kt"); } + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt"); + } + + @TestMetadata("localFunctionWithSingleLineExpressionBody.kt") + public void testLocalFunctionWithSingleLineExpressionBody() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt"); + } + @TestMetadata("noParameterExtensionLambdaArgumentCallInInline.kt") public void testNoParameterExtensionLambdaArgumentCallInInline() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/noParameterExtensionLambdaArgumentCallInInline.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java index a0ff77b097c..49c8b3c954b 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java @@ -336,6 +336,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localClass.kt"); } + @TestMetadata("localFunctionCapturedLocalVariable.kt") + public void testLocalFunctionCapturedLocalVariable() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt"); + } + @TestMetadata("localFunctionsWithReceivers.kt") public void testLocalFunctionsWithReceivers() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionsWithReceivers.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinSteppingTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinSteppingTestGenerated.java index 60e08be64e6..1fce43faee8 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinSteppingTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinSteppingTestGenerated.java @@ -503,6 +503,16 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest { runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/lambdaToInlineMapFiltersDisabled.kt"); } + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt"); + } + + @TestMetadata("localFunctionWithSingleLineExpressionBody.kt") + public void testLocalFunctionWithSingleLineExpressionBody() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt"); + } + @TestMetadata("noParameterExtensionLambdaArgumentCallInInline.kt") public void testNoParameterExtensionLambdaArgumentCallInInline() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/noParameterExtensionLambdaArgumentCallInInline.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt new file mode 100644 index 00000000000..a0b11dd2ddb --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt @@ -0,0 +1,13 @@ +package localFunctionCapturedLocalVariable + +fun main(args: Array) { + val a = 1 + fun local() { + //Breakpoint! + val x = a + 2 + } + local() +} + +// EXPRESSION: a +// RESULT: 1: I diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.out b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.out new file mode 100644 index 00000000000..691ea28030f --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.out @@ -0,0 +1,8 @@ +LineBreakpoint created at localFunctionCapturedLocalVariable.kt:7 +Run Java +Connected to the target VM +localFunctionCapturedLocalVariable.kt:7 +Compile bytecode for a +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.ir.out b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.ir.out new file mode 100644 index 00000000000..caafbbb6392 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.ir.out @@ -0,0 +1,6 @@ +LineBreakpoint created at localFunction.kt:5 +Run Java +Connected to the target VM +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt new file mode 100644 index 00000000000..b50621e97a3 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt @@ -0,0 +1,12 @@ +package localFunction + +fun main() { + //Breakpoint! + fun bar() { + "OK" + } + bar() +} + +// STEP_OVER: 1 +// Code compiled on the IR cannot break on local function declarations \ No newline at end of file diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.out b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.out new file mode 100644 index 00000000000..13aac9ff50a --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.out @@ -0,0 +1,8 @@ +LineBreakpoint created at localFunction.kt:5 +Run Java +Connected to the target VM +localFunction.kt:5 +localFunction.kt:8 +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.ir.out b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.ir.out new file mode 100644 index 00000000000..1ce6d75cc17 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.ir.out @@ -0,0 +1,9 @@ +LineBreakpoint created at localFunctionWithSingleLineExpressionBody.kt:5 +Run Java +Connected to the target VM +localFunctionWithSingleLineExpressionBody.kt:5 +localFunctionWithSingleLineExpressionBody.kt:7 +Disconnected from the target VM + +Process finished with exit code 0 + diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt new file mode 100644 index 00000000000..92dd8e98f50 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt @@ -0,0 +1,13 @@ +package localFunctionWithSingleLineExpressionBody + +fun main() { + //Breakpoint! + fun bar() = "OK" + val x = 1 + bar() +} + +// STEP_OVER: 1 +// The behavior of the two backends is different because they stop at two different instructions. +// - The JVM backend stops on the declaration of bar on main:5, so stepping over proceeds to main:6 +// - The IR backend stops on the _body_ of bar when called from main:7, so proceeds to main:7 \ No newline at end of file diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.out b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.out new file mode 100644 index 00000000000..64c08d8fe31 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.out @@ -0,0 +1,10 @@ +LineBreakpoint created at localFunctionWithSingleLineExpressionBody.kt:5 +Run Java +Connected to the target VM +localFunctionWithSingleLineExpressionBody.kt:5 +localFunctionWithSingleLineExpressionBody.kt:6 +resuming localFunctionWithSingleLineExpressionBody.kt:5 +Disconnected from the target VM + +Process finished with exit code 0 +