From 7de5ddaac9fc1fb79e7c60c9f57a671fc09d3a34 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Mon, 17 Dec 2018 23:05:02 +0900 Subject: [PATCH] Fix receiver evaluation for primitive receiver types --- .../idea/debugger/evaluate/VariableFinder.kt | 11 +++---- .../multipleBreakpoints/thisLabels.kt | 31 +++++++++++++++++++ .../multipleBreakpoints/thisLabels.out | 14 +++++++++ ...KotlinEvaluateExpressionTestGenerated.java | 5 +++ 4 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.kt create mode 100644 idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.out diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/VariableFinder.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/VariableFinder.kt index 18b1f4efee5..1e507c64f07 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/VariableFinder.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/VariableFinder.kt @@ -327,19 +327,17 @@ class VariableFinder private constructor(private val context: EvaluationContextI } return variables.namedEntitySequence() - .filter { isReceiverOrPassedThis(it.name) && it.type is ReferenceType? } + .filter { isReceiverOrPassedThis(it.name) } .mapNotNull { findCapturedVariable(kind, it.value()) } .firstOrNull() } private fun findCapturedVariable(kind: VariableKind, parent: Value?): Result? { - if (parent !is ObjectReference) return null - - if (kind is VariableKind.UnlabeledThis && kind.typeMatches(parent.type())) { + if (parent != null && kind is VariableKind.UnlabeledThis && kind.typeMatches(parent.type())) { return Result(parent) } - val fields = parent.referenceType().fields() + val fields = (parent as? ObjectReference)?.referenceType()?.fields() ?: return null // Captured variables - direct search fields.namedEntitySequence(parent) @@ -349,7 +347,7 @@ class VariableFinder private constructor(private val context: EvaluationContextI // Recursive search in captured receivers fields.namedEntitySequence(parent) - .filter { isCapturedReceiverFieldName(it.name) && it.type is ReferenceType? } + .filter { isCapturedReceiverFieldName(it.name) } .mapNotNull { findCapturedVariable(kind, it.value()) } .firstOrNull() ?.let { return it } @@ -357,7 +355,6 @@ class VariableFinder private constructor(private val context: EvaluationContextI // Recursive search in outer and captured this fields.namedEntitySequence(parent) .filter { it.name == AsmUtil.getCapturedFieldName(AsmUtil.THIS) || it.name == AsmUtil.CAPTURED_THIS_FIELD } - .filter { it.type is ReferenceType? } .firstOrNull() ?.let { return findCapturedVariable(kind, it.value()) } diff --git a/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.kt b/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.kt new file mode 100644 index 00000000000..16a05e39f94 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.kt @@ -0,0 +1,31 @@ +package thisLabels + +fun main() { + block(1) a@ { + //Breakpoint! + inlineBlock(2) b@ { + //Breakpoint! + block(3) c@ { + //Breakpoint! + val a = 5 + } + } + } +} + +fun block(t: T, block: T.() -> Unit) { + t.block() +} + +fun T.inlineBlock(t: T, block: T.() -> Unit) { + t.block() +} + +// EXPRESSION: this +// RESULT: 1: I + +// EXPRESSION: this +// RESULT: 2: I + +// EXPRESSION: this@c +// RESULT: 3: I \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.out b/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.out new file mode 100644 index 00000000000..ca185b30c13 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.out @@ -0,0 +1,14 @@ +LineBreakpoint created at thisLabels.kt:6 +LineBreakpoint created at thisLabels.kt:8 +LineBreakpoint created at thisLabels.kt:10 +Run Java +Connected to the target VM +thisLabels.kt:6 +Compile bytecode for this +thisLabels.kt:8 +Compile bytecode for this +thisLabels.kt:10 +Compile bytecode for this + this@a + this@b + this@c +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 f43fd2b541d..fe1aff4fb07 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java @@ -1011,6 +1011,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat runTest("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/smartcasts.kt"); } + @TestMetadata("thisLabels.kt") + public void testThisLabels() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/thisLabels.kt"); + } + @TestMetadata("whenEntry.kt") public void testWhenEntry() throws Exception { runTest("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/whenEntry.kt");