From 73af7f89bdb2c5a01bd4f3329d2ec10fb2388864 Mon Sep 17 00:00:00 2001 From: Bartek Pacia Date: Tue, 24 Jun 2025 13:46:23 +0200 Subject: [PATCH] [ByteCodeViewer] IDEA-373600 Fix source<->bytecode matching being off by one when debug info is shown GitOrigin-RevId: 57d6587afdbb97d966cf2c5460ccbc7f793fd0e4 --- .../byteCodeViewer/bytecodeLineMapping.kt | 6 +++++- .../byteCodeViewer/BytecodeLineMappingTest.kt | 18 +++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/bytecodeLineMapping.kt b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/bytecodeLineMapping.kt index 3ab673becff4..00aa865ce3c7 100644 --- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/bytecodeLineMapping.kt +++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/bytecodeLineMapping.kt @@ -36,7 +36,7 @@ internal fun removeDebugInfo(bytecodeWithDebugInfo: String): String = bytecodeWi * @return A pair where the first element is the start line number in the bytecode, and the second element is the end line number in the bytecode. Returns (0, 0) if no valid mapping * is found. */ -internal fun mapLines(bytecodeWithDebugInfo: String, sourceStartLine: Int, sourceEndLine: Int, showDebugInfo: Boolean = true): IntRange { +internal fun mapLines(bytecodeWithDebugInfo: String, sourceStartLine: Int, sourceEndLine: Int, showDebugInfo: Boolean): IntRange { var sourceStartLine = sourceStartLine // editor selection is 0-indexed var currentBytecodeLine = 0 var bytecodeStartLine = -1 @@ -97,6 +97,10 @@ internal fun mapLines(bytecodeWithDebugInfo: String, sourceStartLine: Int, sourc bytecodeStartLine -= linesToSkipBeforeStartLine bytecodeEndLine -= linesToSkipBeforeEndLine } + else { + bytecodeStartLine -= 1 + bytecodeEndLine -= 1 + } return if (bytecodeStartLine == -1 || bytecodeEndLine == -1) IntRange(0, 0) else IntRange(bytecodeStartLine, bytecodeEndLine) } diff --git a/plugins/ByteCodeViewer/test/com/intellij/byteCodeViewer/BytecodeLineMappingTest.kt b/plugins/ByteCodeViewer/test/com/intellij/byteCodeViewer/BytecodeLineMappingTest.kt index b27f2a0a399a..f8f445777d59 100644 --- a/plugins/ByteCodeViewer/test/com/intellij/byteCodeViewer/BytecodeLineMappingTest.kt +++ b/plugins/ByteCodeViewer/test/com/intellij/byteCodeViewer/BytecodeLineMappingTest.kt @@ -122,7 +122,7 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { fixture = simple1, showDebugInfo = true, expectedBytecodeSelection = """ - | LINENUMBER 5 L0 + | L0 """.trimMargin("|"), ) } @@ -168,12 +168,12 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { doTest( sourceWithSelection = source, fixture = simple1, showDebugInfo = true, expectedBytecodeSelection = """ + | L0 | LINENUMBER 5 L0 | GETSTATIC java/lang/System.out : Ljava/io/PrintStream; | LDC "hello world" | INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V | L1 - | LINENUMBER 6 L1 """.trimMargin("|"), ) } @@ -219,6 +219,7 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { doTest( sourceWithSelection = source, fixture = simple1, showDebugInfo = true, expectedBytecodeSelection = """ + | L0 | LINENUMBER 5 L0 | GETSTATIC java/lang/System.out : Ljava/io/PrintStream; | LDC "hello world" @@ -227,7 +228,6 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { | LINENUMBER 6 L1 | RETURN | L2 - | LOCALVARIABLE args [Ljava/lang/String; L0 L2 0 """.trimMargin("|"), ) } @@ -270,10 +270,10 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { doTest( sourceWithSelection = source, fixture = simple1, showDebugInfo = true, expectedBytecodeSelection = """ + | L1 | LINENUMBER 6 L1 | RETURN | L2 - | LOCALVARIABLE args [Ljava/lang/String; L0 L2 0 """.trimMargin("|"), ) } @@ -317,12 +317,12 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { doTest( sourceWithSelection = source, fixture = simple1, showDebugInfo = true, expectedBytecodeSelection = """ + | L0 | LINENUMBER 3 L0 | ALOAD 0 | INVOKESPECIAL java/lang/Object. ()V | RETURN | L1 - | LOCALVARIABLE this Lsimple1/Main; L0 L1 0 """.trimMargin("|"), ) } @@ -376,11 +376,11 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { doTest( sourceWithSelection = source, fixture = simple2, showDebugInfo = true, expectedBytecodeSelection = """ + | L0 | LINENUMBER 4 L0 | LDC "Charlie" | PUTSTATIC simple2/Main.name : Ljava/lang/String; | L1 - | LINENUMBER 5 L1 """.trimMargin("|"), ) } @@ -439,6 +439,7 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { doTest( sourceWithSelection = source, fixture = simple2, showDebugInfo = true, expectedBytecodeSelection = """ + | L0 | LINENUMBER 4 L0 | LDC "Charlie" | PUTSTATIC simple2/Main.name : Ljava/lang/String; @@ -449,7 +450,6 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { | INVOKESPECIAL java/lang/Object. ()V | PUTSTATIC simple2/Main.obj : Ljava/lang/Object; | RETURN - | MAXSTACK = 2 """.trimMargin("|"), ) } @@ -508,6 +508,7 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { doTest( sourceWithSelection = source, fixture = simple2, showDebugInfo = true, expectedBytecodeSelection = """ + | L0 | LINENUMBER 8 L0 | GETSTATIC java/lang/System.out : Ljava/io/PrintStream; | LDC "hello world" @@ -518,7 +519,6 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { | ARRAYLENGTH | ISTORE 1 | L2 - | LINENUMBER 10 L2 """.trimMargin("|"), ) } @@ -622,6 +622,7 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { doTest( sourceWithSelection = source, fixture = simple3, showDebugInfo = true, expectedBytecodeSelection = """ + | L0 | LINENUMBER 12 L0 | ILOAD 1 | GETSTATIC java/lang/Boolean.TRUE : Ljava/lang/Boolean; @@ -632,7 +633,6 @@ class BytecodeLineMappingTest : BasePlatformTestCase() { | LDC "bar" | ARETURN | L1 - | LINENUMBER 15 L1 """.trimMargin("|"), ) }