JVM IR: fix "step over" for inline function calls in conditions
Reimplement the same hacky approach used in the old backend (see
cc2fe6b0c6).
Previously, the debugger incorrectly stepped into Collections.kt on
"step over" inline function calls from stdlib like 'any'.
Since `if` and `when` expressions are represented the same way in IR,
the behavior is fixed for both of them. It's not the case in the old JVM
backend, where stepping over `when` conditions still suffers from the
same problem, which the newly added test checks.
This commit is contained in:
+17
-4
@@ -131,6 +131,8 @@ class ExpressionCodegen(
|
|||||||
override var lastLineNumber: Int = -1
|
override var lastLineNumber: Int = -1
|
||||||
var noLineNumberScope: Boolean = false
|
var noLineNumberScope: Boolean = false
|
||||||
|
|
||||||
|
private var isInsideCondition = false
|
||||||
|
|
||||||
private val closureReifiedMarkers = hashMapOf<IrClass, ReifiedTypeParametersUsages>()
|
private val closureReifiedMarkers = hashMapOf<IrClass, ReifiedTypeParametersUsages>()
|
||||||
|
|
||||||
private val IrType.asmType: Type
|
private val IrType.asmType: Type
|
||||||
@@ -429,7 +431,7 @@ class ExpressionCodegen(
|
|||||||
val generatorForActualCall =
|
val generatorForActualCall =
|
||||||
// Do not inline callee to continuation, instead, call it
|
// Do not inline callee to continuation, instead, call it
|
||||||
if (irFunction.isInvokeSuspendOfContinuation()) IrCallGenerator.DefaultCallGenerator else callGenerator
|
if (irFunction.isInvokeSuspendOfContinuation()) IrCallGenerator.DefaultCallGenerator else callGenerator
|
||||||
generatorForActualCall.genCall(callable, this, expression)
|
generatorForActualCall.genCall(callable, this, expression, isInsideCondition)
|
||||||
|
|
||||||
if (isSuspensionPoint != SuspensionPointKind.NEVER) {
|
if (isSuspensionPoint != SuspensionPointKind.NEVER) {
|
||||||
addSuspendMarker(mv, isStartNotEnd = false, isSuspensionPoint == SuspensionPointKind.NOT_INLINE)
|
addSuspendMarker(mv, isStartNotEnd = false, isSuspensionPoint == SuspensionPointKind.NOT_INLINE)
|
||||||
@@ -829,7 +831,10 @@ class ExpressionCodegen(
|
|||||||
if (branch.condition.isFalseConst())
|
if (branch.condition.isFalseConst())
|
||||||
continue // The branch body is dead code.
|
continue // The branch body is dead code.
|
||||||
} else {
|
} else {
|
||||||
|
val oldIsInsideCondition = isInsideCondition
|
||||||
|
isInsideCondition = true
|
||||||
branch.condition.accept(this, data).coerceToBoolean().jumpIfFalse(elseLabel)
|
branch.condition.accept(this, data).coerceToBoolean().jumpIfFalse(elseLabel)
|
||||||
|
isInsideCondition = oldIsInsideCondition
|
||||||
}
|
}
|
||||||
val result = branch.result.accept(this, data)
|
val result = branch.result.accept(this, data)
|
||||||
if (!exhaustive) {
|
if (!exhaustive) {
|
||||||
@@ -1250,9 +1255,17 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards: Boolean) {
|
override fun markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards: Boolean) {
|
||||||
// Inline function has its own line number which is in a separate instance of codegen,
|
if (noLineNumberScope || registerLineNumberAfterwards) {
|
||||||
// therefore we need to reset lastLineNumber to force a line number generation after visiting inline function.
|
if (lastLineNumber > -1) {
|
||||||
lastLineNumber = -1
|
val label = Label()
|
||||||
|
v.visitLabel(label)
|
||||||
|
v.visitLineNumber(lastLineNumber, label)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Inline function has its own line number which is in a separate instance of codegen,
|
||||||
|
// therefore we need to reset lastLineNumber to force a line number generation after visiting inline function.
|
||||||
|
lastLineNumber = -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isFinallyMarkerRequired(): Boolean {
|
fun isFinallyMarkerRequired(): Boolean {
|
||||||
|
|||||||
+6
-1
@@ -22,7 +22,12 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
interface IrCallGenerator {
|
interface IrCallGenerator {
|
||||||
fun genCall(callableMethod: IrCallableMethod, codegen: ExpressionCodegen, expression: IrFunctionAccessExpression) {
|
fun genCall(
|
||||||
|
callableMethod: IrCallableMethod,
|
||||||
|
codegen: ExpressionCodegen,
|
||||||
|
expression: IrFunctionAccessExpression,
|
||||||
|
isInsideIfCondition: Boolean,
|
||||||
|
) {
|
||||||
with(callableMethod) {
|
with(callableMethod) {
|
||||||
codegen.mv.visitMethodInsn(invokeOpcode, owner.internalName, asmMethod.name, asmMethod.descriptor, isInterfaceMethod)
|
codegen.mv.visitMethodInsn(invokeOpcode, owner.internalName, asmMethod.name, asmMethod.descriptor, isInterfaceMethod)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
package org.jetbrains.kotlin.backend.jvm.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.*
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
|
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
|
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
|
||||||
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.inline.*
|
import org.jetbrains.kotlin.codegen.inline.*
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -17,7 +17,9 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
|
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
|
||||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
@@ -143,7 +145,8 @@ class IrInlineCodegen(
|
|||||||
override fun genCall(
|
override fun genCall(
|
||||||
callableMethod: IrCallableMethod,
|
callableMethod: IrCallableMethod,
|
||||||
codegen: ExpressionCodegen,
|
codegen: ExpressionCodegen,
|
||||||
expression: IrFunctionAccessExpression
|
expression: IrFunctionAccessExpression,
|
||||||
|
isInsideIfCondition: Boolean,
|
||||||
) {
|
) {
|
||||||
val element = codegen.context.psiSourceManager.findPsiElement(expression, codegen.irFunction)
|
val element = codegen.context.psiSourceManager.findPsiElement(expression, codegen.irFunction)
|
||||||
?: codegen.context.psiSourceManager.findPsiElement(codegen.irFunction)
|
?: codegen.context.psiSourceManager.findPsiElement(codegen.irFunction)
|
||||||
@@ -161,7 +164,7 @@ class IrInlineCodegen(
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
codegen.typeMapper.typeSystem,
|
codegen.typeMapper.typeSystem,
|
||||||
registerLineNumberAfterwards = false,
|
registerLineNumberAfterwards = isInsideIfCondition,
|
||||||
isCallOfFunctionInCorrespondingDefaultDispatch = codegen.irFunction == codegen.context.mapping.defaultArgumentsDispatchFunction[function]
|
isCallOfFunctionInCorrespondingDefaultDispatch = codegen.irFunction == codegen.context.mapping.defaultArgumentsDispatchFunction[function]
|
||||||
)
|
)
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//FILE: test.kt
|
//FILE: test.kt
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
|
|
||||||
fun box() {
|
fun box() {
|
||||||
if (listOf(1, 2, 3).myAny { it > 2 }) {
|
if (listOf(1, 2, 3).myAny { it > 2 }) {
|
||||||
@@ -14,4 +14,4 @@ public inline fun <T> Iterable<T>.myAny(predicate: (T) -> Boolean): Boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3 LINENUMBER 5
|
// 3 LINENUMBER 5
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
// FILE: test.kt
|
||||||
|
fun box() {
|
||||||
|
if (inlineFun()) {
|
||||||
|
nop()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
inlineFun().rid() &&
|
||||||
|
inlineFun()
|
||||||
|
) {
|
||||||
|
nop()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
id(
|
||||||
|
inlineFun()
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
nop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun inlineFun(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun id(x: Boolean): Boolean = x
|
||||||
|
inline fun Boolean.rid(): Boolean = this
|
||||||
|
|
||||||
|
fun nop() {}
|
||||||
|
|
||||||
|
// LINENUMBERS
|
||||||
|
// test.kt:3 box
|
||||||
|
// test.kt:24 box
|
||||||
|
// test.kt:3 box
|
||||||
|
// test.kt:4 box
|
||||||
|
// test.kt:30 nop
|
||||||
|
// test.kt:8 box
|
||||||
|
// test.kt:24 box
|
||||||
|
// test.kt:8 box
|
||||||
|
// test.kt:28 box
|
||||||
|
// test.kt:8 box
|
||||||
|
// test.kt:9 box
|
||||||
|
// test.kt:24 box
|
||||||
|
// test.kt:9 box
|
||||||
|
// test.kt:11 box
|
||||||
|
// test.kt:30 nop
|
||||||
|
// test.kt:16 box
|
||||||
|
// test.kt:24 box
|
||||||
|
// test.kt:16 box
|
||||||
|
// test.kt:15 box
|
||||||
|
// test.kt:27 box
|
||||||
|
// test.kt:15 box
|
||||||
|
// test.kt:19 box
|
||||||
|
// test.kt:30 nop
|
||||||
|
// test.kt:21 box
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
// FILE: test.kt
|
||||||
|
fun box() {
|
||||||
|
val x = value()
|
||||||
|
when (x) {
|
||||||
|
x0() -> nop()
|
||||||
|
x1() -> nop()
|
||||||
|
x2() -> nop()
|
||||||
|
x3() -> nop()
|
||||||
|
else -> nop()
|
||||||
|
}
|
||||||
|
|
||||||
|
when (x0() + x1()) {
|
||||||
|
x0().rid() -> nop()
|
||||||
|
id(x1()) -> nop()
|
||||||
|
else -> nop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun value(): Int = 2
|
||||||
|
inline fun x0(): Int = 0
|
||||||
|
inline fun x1(): Int = 1
|
||||||
|
inline fun x2(): Int = 2
|
||||||
|
inline fun x3(): Int = 3
|
||||||
|
|
||||||
|
inline fun id(x: Int): Int = x
|
||||||
|
inline fun Int.rid(): Int = this
|
||||||
|
|
||||||
|
fun nop() {}
|
||||||
|
|
||||||
|
// JVM_IR generates an additional line number for the end of the condition, which is necessary for the correct "step over" behavior.
|
||||||
|
|
||||||
|
// LINENUMBERS
|
||||||
|
// test.kt:3 box
|
||||||
|
// test.kt:19 value
|
||||||
|
// test.kt:3 box
|
||||||
|
// test.kt:4 box
|
||||||
|
// test.kt:5 box
|
||||||
|
// test.kt:20 box
|
||||||
|
// LINENUMBERS JVM_IR
|
||||||
|
// test.kt:5 box
|
||||||
|
// LINENUMBERS
|
||||||
|
// test.kt:6 box
|
||||||
|
// test.kt:21 box
|
||||||
|
// LINENUMBERS JVM_IR
|
||||||
|
// test.kt:6 box
|
||||||
|
// LINENUMBERS
|
||||||
|
// test.kt:7 box
|
||||||
|
// test.kt:22 box
|
||||||
|
// test.kt:7 box
|
||||||
|
// test.kt:28 nop
|
||||||
|
// test.kt:7 box
|
||||||
|
// test.kt:12 box
|
||||||
|
// test.kt:20 box
|
||||||
|
// test.kt:12 box
|
||||||
|
// test.kt:21 box
|
||||||
|
// test.kt:12 box
|
||||||
|
// test.kt:13 box
|
||||||
|
// test.kt:20 box
|
||||||
|
// test.kt:13 box
|
||||||
|
// test.kt:26 box
|
||||||
|
// LINENUMBERS JVM_IR
|
||||||
|
// test.kt:13 box
|
||||||
|
// LINENUMBERS
|
||||||
|
// test.kt:14 box
|
||||||
|
// test.kt:21 box
|
||||||
|
// test.kt:14 box
|
||||||
|
// test.kt:25 box
|
||||||
|
// test.kt:14 box
|
||||||
|
// test.kt:28 nop
|
||||||
|
// test.kt:14 box
|
||||||
|
// test.kt:17 box
|
||||||
+12
@@ -187,6 +187,12 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest {
|
|||||||
runTest("compiler/testData/debug/stepping/IfTrueThenFalse.kt");
|
runTest("compiler/testData/debug/stepping/IfTrueThenFalse.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ifWithInlineInCondition.kt")
|
||||||
|
public void testIfWithInlineInCondition() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/stepping/ifWithInlineInCondition.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("iincStepping.kt")
|
@TestMetadata("iincStepping.kt")
|
||||||
public void testIincStepping() throws Exception {
|
public void testIincStepping() throws Exception {
|
||||||
@@ -475,6 +481,12 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest {
|
|||||||
runTest("compiler/testData/debug/stepping/whenSubject2.kt");
|
runTest("compiler/testData/debug/stepping/whenSubject2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("whenWithInlineInCondition.kt")
|
||||||
|
public void testWhenWithInlineInCondition() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/stepping/whenWithInlineInCondition.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("while.kt")
|
@TestMetadata("while.kt")
|
||||||
public void testWhile() throws Exception {
|
public void testWhile() throws Exception {
|
||||||
|
|||||||
+12
@@ -187,6 +187,12 @@ public class SteppingTestGenerated extends AbstractSteppingTest {
|
|||||||
runTest("compiler/testData/debug/stepping/IfTrueThenFalse.kt");
|
runTest("compiler/testData/debug/stepping/IfTrueThenFalse.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ifWithInlineInCondition.kt")
|
||||||
|
public void testIfWithInlineInCondition() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/stepping/ifWithInlineInCondition.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("iincStepping.kt")
|
@TestMetadata("iincStepping.kt")
|
||||||
public void testIincStepping() throws Exception {
|
public void testIincStepping() throws Exception {
|
||||||
@@ -475,6 +481,12 @@ public class SteppingTestGenerated extends AbstractSteppingTest {
|
|||||||
runTest("compiler/testData/debug/stepping/whenSubject2.kt");
|
runTest("compiler/testData/debug/stepping/whenSubject2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("whenWithInlineInCondition.kt")
|
||||||
|
public void testWhenWithInlineInCondition() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/stepping/whenWithInlineInCondition.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("while.kt")
|
@TestMetadata("while.kt")
|
||||||
public void testWhile() throws Exception {
|
public void testWhile() throws Exception {
|
||||||
|
|||||||
+5
@@ -607,6 +607,11 @@ public class IrKotlinSteppingTestGenerated extends AbstractIrKotlinSteppingTest
|
|||||||
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineLibFun.kt");
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineLibFun.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("soInlineLibFunInWhen.kt")
|
||||||
|
public void testSoInlineLibFunInWhen() throws Exception {
|
||||||
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineLibFunInWhen.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("soInlineOperatorIterator.kt")
|
@TestMetadata("soInlineOperatorIterator.kt")
|
||||||
public void testSoInlineOperatorIterator() throws Exception {
|
public void testSoInlineOperatorIterator() throws Exception {
|
||||||
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineOperatorIterator.kt");
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineOperatorIterator.kt");
|
||||||
|
|||||||
+5
@@ -607,6 +607,11 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineLibFun.kt");
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineLibFun.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("soInlineLibFunInWhen.kt")
|
||||||
|
public void testSoInlineLibFunInWhen() throws Exception {
|
||||||
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineLibFunInWhen.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("soInlineOperatorIterator.kt")
|
@TestMetadata("soInlineOperatorIterator.kt")
|
||||||
public void testSoInlineOperatorIterator() throws Exception {
|
public void testSoInlineOperatorIterator() throws Exception {
|
||||||
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineOperatorIterator.kt");
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/soInlineOperatorIterator.kt");
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
LineBreakpoint created at soInlineLibFun.kt:6
|
LineBreakpoint created at soInlineLibFun.kt:6
|
||||||
Run Java
|
Run Java
|
||||||
Connected to the target VM
|
Connected to the target VM
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
LineBreakpoint created at soInlineLibFunInWhen.kt:6
|
||||||
|
Run Java
|
||||||
|
Connected to the target VM
|
||||||
|
soInlineLibFunInWhen.kt:6
|
||||||
|
soInlineLibFunInWhen.kt:8
|
||||||
|
soInlineLibFunInWhen.kt:9
|
||||||
|
soInlineLibFunInWhen.kt:10
|
||||||
|
soInlineLibFunInWhen.kt:12
|
||||||
|
Disconnected from the target VM
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// FILE: soInlineLibFunInWhen.kt
|
||||||
|
package soInlineLibFunInWhen
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
//Breakpoint!
|
||||||
|
val l = listOf(1, 2, 3)
|
||||||
|
|
||||||
|
when {
|
||||||
|
l.any { it > 4 } -> nop()
|
||||||
|
l.any { it > 2 } -> nop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nop() {}
|
||||||
|
|
||||||
|
// STEP_OVER: 7
|
||||||
|
// Note: on the old JVM backend, debugger incorrectly steps into Collections.kt even though we're stepping over it. This is fixed in JVM_IR.
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
LineBreakpoint created at soInlineLibFunInWhen.kt:6
|
||||||
|
Run Java
|
||||||
|
Connected to the target VM
|
||||||
|
soInlineLibFunInWhen.kt:6
|
||||||
|
soInlineLibFunInWhen.kt:8
|
||||||
|
soInlineLibFunInWhen.kt:9
|
||||||
|
soInlineLibFunInWhen.kt:10
|
||||||
|
_Collections.!EXT!
|
||||||
|
soInlineLibFunInWhen.kt:10
|
||||||
|
soInlineLibFunInWhen.kt:12
|
||||||
|
Disconnected from the target VM
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
Vendored
+2
@@ -16,3 +16,5 @@ inline fun foo(f: () -> Boolean): Boolean = f()
|
|||||||
fun test(i: Int): Boolean = true
|
fun test(i: Int): Boolean = true
|
||||||
|
|
||||||
fun bar() {}
|
fun bar() {}
|
||||||
|
|
||||||
|
// STEP_OVER: 5
|
||||||
|
|||||||
Vendored
+2
@@ -3,6 +3,8 @@ Run Java
|
|||||||
Connected to the target VM
|
Connected to the target VM
|
||||||
soSimpleInlineIfCondition.kt:5
|
soSimpleInlineIfCondition.kt:5
|
||||||
soSimpleInlineIfCondition.kt:8
|
soSimpleInlineIfCondition.kt:8
|
||||||
|
soSimpleInlineIfCondition.kt:11
|
||||||
|
soSimpleInlineIfCondition.kt:12
|
||||||
Disconnected from the target VM
|
Disconnected from the target VM
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
Reference in New Issue
Block a user