diff --git a/idea/jvm-debugger/jvm-debugger-util/src/org/jetbrains/kotlin/idea/debugger/InlineUtils.kt b/idea/jvm-debugger/jvm-debugger-util/src/org/jetbrains/kotlin/idea/debugger/InlineUtils.kt index 02de0482a3d..229339d875c 100644 --- a/idea/jvm-debugger/jvm-debugger-util/src/org/jetbrains/kotlin/idea/debugger/InlineUtils.kt +++ b/idea/jvm-debugger/jvm-debugger-util/src/org/jetbrains/kotlin/idea/debugger/InlineUtils.kt @@ -14,18 +14,20 @@ import org.jetbrains.kotlin.load.java.JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_F val INLINED_THIS_REGEX = getLocalVariableNameRegexInlineAware(AsmUtil.INLINE_DECLARATION_SITE_THIS) fun getInlineDepth(variables: List): Int { - val inlineFunVariables = variables - .filter { it.name().startsWith(LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) } + val rawInlineFunDepth = variables.count { it.name().startsWith(LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) } - if (inlineFunVariables.isEmpty()) { - return 0 + for (variable in variables.sortedByDescending { it.variable }) { + val name = variable.name() + val depth = getInlineDepth(name) + if (depth > 0) { + return depth + } else if (name.startsWith(LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT)) { + // TODO this heuristics doesn't support debugging inlined lambdas inside inline functions. + return 0 + } } - val closestInlineFun = inlineFunVariables.maxBy { it.variable }!!.variable - val inlineLambdaDepth = variables - .count { it.name().startsWith(LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT) && it.variable > closestInlineFun } - - return maxOf(0, inlineFunVariables.size - inlineLambdaDepth) + return rawInlineFunDepth } fun getInlineDepth(variableName: String): Int { diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/nestedInlineFun.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/nestedInlineFun.kt new file mode 100644 index 00000000000..65dd00ca68b --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/nestedInlineFun.kt @@ -0,0 +1,25 @@ +package nestedInlineFun + +fun main() { + val a = 1 + foo { + val b = 2 + //Breakpoint! + val c = 0 + } +} + +inline fun foo(block: () -> Unit) { + val x = 3 + bar(1, block) +} + +inline fun bar(count: Int, block: () -> Unit) { + var i = count + while (i-- > 0) { + block() + } +} + +// SHOW_KOTLIN_VARIABLES +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/nestedInlineFun.out b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/nestedInlineFun.out new file mode 100644 index 00000000000..c535b62e036 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/nestedInlineFun.out @@ -0,0 +1,10 @@ +LineBreakpoint created at nestedInlineFun.kt:8 +Run Java +Connected to the target VM +nestedInlineFun.kt:8 + frame = main:8, NestedInlineFunKt {nestedInlineFun} + local = a: int = 1 (sp = nestedInlineFun.kt, 4) + local = b: int = 2 (sp = nestedInlineFun.kt, 6) +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java index 80f19a6dac3..5b147240530 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java @@ -900,6 +900,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/localFunctionMangling.kt"); } + @TestMetadata("nestedInlineFun.kt") + public void testNestedInlineFun() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/nestedInlineFun.kt"); + } + @TestMetadata("remapThis.kt") public void testRemapThis() throws Exception { runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/remapThis.kt");