Fix receiver evaluation for primitive receiver types

This commit is contained in:
Yan Zhulanow
2018-12-17 23:05:02 +09:00
parent f6cc686095
commit 7de5ddaac9
4 changed files with 54 additions and 7 deletions
@@ -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()) }
@@ -0,0 +1,31 @@
package thisLabels
fun main() {
block(1) a@ {
//Breakpoint!
inlineBlock(2) b@ {
//Breakpoint!
block(3) c@ {
//Breakpoint!
val a = 5
}
}
}
}
fun <T> block(t: T, block: T.() -> Unit) {
t.block()
}
fun <T> 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
@@ -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
@@ -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");