diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt index d84bf39581a..dfc0a04de94 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt @@ -56,9 +56,11 @@ class FrameVisitor(context: EvaluationContextImpl) { else -> { if (isInsideInlineFunctionBody(frame.visibleVariables())) { val number = numberOfInlinedFunctions(frame.visibleVariables()) - val inlineFunVar = findLocalVariableForInlineArgument(name, number, asmType, true) - if (inlineFunVar != null) { - return inlineFunVar + for (inlineFunctionIndex in number downTo 1) { + val inlineFunVar = findLocalVariableForInlineArgument(name, inlineFunctionIndex, asmType, true) + if (inlineFunVar != null) { + return inlineFunVar + } } } diff --git a/idea/testData/debugger/tinyApp/outs/frameInlineArgumentInsideInlineFun.out b/idea/testData/debugger/tinyApp/outs/frameInlineArgumentInsideInlineFun.out new file mode 100644 index 00000000000..c87f8fa8cb8 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameInlineArgumentInsideInlineFun.out @@ -0,0 +1,57 @@ +LineBreakpoint created at frameInlineArgumentInsideInlineFun.kt:16 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! frameInlineArgumentInsideInlineFun.FrameInlineArgumentInsideInlineFunKt +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameInlineArgumentInsideInlineFun.kt:16 +Compile bytecode for element +// KT-10674: Debugger: Evaluate Expression / Watches fail for variable/parameter captured from one inline function to another +package frameInlineArgumentInsideInlineFun + +class A { + inline fun inlineFun(s: (Int) -> Unit) { + val element = 1.0 + s(1) + } +} + +class B { + inline fun foo(s: (Int) -> Unit) { + val element = 1 + A().inlineFun { + //Breakpoint! + val e = element + } + s(1) + } +} + +class C { + fun bar() { + val element = 1f + B().foo { + val e = element + } + } +} + +fun main(args: Array) { + C().bar() +} + +// PRINT_FRAME + +// EXPRESSION: element +// RESULT: 1: I + frame = bar():16, C {frameInlineArgumentInsideInlineFun} + this = this = {frameInlineArgumentInsideInlineFun.C@uniqueID} + - Class has no fields + local = element: float = 1.0 (sp = frameInlineArgumentInsideInlineFun.kt, 13) + local = this_$iv: frameInlineArgumentInsideInlineFun.B = {frameInlineArgumentInsideInlineFun.B@uniqueID} (sp = null) + - Class has no fields + local = element$iv: int = 1 (sp = frameInlineArgumentInsideInlineFun.kt, 13) + local = this_$iv$iv: frameInlineArgumentInsideInlineFun.A = {frameInlineArgumentInsideInlineFun.A@uniqueID} (sp = null) + - Class has no fields + local = element$iv$iv: double = 1.0 (sp = frameInlineArgumentInsideInlineFun.kt, 13) + local = it$iv: int = 1 (sp = null) +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt new file mode 100644 index 00000000000..6564a8b82c7 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt @@ -0,0 +1,38 @@ +// KT-10674: Debugger: Evaluate Expression / Watches fail for variable/parameter captured from one inline function to another +package frameInlineArgumentInsideInlineFun + +class A { + inline fun inlineFun(s: (Int) -> Unit) { + val element = 1.0 + s(1) + } +} + +class B { + inline fun foo(s: (Int) -> Unit) { + val element = 1 + A().inlineFun { + //Breakpoint! + val e = element + } + s(1) + } +} + +class C { + fun bar() { + val element = 1f + B().foo { + val e = element + } + } +} + +fun main(args: Array) { + C().bar() +} + +// PRINT_FRAME + +// EXPRESSION: element +// RESULT: 1: I \ No newline at end of file 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 bfe6e3979b5..ccb3c44a7b0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java @@ -513,6 +513,12 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat doSingleBreakpointTest(fileName); } + @TestMetadata("frameInlineArgumentInsideInlineFun.kt") + public void testFrameInlineArgumentInsideInlineFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt"); + doSingleBreakpointTest(fileName); + } + @TestMetadata("frameInlineFun.kt") public void testFrameInlineFun() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/frameInlineFun.kt");