提交 dc34d355 编写于 作者: M Mads Ager 提交者: max-kammerer

[JVM_IR] Generate line numbers and nops for init blocks.

This seems to be what JVM does and it allows you to set a
breakpoint on the init line.
上级 85e2392f
......@@ -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
......
......@@ -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 <init>
// test.kt:8 <init>
// LINENUMBERS JVM_IR
// test.kt:3 <init>
// LINENUMBERS
// test.kt:48 box
// test.kt:49 box
// test.kt:11 <init>
......@@ -73,6 +74,9 @@ fun box() {
// test.kt:16 <init>
// test.kt:17 <init>
// test.kt:18 <init>
// LINENUMBERS JVM_IR
// test.kt:11 <init>
// LINENUMBERS
// test.kt:49 box
// test.kt:50 box
// test.kt:21 <init>
......@@ -85,6 +89,9 @@ fun box() {
// test.kt:28 <init>
// test.kt:29 <init>
// test.kt:30 <init>
// LINENUMBERS JVM_IR
// test.kt:21 <init>
// LINENUMBERS
// test.kt:50 box
// test.kt:51 box
// test.kt:33 <init>
......@@ -94,5 +101,8 @@ fun box() {
// test.kt:39 <init>
// test.kt:40 <init>
// test.kt:42 <init>
// LINENUMBERS JVM_IR
// test.kt:33 <init>
// LINENUMBERS
// test.kt:51 box
// test.kt:52 box
// 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 <clinit> 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
......@@ -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 {
......
......@@ -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 {
......
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册