Evaluate Expression: fix for anonymous objects - expressions where anonymous type can be replaced with super type can be evaluated
This commit is contained in:
@@ -76,6 +76,7 @@ import org.jetbrains.jet.lang.psi.JetElement
|
||||
import org.jetbrains.jet.plugin.util.attachment.attachmentByPsiFile
|
||||
import com.intellij.openapi.diagnostic.Attachment
|
||||
import org.jetbrains.jet.plugin.util.attachment.mergeAttachments
|
||||
import com.sun.jdi.ClassType
|
||||
|
||||
private val RECEIVER_NAME = "\$receiver"
|
||||
private val THIS_NAME = "this"
|
||||
@@ -346,6 +347,22 @@ private fun SuspendContext.getInvokePolicy(): Int {
|
||||
return if (getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD) ObjectReference.INVOKE_SINGLE_THREADED else 0
|
||||
}
|
||||
|
||||
private fun com.sun.jdi.Type?.isSubclass(superClassName: String): Boolean {
|
||||
if (this !is ClassType) return false
|
||||
if (allInterfaces().any { it.name() == superClassName }) {
|
||||
return true
|
||||
}
|
||||
|
||||
var superClass = this.superclass()
|
||||
while (superClass != null) {
|
||||
if (superClass.name() == superClassName) {
|
||||
return true
|
||||
}
|
||||
superClass = superClass.superclass()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun EvaluationContextImpl.findLocalVariable(name: String, asmType: Type?, checkType: Boolean, failIfNotFound: Boolean): Value? {
|
||||
val project = getDebugProcess().getProject()
|
||||
val frame = getFrameProxy()?.getStackFrame()
|
||||
@@ -355,6 +372,10 @@ fun EvaluationContextImpl.findLocalVariable(name: String, asmType: Type?, checkT
|
||||
if (!shouldCheckType || asmType == null || value.asmType == asmType) return true
|
||||
if (project == null) return false
|
||||
|
||||
if ((value.obj() as? com.sun.jdi.ObjectReference)?.referenceType().isSubclass(asmType.getClassName())) {
|
||||
return true
|
||||
}
|
||||
|
||||
val thisDesc = value.asmType.getClassDescriptor(project)
|
||||
val expDesc = asmType.getClassDescriptor(project)
|
||||
return thisDesc != null && expDesc != null && runReadAction { DescriptorUtils.isSubclass(thisDesc, expDesc) }
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
LineBreakpoint created at anonymousObjects.kt:11
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! anonymousObjects.AnonymousObjectsPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
anonymousObjects.kt:11
|
||||
Compile bytecode for test(2)
|
||||
Compile bytecode for i
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -0,0 +1,19 @@
|
||||
package anonymousObjects
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a = object: AbstractClass(1) {}
|
||||
a.test(1)
|
||||
}
|
||||
|
||||
abstract class AbstractClass(val i: Int) {
|
||||
fun test(i: Int): Int {
|
||||
//Breakpoint!
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
// EXPRESSION: test(2)
|
||||
// RESULT: 2: I
|
||||
|
||||
// EXPRESSION: i
|
||||
// RESULT: 1: I
|
||||
+6
@@ -46,6 +46,12 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousObjects.kt")
|
||||
public void testAnonymousObjects() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/anonymousObjects.kt");
|
||||
doSingleBreakpointTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("arrays.kt")
|
||||
public void testArrays() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/arrays.kt");
|
||||
|
||||
Reference in New Issue
Block a user