From 27fb46712aee604deb47e5352d87a3c4a380c061 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersen Date: Mon, 19 Oct 2020 15:34:16 +0200 Subject: [PATCH] [JVM+IR] Unify new debugger tests expectations This commit unifies the expectation format between the stepping and LVT tests in the new debugging test harness. Furthermore, it introduces a compression of runs of locations without linenumbers. These default to showing as bytecode offsets from previous line number, which overspecifies the tests: the bytecodes chosen should not be constrained by a debugging step test. --- .../debug/localVariables/catchClause.kt | 14 ++--- .../debug/localVariables/copyFunction.kt | 17 +++--- .../localVariables/destructuringInFor.kt | 12 ++--- .../localVariables/destructuringInLambdas.kt | 19 ++++--- .../debug/localVariables/inlineProperty.kt | 16 +++--- .../debug/localVariables/jvmOverloads.kt | 12 ++--- .../testData/debug/localVariables/localFun.kt | 8 +-- .../debug/localVariables/receiverParameter.kt | 6 +-- .../debug/localVariables/suspend/simple.kt | 4 +- .../localVariables/suspend/underscoreNames.kt | 52 +++++++++++++++++++ .../debug/localVariables/underscoreNames.kt | 41 ++++++--------- .../debugInformation/AbstractDebugTest.kt | 29 +++++++++++ .../AbstractLocalVariableTest.kt | 30 +++++++---- .../debugInformation/AbstractSteppingTest.kt | 11 ++-- .../IrLocalVariableTestGenerated.java | 6 +++ .../LocalVariableTestGenerated.java | 6 +++ 16 files changed, 184 insertions(+), 99 deletions(-) create mode 100644 compiler/testData/debug/localVariables/suspend/underscoreNames.kt diff --git a/compiler/testData/debug/localVariables/catchClause.kt b/compiler/testData/debug/localVariables/catchClause.kt index 5ca09e84bd9..d3e93aff10a 100644 --- a/compiler/testData/debug/localVariables/catchClause.kt +++ b/compiler/testData/debug/localVariables/catchClause.kt @@ -10,10 +10,10 @@ fun box() { } // LOCAL VARIABLES -// TestKt:3: -// TestKt:4: -// TestKt:5: a:int=1:int -// TestKt:6: a:int=0:int -// TestKt:7: -// TestKt:8: e:java.lang.Throwable=java.lang.ArithmeticException -// TestKt:10: +// test.kt:3 box: +// test.kt:4 box: +// test.kt:5 box: a:int=1:int +// test.kt:6 box: a:int=0:int +// test.kt:7 box: +// test.kt:8 box: e:java.lang.Throwable=java.lang.ArithmeticException +// test.kt:10 box: diff --git a/compiler/testData/debug/localVariables/copyFunction.kt b/compiler/testData/debug/localVariables/copyFunction.kt index 76184a8121d..a87960d3b5f 100644 --- a/compiler/testData/debug/localVariables/copyFunction.kt +++ b/compiler/testData/debug/localVariables/copyFunction.kt @@ -8,12 +8,11 @@ fun box() { } // LOCAL VARIABLES -// TestKt:6: -// someClass:3: a:double=1.0:double, b:double=2.0:double -// TestKt:6: -// TestKt:7: a:someClass=someClass -// someClass:3: a:double=1.0:double, b:double=3.0:double -// someClass.copy(double, double)+9: a:double=1.0:double, b:double=3.0:double -// someClass.copy$default(someClass, double, double, int, java.lang.Object)+30: -// TestKt:7: a:someClass=someClass -// TestKt:8: a:someClass=someClass, b:someClass=someClass \ No newline at end of file +// test.kt:6 box: +// test.kt:3 : a:double=1.0:double, b:double=2.0:double +// test.kt:6 box: +// test.kt:7 box: a:someClass=someClass +// test.kt:3 : a:double=1.0:double, b:double=3.0:double +// test.kt:-1 copy: a:double=1.0:double, b:double=3.0:double +// test.kt:7 box: a:someClass=someClass +// test.kt:8 box: a:someClass=someClass, b:someClass=someClass \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/destructuringInFor.kt b/compiler/testData/debug/localVariables/destructuringInFor.kt index ed6bdaefe7a..4d690efa9b4 100644 --- a/compiler/testData/debug/localVariables/destructuringInFor.kt +++ b/compiler/testData/debug/localVariables/destructuringInFor.kt @@ -11,9 +11,9 @@ fun box() { } // IGNORE_BACKEND: JVM_IR // LOCAL VARIABLES -// TestKt:6: -// TestKt:8: map:java.util.Map=java.util.Collections$SingletonMap -// TestKt:7: map:java.util.Map=java.util.Collections$SingletonMap -// TestKt:9: map:java.util.Map=java.util.Collections$SingletonMap, a:java.lang.String="1":java.lang.String, b:java.lang.String="23":java.lang.String -// TestKt:7: map:java.util.Map=java.util.Collections$SingletonMap -// TestKt:11: map:java.util.Map=java.util.Collections$SingletonMap \ No newline at end of file +// 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 diff --git a/compiler/testData/debug/localVariables/destructuringInLambdas.kt b/compiler/testData/debug/localVariables/destructuringInLambdas.kt index 6d680bf8def..3436e806768 100644 --- a/compiler/testData/debug/localVariables/destructuringInLambdas.kt +++ b/compiler/testData/debug/localVariables/destructuringInLambdas.kt @@ -7,14 +7,13 @@ fun foo(a: A, block: (A) -> String): String = block(a) fun box() { foo(A("O", 123)) { (x, y) -> x + y } } -// IGNORE_BACKEND: JVM_IR + // LOCAL VARIABLES -// TestKt:8: -// A:3: x:java.lang.String="O":java.lang.String, y:int=123:int -// TestKt:8: -// TestKt:5: a:A=A, block:kotlin.jvm.functions.Function1=TestKt$box$1 -// TestKt$box$1:8: $dstr$x$y:A=A -// TestKt$box$1.invoke(java.lang.Object)+8: -// TestKt:5: a:A=A, block:kotlin.jvm.functions.Function1=TestKt$box$1 -// TestKt:8: -// TestKt:9: \ No newline at end of file +// test.kt:8 box: +// test.kt:3 : x:java.lang.String="O":java.lang.String, y:int=123:int +// test.kt:8 box: +// test.kt:5 foo: a:A=A, block:kotlin.jvm.functions.Function1=TestKt$box$1 +// test.kt:8 invoke: $dstr$x$y:A=A +// test.kt:5 foo: a:A=A, block:kotlin.jvm.functions.Function1=TestKt$box$1 +// test.kt:8 box: +// test.kt:9 box: \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/inlineProperty.kt b/compiler/testData/debug/localVariables/inlineProperty.kt index bfe59934a1f..bed55267726 100644 --- a/compiler/testData/debug/localVariables/inlineProperty.kt +++ b/compiler/testData/debug/localVariables/inlineProperty.kt @@ -11,11 +11,11 @@ fun box() { } // LOCAL VARIABLES -// TestKt:8: -// A:2: -// TestKt:8: -// TestKt:9: a:A=A -// TestKt:4: a:A=A, this_$iv:A=A, $i$f$getS:int=0:int -// TestKt:9: a:A=A -// TestKt:10: a:A=A, y:int=1:int -// TestKt:11: a:A=A, y:int=2:int \ No newline at end of file +// test.kt:8 box: +// test.kt:2 : +// test.kt:8 box: +// test.kt:9 box: a:A=A +// test.kt:4 box: a:A=A, this_$iv:A=A, $i$f$getS:int=0:int +// test.kt:9 box: a:A=A +// test.kt:10 box: a:A=A, y:int=1:int +// test.kt:11 box: a:A=A, y:int=2:int \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/jvmOverloads.kt b/compiler/testData/debug/localVariables/jvmOverloads.kt index 66ebeaabc6e..0bfa6de8ed8 100644 --- a/compiler/testData/debug/localVariables/jvmOverloads.kt +++ b/compiler/testData/debug/localVariables/jvmOverloads.kt @@ -10,10 +10,8 @@ fun box() { } // LOCAL VARIABLES -// TestKt:9: -// C:3: -// TestKt:9: -// C:4: -// C:5: firstParam:int=4:int, secondParam:java.lang.String="":java.lang.String -// C:4: -// TestKt:10: \ No newline at end of file +// test.kt:9 box: +// test.kt:3 : +// test.kt:9 box: +// test.kt:5 foo: firstParam:int=4:int, secondParam:java.lang.String="":java.lang.String +// test.kt:10 box: \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/localFun.kt b/compiler/testData/debug/localVariables/localFun.kt index 7cdccc8a8db..c925105848f 100644 --- a/compiler/testData/debug/localVariables/localFun.kt +++ b/compiler/testData/debug/localVariables/localFun.kt @@ -10,7 +10,7 @@ fun box() { } // IGNORE_BACKEND: JVM_IR // LOCAL VARIABLES -// TestKt:9: -// TestKt:4: -// TestKt:6: $fun$bar$1:TestKt$foo$1=TestKt$foo$1 -// TestKt:10: \ No newline at end of file +// 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 diff --git a/compiler/testData/debug/localVariables/receiverParameter.kt b/compiler/testData/debug/localVariables/receiverParameter.kt index 5f7ffae8567..951d95a57f2 100644 --- a/compiler/testData/debug/localVariables/receiverParameter.kt +++ b/compiler/testData/debug/localVariables/receiverParameter.kt @@ -8,6 +8,6 @@ fun box() { } // LOCAL VARIABLES -// TestKt:7: -// TestKt:4: $this$test:java.lang.String="OK":java.lang.String -// TestKt:8: \ No newline at end of file +// test.kt:7 box: +// test.kt:4 test: $this$test:java.lang.String="OK":java.lang.String +// test.kt:8 box: \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/suspend/simple.kt b/compiler/testData/debug/localVariables/suspend/simple.kt index 272cf66b631..56f5657c19b 100644 --- a/compiler/testData/debug/localVariables/suspend/simple.kt +++ b/compiler/testData/debug/localVariables/suspend/simple.kt @@ -6,5 +6,5 @@ suspend fun box() { } // LOCAL VARIABLES -// TestKt:5: $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation -// TestKt:6: $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation, x:int=1:int \ No newline at end of file +// test.kt:5 box: $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation +// test.kt:6 box: $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation, x:int=1:int \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/suspend/underscoreNames.kt b/compiler/testData/debug/localVariables/suspend/underscoreNames.kt new file mode 100644 index 00000000000..d654a083455 --- /dev/null +++ b/compiler/testData/debug/localVariables/suspend/underscoreNames.kt @@ -0,0 +1,52 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// FILE: test.kt +class A { + operator fun component1() = "O" + operator fun component2(): String = throw RuntimeException("fail 0") + operator fun component3() = "K" +} + +suspend fun foo(a: A, block: suspend (A) -> String): String = block(a) + +suspend fun box() = foo(A()) { (x_param, _, y_param) -> + x_param + y_param +} + +// Parameters (including anonymous destructuring parameters) are moved to fields in the Continuation class for the suspend lambda class. +// However, in non-IR, the fields are first stored in local variables, and they are not read directly (even for destructuring components). +// In IR, the fields are directly read from. + +// METHOD : UnderscoreNamesKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; + +// JVM_TEMPLATES +// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3 +// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=4 +// VARIABLE : NAME=this TYPE=LUnderscoreNamesKt$test$2; INDEX=0 +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 + +// JVM_IR_TEMPLATES +// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=2 +// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=3 +// VARIABLE : NAME=this TYPE=LUnderscoreNamesKt$test$2; INDEX=0 +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 + +// IGNORE_BACKEND: JVM_IR +// LOCAL VARIABLES +// test.kt:12 box: $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation +// test.kt:4 : +// test.kt:12 box: $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation +// test.kt:10 foo: a:A=A, block:kotlin.jvm.functions.Function2=TestKt$box$2, $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation +// CoroutineUtil.kt:28 getContext: +// test.kt:-1 : +// test.kt:-1 create: value:java.lang.Object=A, completion:kotlin.coroutines.Continuation=helpers.ResultContinuation +// test.kt:-1 invoke: +// test.kt:12 invokeSuspend: +// test.kt:5 component1: +// test.kt:12 invokeSuspend: $result:java.lang.Object=kotlin.Unit, $dstr$x_param$_u24__u24$y_param:A=A +// test.kt:7 component3: +// test.kt:12 invokeSuspend: $result:java.lang.Object=kotlin.Unit, $dstr$x_param$_u24__u24$y_param:A=A +// test.kt:13 invokeSuspend: $result:java.lang.Object=kotlin.Unit, x_param:java.lang.String="O":java.lang.String, y_param:java.lang.String="K":java.lang.String +// test.kt:-1 invoke: +// test.kt:10 foo: a:A=A, block:kotlin.jvm.functions.Function2=TestKt$box$2, $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation +// test.kt:14 box: $completion:kotlin.coroutines.Continuation=helpers.ResultContinuation \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/underscoreNames.kt b/compiler/testData/debug/localVariables/underscoreNames.kt index 9dce211a2d1..f106a2bcea3 100644 --- a/compiler/testData/debug/localVariables/underscoreNames.kt +++ b/compiler/testData/debug/localVariables/underscoreNames.kt @@ -23,27 +23,20 @@ fun box() { } // IGNORE_BACKEND: JVM_IR // LOCAL VARIABLES -// TestKt:11: -// A:3: -// A:3: x:double=1.0:double, y:java.lang.String="":java.lang.String, z:char=0:char -// A:3: -// TestKt:11: -// TestKt:5: a:A=A, block:kotlin.jvm.functions.Function3=TestKt$box$1 -// TestKt$box$1:14: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int -// A:3: -// A:3: x:double=1.0:double, y:java.lang.String="":java.lang.String, z:char=0:char -// A:3: -// TestKt$box$1:14: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char -// TestKt$box$1:15: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char -// A:3: -// A:3: x:double=1.0:double, y:java.lang.String="":java.lang.String, z:char=0:char -// A:3: -// TestKt$box$1:15: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char -// TestKt$box$1:17: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char, _:java.lang.String="":java.lang.String, d:char=0:char -// TestKt:7: -// TestKt$box$1:17: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char, _:java.lang.String="":java.lang.String, d:char=0:char -// TestKt$box$1:21: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char, _:java.lang.String="":java.lang.String, d:char=0:char -// TestKt$box$1.invoke(java.lang.Object, java.lang.Object, java.lang.Object)+19: -// TestKt:5: a:A=A, block:kotlin.jvm.functions.Function3=TestKt$box$1 -// TestKt:11: -// TestKt:23: \ No newline at end of file +// test.kt:11 box: +// test.kt:3 : x:double=1.0:double, y:java.lang.String="":java.lang.String, z:char=0:char +// test.kt:11 box: +// test.kt:5 foo: a:A=A, block:kotlin.jvm.functions.Function3=TestKt$box$1 +// test.kt:14 invoke: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int +// test.kt:3 : x:double=1.0:double, y:java.lang.String="":java.lang.String, z:char=0:char +// test.kt:14 invoke: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char +// test.kt:15 invoke: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char +// test.kt:3 : x:double=1.0:double, y:java.lang.String="":java.lang.String, z:char=0:char +// test.kt:15 invoke: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char +// test.kt:17 invoke: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char, _:java.lang.String="":java.lang.String, d:char=0:char +// test.kt:7 getArrayOfA: +// test.kt:17 invoke: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char, _:java.lang.String="":java.lang.String, d:char=0:char +// test.kt:21 invoke: $dstr$x$_u24__u24$y:A=A, $noName_1:java.lang.String="":java.lang.String, w:int=1:int, x:double=1.0:double, y:char=0:char, a:double=1.0:double, c:char=0:char, _:java.lang.String="":java.lang.String, d:char=0:char +// test.kt:5 foo: a:A=A, block:kotlin.jvm.functions.Function3=TestKt$box$1 +// test.kt:11 box: +// test.kt:23 box: \ No newline at end of file diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractDebugTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractDebugTest.kt index 0a086afbe79..555355b3ad4 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractDebugTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractDebugTest.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.util.SystemInfo import com.intellij.util.PathUtil import com.intellij.util.SystemProperties import com.sun.jdi.AbsentInformationException +import com.sun.jdi.Location import com.sun.jdi.VirtualMachine import com.sun.jdi.event.* import com.sun.jdi.request.EventRequest @@ -266,6 +267,34 @@ abstract class AbstractDebugTest : CodegenTestCase() { checkResult(wholeFile, loggedItems) } + fun Location.formatAsExpectation(): String { + val synthetic = if (method().isSynthetic) " (synthetic)" else "" + return "${sourceName()}:${lineNumber()} ${method().name()}$synthetic" + } + + /* + Compresses runs of the same, linenumber-less location in the log: + specifically removes locations without linenumber, that would otherwise + print as byte offsets. This avoids overspecifying code generation + strategy in debug tests. + */ + fun compressRunsWithoutLinenumber(loggedItems: List, getLocation: (T) -> Location): List { + if (loggedItems.isEmpty()) return listOf() + + val logIterator = loggedItems.iterator() + var currentItem = logIterator.next() + val result = mutableListOf(currentItem) + + for (logItem in logIterator) { + if (getLocation(currentItem).lineNumber() != -1 || getLocation(currentItem).formatAsExpectation() != getLocation(logItem).formatAsExpectation()) { + result.add(logItem) + currentItem = logItem + } + } + + return result + } + abstract fun storeStep(loggedItems: ArrayList, event: Event) abstract fun checkResult(wholeFile: File, loggedItems: List) diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractLocalVariableTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractLocalVariableTest.kt index 52c90fd2d19..c3aec9a7e32 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractLocalVariableTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractLocalVariableTest.kt @@ -72,19 +72,24 @@ abstract class AbstractLocalVariableTest : AbstractDebugTest() { } } + data class LVTStep( + val location : Location, + val visibleVars: Collection + ) + override fun storeStep(loggedItems: ArrayList, event: Event) { - waitUntil { (event as LocatableEvent).thread().isSuspended } - val frame = (event as LocatableEvent).thread().frame(0) - try { - val visibleVars = frame - .visibleVariables() - .map { variable -> toRecord(frame, variable) } - .joinToString(", ") - loggedItems.add("${event.location()}: $visibleVars".trim()) + val locatableEvent = event as LocatableEvent + waitUntil { locatableEvent.thread().isSuspended } + val location = locatableEvent.location() + if (location.method().isSynthetic) return + val frame = locatableEvent.thread().frame(0) + val visibleVars = try { + frame.visibleVariables().map { variable -> toRecord(frame, variable) } } catch (e: AbsentInformationException) { // LVT Completely absent - not distinguished from an empty table - loggedItems.add("${event.location()}:".trim()) + listOf() } + loggedItems.add(LVTStep(location, visibleVars)) } override fun checkResult(wholeFile: File, loggedItems: List) { @@ -109,11 +114,14 @@ abstract class AbstractLocalVariableTest : AbstractDebugTest() { continue } if (currentBackend == TargetBackend.ANY || currentBackend == backend) { - expectedLocalVariables.add(line.drop(3)) + expectedLocalVariables.add(line) } } - val actualLocalVariables = loggedItems.joinToString("\n") + val compressedLog = compressRunsWithoutLinenumber(loggedItems as List, LVTStep::location) + val actualLocalVariables = compressedLog.joinToString("\n") { + "// ${it.location.formatAsExpectation()}: ${it.visibleVars.joinToString(", ")}".trim() + } TestCase.assertEquals(expectedLocalVariables.joinToString("\n"), actualLocalVariables) } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractSteppingTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractSteppingTest.kt index e10e061b6e5..a04fdbfe55c 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractSteppingTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractSteppingTest.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen.debugInformation import com.sun.jdi.VirtualMachine import com.sun.jdi.event.Event import com.sun.jdi.event.LocatableEvent -import junit.framework.TestCase import org.jetbrains.kotlin.test.KotlinTestUtils.assertEqualsToFile import org.jetbrains.kotlin.test.TargetBackend import org.junit.AfterClass @@ -57,18 +56,14 @@ abstract class AbstractSteppingTest : AbstractDebugTest() { val lines = wholeFile.readLines() val forceStepInto = lines.any { it.startsWith(FORCE_STEP_INTO_MARKER) } - val actualLineNumbers = loggedItems + val actualLineNumbers = compressRunsWithoutLinenumber(loggedItems as List, LocatableEvent::location) .filter { - val location = (it as LocatableEvent).location() + val location = it.location() // Ignore synthetic code with no line number information // unless force step into behavior is requested. forceStepInto || !location.method().isSynthetic } - .map { event -> - val location = (event as LocatableEvent).location() - val synthetic = if (location.method().isSynthetic) " (synthetic)" else "" - "// ${location.sourceName()}:${location.lineNumber()} ${location.method().name()}$synthetic" - } + .map { "// ${it.location().formatAsExpectation()}" } val actualLineNumbersIterator = actualLineNumbers.iterator() val lineIterator = lines.iterator() diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java index 1794309a257..e18962bb9ca 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java @@ -103,5 +103,11 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest { public void testSimple() throws Exception { runTest("compiler/testData/debug/localVariables/suspend/simple.kt"); } + + @Test + @TestMetadata("underscoreNames.kt") + public void testUnderscoreNames() throws Exception { + runTest("compiler/testData/debug/localVariables/suspend/underscoreNames.kt"); + } } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java index f840e35da79..0b4d60c9060 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java @@ -103,5 +103,11 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest { public void testSimple() throws Exception { runTest("compiler/testData/debug/localVariables/suspend/simple.kt"); } + + @Test + @TestMetadata("underscoreNames.kt") + public void testUnderscoreNames() throws Exception { + runTest("compiler/testData/debug/localVariables/suspend/underscoreNames.kt"); + } } }