diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 1af5a014d89..98a5fdd713f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.common.lower.BOUND_RECEIVER_PARAMETER +import org.jetbrains.kotlin.backend.common.lower.SYNTHESIZED_INIT_BLOCK import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods import org.jetbrains.kotlin.backend.jvm.intrinsics.JavaClassProperty @@ -324,15 +325,25 @@ class ExpressionCodegen( override fun visitBlock(expression: IrBlock, data: BlockInfo): PromisedValue { assert(expression !is IrReturnableBlock) { "unlowered returnable block: ${expression.dump()}" } + val isSynthesizedInitBlock = expression.origin == SYNTHESIZED_INIT_BLOCK + if (isSynthesizedInitBlock) { + expression.markLineNumber(startOffset = true) + mv.nop() + } if (expression.isTransparentScope) return super.visitBlock(expression, data) val info = BlockInfo(data) // Force materialization to avoid reading from out-of-scope variables. - return super.visitBlock(expression, info).materialized().also { + val value = super.visitBlock(expression, info).materialized().also { if (info.variables.isNotEmpty()) { writeLocalVariablesInTable(info, markNewLabel()) } } + if (isSynthesizedInitBlock) { + expression.markLineNumber(startOffset = false) + mv.nop() + } + return value } private val IrVariable.isVisibleInLVT: Boolean diff --git a/compiler/testData/debug/stepping/initBlocks.kt b/compiler/testData/debug/stepping/initBlocks.kt index b4ecbd24363..673a77a9390 100644 --- a/compiler/testData/debug/stepping/initBlocks.kt +++ b/compiler/testData/debug/stepping/initBlocks.kt @@ -51,10 +51,8 @@ fun box() { Zoo() } -// IGNORE_BACKEND: JVM_IR -// The JVM_IR does not generate code that will break on the line -// containing the `init`, nor the exit from the `init`. It only -// contains lines for the contents of the init blocks. +// JVM_IR has an extra step back to the line of the class +// declaration for the return in the constructor. // LINENUMBERS // test.kt:48 box @@ -64,6 +62,9 @@ fun box() { // test.kt:45 x // test.kt:7 // test.kt:8 +// LINENUMBERS JVM_IR +// test.kt:3 +// LINENUMBERS // test.kt:48 box // test.kt:49 box // test.kt:11 @@ -73,6 +74,9 @@ fun box() { // test.kt:16 // test.kt:17 // test.kt:18 +// LINENUMBERS JVM_IR +// test.kt:11 +// LINENUMBERS // test.kt:49 box // test.kt:50 box // test.kt:21 @@ -85,6 +89,9 @@ fun box() { // test.kt:28 // test.kt:29 // test.kt:30 +// LINENUMBERS JVM_IR +// test.kt:21 +// LINENUMBERS // test.kt:50 box // test.kt:51 box // test.kt:33 @@ -94,5 +101,8 @@ fun box() { // test.kt:39 // test.kt:40 // test.kt:42 +// LINENUMBERS JVM_IR +// test.kt:33 +// LINENUMBERS // test.kt:51 box // test.kt:52 box diff --git a/compiler/testData/debug/stepping/initBlocksCompanion.kt b/compiler/testData/debug/stepping/initBlocksCompanion.kt new file mode 100644 index 00000000000..4b0c529188f --- /dev/null +++ b/compiler/testData/debug/stepping/initBlocksCompanion.kt @@ -0,0 +1,52 @@ +// FILE: test.kt + +class A { + companion object { + val s: String + + init { + s = "OK" + } + + val x = x() + + init { val a = 32 } + + init { + val b = 42 + } + + init + { + val c = 43 + } + } +} + +fun x() = "" + +fun box() { + A.x + A.s +} + +// JVM backend has extra steps for getX and getS. + +// TODO: since these tests operate as step-into, we do not get any steps +// in the for the companion object. Maybe extend the test infrastructure +// with directives to set break points in order to test this. + +// LINENUMBERS +// test.kt:29 box +// test.kt:11 getX +// LINENUMBERS JVM +// test.kt:11 getX +// LINENUMBERS +// test.kt:29 box +// test.kt:30 box +// test.kt:5 getS +// LINENUMBERS JVM +// test.kt:5 getS +// LINENUMBERS +// test.kt:30 box +// test.kt:31 box \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java index fb757aeda24..443199c20d3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java @@ -193,6 +193,12 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest { runTest("compiler/testData/debug/stepping/initBlocks.kt"); } + @Test + @TestMetadata("initBlocksCompanion.kt") + public void testInitBlocksCompanion() throws Exception { + runTest("compiler/testData/debug/stepping/initBlocksCompanion.kt"); + } + @Test @TestMetadata("inlineCallableReference.kt") public void testInlineCallableReference() throws Exception { diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java index cbadcc9dc80..0853eb0b9ee 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java @@ -193,6 +193,12 @@ public class SteppingTestGenerated extends AbstractSteppingTest { runTest("compiler/testData/debug/stepping/initBlocks.kt"); } + @Test + @TestMetadata("initBlocksCompanion.kt") + public void testInitBlocksCompanion() throws Exception { + runTest("compiler/testData/debug/stepping/initBlocksCompanion.kt"); + } + @Test @TestMetadata("inlineCallableReference.kt") public void testInlineCallableReference() throws Exception { diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen/Basic.ir.txt b/plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen/Basic.ir.txt index 4a5f19f6883..55adbd53bcb 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen/Basic.ir.txt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen/Basic.ir.txt @@ -25,6 +25,8 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa ALOAD (0) CHECKCAST PUTSTATIC (descriptor, Lkotlinx/serialization/SerialDescriptor;) + LABEL (L1) + LINENUMBER (13) RETURN } @@ -332,6 +334,8 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ ALOAD (0) CHECKCAST PUTSTATIC (descriptor, Lkotlinx/serialization/SerialDescriptor;) + LABEL (L1) + LINENUMBER (10) RETURN } @@ -687,6 +691,8 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in ALOAD (0) CHECKCAST PUTSTATIC (descriptor, Lkotlinx/serialization/SerialDescriptor;) + LABEL (L1) + LINENUMBER (7) RETURN } @@ -1000,4 +1006,4 @@ public final class User : java/lang/Object { public final java.lang.String getFirstName() public final java.lang.String getLastName() -} +} \ No newline at end of file