diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt index 7bc71095a31..cd3286dca5b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt @@ -69,7 +69,7 @@ internal const val THIS = "this" internal const val THIS_0 = "this$0" internal const val FIRST_FUN_LABEL = "$$$$\$ROOT$$$$$" internal const val SPECIAL_TRANSFORMATION_NAME = "\$special" -internal const val INLINE_TRANSFORMATION_SUFFIX = "\$inlined" +const val INLINE_TRANSFORMATION_SUFFIX = "\$inlined" internal const val INLINE_CALL_TRANSFORMATION_SUFFIX = "$" + INLINE_TRANSFORMATION_SUFFIX internal const val INLINE_FUN_THIS_0_SUFFIX = "\$inline_fun" internal const val DEFAULT_LAMBDA_FAKE_CALL = "$$\$DEFAULT_LAMBDA_FAKE_CALL$$$" 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 cefc45ca1ad..8da76bf1b41 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.debugger.evaluate import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil import com.intellij.debugger.engine.evaluation.EvaluationContextImpl +import com.intellij.debugger.jdi.StackFrameProxyImpl import com.sun.jdi.ClassType import com.sun.jdi.InvalidStackFrameException import com.sun.jdi.ObjectReference @@ -27,6 +28,7 @@ import org.jetbrains.eval4j.jdi.asValue import org.jetbrains.eval4j.obj import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX +import org.jetbrains.kotlin.codegen.inline.INLINE_TRANSFORMATION_SUFFIX import org.jetbrains.kotlin.codegen.inline.NUMBERED_FUNCTION_PREFIX import org.jetbrains.kotlin.idea.debugger.isInsideInlineFunctionBody import org.jetbrains.kotlin.idea.debugger.numberOfInlinedFunctions @@ -78,11 +80,10 @@ class FrameVisitor(context: EvaluationContextImpl) { return localVariable } - val capturedValName = getCapturedFieldName(name) - val capturedVal = findCapturedLocalVariable(capturedValName, asmType, checkType) - if (capturedVal != null) { - return capturedVal - } + getCapturedFieldNames(name).asSequence() + .mapNotNull { findCapturedLocalVariable(it, asmType, checkType) } + .firstOrNull() + ?.let { return it } } } @@ -221,12 +222,15 @@ class FrameVisitor(context: EvaluationContextImpl) { return null } - private fun getCapturedFieldName(name: String) = when (name) { - RECEIVER_NAME -> AsmUtil.CAPTURED_RECEIVER_FIELD - THIS_NAME -> AsmUtil.CAPTURED_THIS_FIELD - AsmUtil.CAPTURED_RECEIVER_FIELD -> name - AsmUtil.CAPTURED_THIS_FIELD -> name - else -> "$$name" + private fun getCapturedFieldNames(name: String): List = when (name) { + RECEIVER_NAME -> listOf(AsmUtil.CAPTURED_RECEIVER_FIELD) + THIS_NAME -> listOf(AsmUtil.CAPTURED_THIS_FIELD) + AsmUtil.CAPTURED_RECEIVER_FIELD -> listOf(name) + AsmUtil.CAPTURED_THIS_FIELD -> listOf(name) + else -> { + val simpleName = "$$name" + listOf(simpleName, simpleName + INLINE_TRANSFORMATION_SUFFIX) + } } private fun com.sun.jdi.Type?.isSubclass(superClassName: String): Boolean { diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt17514.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt17514.kt new file mode 100644 index 00000000000..049ed636dfd --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt17514.kt @@ -0,0 +1,23 @@ +package kt17514 + +fun checkSucceeds(callable: () -> T) = callable() + +fun main(args: Array) { + val isPresent = true + val isPresent2 = true + val expectedLibs = listOf("aa", "bb", "cc") + expectedLibs + .forEach { + checkSucceeds { + val isPresent2 = false + //Breakpoint! + val v = isPresent + } + } +} + +// EXPRESSION: isPresent +// RESULT: 1: Z + +// EXPRESSION: isPresent2 +// RESULT: 0: Z \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt17514.out b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt17514.out new file mode 100644 index 00000000000..5051873761f --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt17514.out @@ -0,0 +1,11 @@ +LineBreakpoint created at kt17514.kt:14 +Run Java +Connected to the target VM +kt17514.kt:14 +Compile bytecode for isPresent +Compile bytecode for isPresent2 +kt17514.kt:14 +resuming kt17514.kt:14 +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 7893776afcf..e01f37f15ea 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java @@ -236,6 +236,12 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat doSingleBreakpointTest(fileName); } + @TestMetadata("kt17514.kt") + public void testKt17514() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt17514.kt"); + doSingleBreakpointTest(fileName); + } + @TestMetadata("kt5554OnlyIntsShouldBeCoerced.kt") public void testKt5554OnlyIntsShouldBeCoerced() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt5554OnlyIntsShouldBeCoerced.kt");