Debugger: implement getSourcePosition for fields
This commit is contained in:
+4
-8
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.plugin.debugger.render
|
package org.jetbrains.jet.plugin.debugger.render
|
||||||
|
|
||||||
import com.intellij.debugger.ui.tree.render.ClassRenderer
|
|
||||||
import com.sun.jdi.Type as JdiType
|
import com.sun.jdi.Type as JdiType
|
||||||
import com.sun.jdi.Value
|
import com.sun.jdi.Value
|
||||||
import com.intellij.debugger.ui.tree.render.ChildrenBuilder
|
import com.intellij.debugger.ui.tree.render.ChildrenBuilder
|
||||||
@@ -24,7 +23,6 @@ import com.intellij.debugger.engine.evaluation.EvaluationContext
|
|||||||
import com.intellij.debugger.ui.tree.DebuggerTreeNode
|
import com.intellij.debugger.ui.tree.DebuggerTreeNode
|
||||||
import org.jetbrains.org.objectweb.asm.Type as AsmType
|
import org.jetbrains.org.objectweb.asm.Type as AsmType
|
||||||
import com.intellij.debugger.engine.DebuggerManagerThreadImpl
|
import com.intellij.debugger.engine.DebuggerManagerThreadImpl
|
||||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl
|
|
||||||
import com.sun.jdi.ObjectReference
|
import com.sun.jdi.ObjectReference
|
||||||
import com.intellij.xdebugger.settings.XDebuggerSettingsManager
|
import com.intellij.xdebugger.settings.XDebuggerSettingsManager
|
||||||
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl
|
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl
|
||||||
@@ -32,20 +30,18 @@ import com.intellij.debugger.ui.impl.watch.MessageDescriptor
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi
|
||||||
import com.sun.jdi.Field
|
import com.sun.jdi.Field
|
||||||
import com.intellij.debugger.engine.DebuggerUtils
|
|
||||||
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl
|
|
||||||
import com.intellij.debugger.engine.evaluation.EvaluateException
|
|
||||||
import com.sun.jdi.ReferenceType
|
import com.sun.jdi.ReferenceType
|
||||||
import com.sun.jdi.Type
|
import com.sun.jdi.Type
|
||||||
import com.sun.jdi.InvocationException
|
import com.sun.jdi.InvocationException
|
||||||
import com.sun.jdi.Method
|
import com.sun.jdi.Method
|
||||||
import org.jetbrains.jet.codegen.PropertyCodegen
|
import org.jetbrains.jet.codegen.PropertyCodegen
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name
|
import org.jetbrains.jet.lang.resolve.name.Name
|
||||||
|
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl
|
||||||
|
|
||||||
public class KotlinClassWithDelegatedPropertyRenderer : ClassRenderer() {
|
public class KotlinClassWithDelegatedPropertyRenderer : KotlinObjectRenderer() {
|
||||||
|
|
||||||
override fun isApplicable(jdiType: Type?): Boolean {
|
override fun isApplicable(jdiType: Type?): Boolean {
|
||||||
if (!super<ClassRenderer>.isApplicable(jdiType)) return false
|
if (!super.isApplicable(jdiType)) return false
|
||||||
|
|
||||||
if (jdiType !is ReferenceType) return false
|
if (jdiType !is ReferenceType) return false
|
||||||
|
|
||||||
@@ -72,7 +68,7 @@ public class KotlinClassWithDelegatedPropertyRenderer : ClassRenderer() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val fieldDescriptor = nodeDescriptorFactory.getFieldDescriptor(builder.getParentDescriptor(), value, field)
|
val fieldDescriptor = createFieldDescriptor(builder.getParentDescriptor() as ValueDescriptorImpl, nodeDescriptorFactory, value, field, context)
|
||||||
children.add(nodeManager.createNode(fieldDescriptor, context))
|
children.add(nodeManager.createNode(fieldDescriptor, context))
|
||||||
|
|
||||||
if (field.name().endsWith(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX)) {
|
if (field.name().endsWith(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX)) {
|
||||||
|
|||||||
@@ -32,8 +32,22 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi
|
|||||||
import com.intellij.debugger.ui.tree.ValueDescriptor
|
import com.intellij.debugger.ui.tree.ValueDescriptor
|
||||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener
|
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener
|
||||||
import com.intellij.debugger.settings.NodeRendererSettings
|
import com.intellij.debugger.settings.NodeRendererSettings
|
||||||
|
import com.intellij.psi.PsiClass
|
||||||
|
import com.intellij.psi.JavaPsiFacade
|
||||||
|
import com.intellij.debugger.SourcePosition
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import com.intellij.debugger.impl.DebuggerContextUtil
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.sun.jdi.AbsentInformationException
|
||||||
|
import com.sun.jdi.ClassNotPreparedException
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClass
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName
|
||||||
|
import com.sun.jdi.ReferenceType
|
||||||
|
import org.jetbrains.jet.codegen.AsmUtil
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassOrObject
|
||||||
|
|
||||||
public class KotlinObjectRenderer : ClassRenderer() {
|
public open class KotlinObjectRenderer : ClassRenderer() {
|
||||||
|
|
||||||
override fun isApplicable(jdiType: Type?): Boolean {
|
override fun isApplicable(jdiType: Type?): Boolean {
|
||||||
if (!super.isApplicable(jdiType)) return false
|
if (!super.isApplicable(jdiType)) return false
|
||||||
@@ -65,18 +79,75 @@ public class KotlinObjectRenderer : ClassRenderer() {
|
|||||||
}
|
}
|
||||||
return super.calcLabel(descriptor, evaluationContext, labelListener)
|
return super.calcLabel(descriptor, evaluationContext, labelListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Type?.isKotlinClass(): Boolean {
|
|
||||||
return this is ClassType && this.allInterfaces().any { it.name() == JvmAbi.K_OBJECT.asString() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class KotlinObjectFieldDescriptor(
|
public class KotlinObjectFieldDescriptor(
|
||||||
project: Project?,
|
project: Project?,
|
||||||
objRef: ObjectReference?,
|
objRef: ObjectReference?,
|
||||||
field: Field?
|
field: Field?
|
||||||
): FieldDescriptorImpl(project, objRef, field) {
|
) : FieldDescriptorImpl(project, objRef, field) {
|
||||||
override fun getSourcePosition(project: Project?, context: DebuggerContextImpl?) = null
|
override fun getSourcePosition(project: Project?, context: DebuggerContextImpl?, nearest: Boolean): SourcePosition? {
|
||||||
override fun getSourcePosition(project: Project?, context: DebuggerContextImpl?, nearest: Boolean) = null
|
if (context == null || context.getFrameProxy() == null) return null
|
||||||
|
|
||||||
|
val fieldName = getField().name()
|
||||||
|
if (fieldName == AsmUtil.CAPTURED_THIS_FIELD || fieldName == AsmUtil.CAPTURED_RECEIVER_FIELD) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val type = getField().declaringType()
|
||||||
|
val myClass = findClassByType(type, context)?.getNavigationElement()
|
||||||
|
if (myClass !is JetClassOrObject) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val field = myClass.getDeclarations().firstOrNull { fieldName == it.getName() }
|
||||||
|
if (field == null) return null
|
||||||
|
|
||||||
|
if (nearest) {
|
||||||
|
return DebuggerContextUtil.findNearest(context, field, myClass.getContainingFile())
|
||||||
|
}
|
||||||
|
return SourcePosition.createFromOffset(field.getContainingFile(), field.getTextOffset())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findClassByType(type: ReferenceType, context: DebuggerContextImpl): PsiElement? {
|
||||||
|
val session = context.getDebuggerSession()
|
||||||
|
val scope = if (session != null) session.getSearchScope() else GlobalSearchScope.allScope(myProject)
|
||||||
|
val className = JvmClassName.byInternalName(type.name()).getFqNameForClassNameWithoutDollars().asString()
|
||||||
|
|
||||||
|
val myClass = JavaPsiFacade.getInstance(myProject).findClass(className, scope)
|
||||||
|
if (myClass != null) return myClass
|
||||||
|
|
||||||
|
val position = getLastSourcePosition(type, context)
|
||||||
|
if (position != null) {
|
||||||
|
val element = position.getElementAt()
|
||||||
|
if (element != null) {
|
||||||
|
return PsiTreeUtil.getParentOfType(element, javaClass<JetClassOrObject>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getLastSourcePosition(type: ReferenceType, context: DebuggerContextImpl): SourcePosition? {
|
||||||
|
val debugProcess = context.getDebugProcess()
|
||||||
|
if (debugProcess != null) {
|
||||||
|
try {
|
||||||
|
val locations = type.allLineLocations()
|
||||||
|
if (!locations.isEmpty()) {
|
||||||
|
val lastLocation = locations.get(locations.size() - 1)
|
||||||
|
return debugProcess.getPositionManager().getSourcePosition(lastLocation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ignored: AbsentInformationException) {
|
||||||
|
}
|
||||||
|
catch (ignored: ClassNotPreparedException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Type?.isKotlinClass(): Boolean {
|
||||||
|
return this is ClassType && this.allInterfaces().any { it.name() == JvmAbi.K_OBJECT.asString() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ class MyDelegateThrowsException {
|
|||||||
static = static = delegatedPropertyInClass.DelegatedPropertyInClassPackage$@packagePartHASH
|
static = static = delegatedPropertyInClass.DelegatedPropertyInClassPackage$@packagePartHASH
|
||||||
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
||||||
local = a: delegatedPropertyInClass.A = {delegatedPropertyInClass.A@uniqueID}
|
local = a: delegatedPropertyInClass.A = {delegatedPropertyInClass.A@uniqueID}
|
||||||
field = prop$delegate: delegatedPropertyInClass.MyDelegate = {delegatedPropertyInClass.MyDelegate@uniqueID}
|
field = prop$delegate: delegatedPropertyInClass.MyDelegate = {delegatedPropertyInClass.MyDelegate@uniqueID} (sp = null)
|
||||||
field = prop: int = 1
|
field = prop: int = 1
|
||||||
field = propEx$delegate: delegatedPropertyInClass.MyDelegateThrowsException = {delegatedPropertyInClass.MyDelegateThrowsException@uniqueID}
|
field = propEx$delegate: delegatedPropertyInClass.MyDelegateThrowsException = {delegatedPropertyInClass.MyDelegateThrowsException@uniqueID} (sp = null)
|
||||||
field = propEx: java.lang.IllegalStateException = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException
|
field = propEx: java.lang.IllegalStateException = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException
|
||||||
field = detailMessage: java.lang.String = null
|
field = detailMessage: java.lang.String = null (sp = Throwable.!EXT!)
|
||||||
field = cause: java.lang.Throwable = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException
|
field = cause: java.lang.Throwable = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException (sp = Throwable.!EXT!)
|
||||||
field = stackTrace: java.lang.StackTraceElement[] = null
|
field = stackTrace: java.lang.StackTraceElement[] = null (sp = Throwable.!EXT!)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ fun foo(f: () -> Unit) {
|
|||||||
// PRINT_FRAME
|
// PRINT_FRAME
|
||||||
frame = invoke():11, FrameAnonymousObjectPackage$@packagePartHASH$main$o$1$run$1 {frameAnonymousObject}
|
frame = invoke():11, FrameAnonymousObjectPackage$@packagePartHASH$main$o$1$run$1 {frameAnonymousObject}
|
||||||
this = this = {frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1$run$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
this = this = {frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1$run$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||||
field = this$0: frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1 = {frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1@uniqueID}
|
field = this$0: frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1 = {frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1@uniqueID} (sp = null)
|
||||||
field = obProp: int = 1
|
field = obProp: int = 1 (sp = frameAnonymousObject.kt, 5)
|
||||||
field = $val1: int = 1
|
field = $val1: int = 1 (sp = null)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -70,16 +70,16 @@ fun lambda(f: () -> Unit) {
|
|||||||
// RESULT: 1: I
|
// RESULT: 1: I
|
||||||
frame = invoke():22, Outer$foo$LocalClass$test$1 {frameExtFunExtFun}
|
frame = invoke():22, Outer$foo$LocalClass$test$1 {frameExtFunExtFun}
|
||||||
this = this = {frameExtFunExtFun.Outer$foo$LocalClass$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
this = this = {frameExtFunExtFun.Outer$foo$LocalClass$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||||
field = this$0: frameExtFunExtFun.Outer$foo$LocalClass = {frameExtFunExtFun.Outer$foo$LocalClass@uniqueID}
|
field = this$0: frameExtFunExtFun.Outer$foo$LocalClass = {frameExtFunExtFun.Outer$foo$LocalClass@uniqueID} (sp = null)
|
||||||
field = lcProp: int = 1
|
field = lcProp: int = 1 (sp = frameExtFunExtFun.kt, 16)
|
||||||
field = this$0: frameExtFunExtFun.Outer = {frameExtFunExtFun.Outer@uniqueID}
|
field = this$0: frameExtFunExtFun.Outer = {frameExtFunExtFun.Outer@uniqueID} (sp = null)
|
||||||
field = outerProp: int = 1
|
field = outerProp: int = 1 (sp = frameExtFunExtFun.kt, 11)
|
||||||
field = receiver$0: frameExtFunExtFun.A = {frameExtFunExtFun.A@uniqueID}
|
field = receiver$0: frameExtFunExtFun.A = {frameExtFunExtFun.A@uniqueID} (sp = null)
|
||||||
field = aProp: int = 1
|
field = aProp: int = 1 (sp = frameExtFunExtFun.kt, 7)
|
||||||
field = $valFoo: int = 1
|
field = $valFoo: int = 1 (sp = null)
|
||||||
field = receiver$0: frameExtFunExtFun.B = {frameExtFunExtFun.B@uniqueID}
|
field = receiver$0: frameExtFunExtFun.B = {frameExtFunExtFun.B@uniqueID} (sp = null)
|
||||||
field = bProp: int = 1
|
field = bProp: int = 1 (sp = frameExtFunExtFun.kt, 38)
|
||||||
field = $valTest: int = 1
|
field = $valTest: int = 1 (sp = null)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ fun A.foo() {
|
|||||||
frame = foo():13, FrameExtensionFunPackage$@packagePartHASH {frameExtensionFun}
|
frame = foo():13, FrameExtensionFunPackage$@packagePartHASH {frameExtensionFun}
|
||||||
static = static = frameExtensionFun.FrameExtensionFunPackage$@packagePartHASH
|
static = static = frameExtensionFun.FrameExtensionFunPackage$@packagePartHASH
|
||||||
local = $receiver: frameExtensionFun.A = {frameExtensionFun.A@uniqueID}
|
local = $receiver: frameExtensionFun.A = {frameExtensionFun.A@uniqueID}
|
||||||
field = prop: int = 1
|
field = prop: int = 1 (sp = frameExtensionFun.kt, 7)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ class A {
|
|||||||
// RESULT: 1: I
|
// RESULT: 1: I
|
||||||
frame = test():15, A$Inner {frameInnerClass}
|
frame = test():15, A$Inner {frameInnerClass}
|
||||||
this = this = {frameInnerClass.A$Inner@uniqueID}
|
this = this = {frameInnerClass.A$Inner@uniqueID}
|
||||||
field = prop2: int = 1
|
field = prop2: int = 1 (sp = frameInnerClass.kt, 10)
|
||||||
field = this$0: frameInnerClass.A = {frameInnerClass.A@uniqueID}
|
field = this$0: frameInnerClass.A = {frameInnerClass.A@uniqueID} (sp = null)
|
||||||
field = prop1: int = 1
|
field = prop1: int = 1 (sp = frameInnerClass.kt, 7)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ fun foo(f: () -> Unit) {
|
|||||||
// RESULT: 2: I
|
// RESULT: 2: I
|
||||||
frame = invoke():9, FrameInnerLambdaPackage$@packagePartHASH$main$1$1 {frameInnerLambda}
|
frame = invoke():9, FrameInnerLambdaPackage$@packagePartHASH$main$1$1 {frameInnerLambda}
|
||||||
this = this = {frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
this = this = {frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||||
field = this$0: frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1 = {frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
field = this$0: frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1 = {frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit> (sp = null)
|
||||||
field = $val1: int = 1
|
field = $val1: int = 1 (sp = null)
|
||||||
field = $val2: int = 1
|
field = $val2: int = 1 (sp = null)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ fun foo(f: () -> Unit) {
|
|||||||
// RESULT: 1: I
|
// RESULT: 1: I
|
||||||
frame = invoke():7, FrameLambdaPackage$@packagePartHASH$main$1 {frameLambda}
|
frame = invoke():7, FrameLambdaPackage$@packagePartHASH$main$1 {frameLambda}
|
||||||
this = this = {frameLambda.FrameLambdaPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
this = this = {frameLambda.FrameLambdaPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||||
field = $val1: int = 1
|
field = $val1: int = 1 (sp = null)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ fun foo(f: () -> Unit) {
|
|||||||
// RESULT: 1: I
|
// RESULT: 1: I
|
||||||
frame = invoke():7, FrameSharedVarPackage$@packagePartHASH$main$1 {frameSharedVar}
|
frame = invoke():7, FrameSharedVarPackage$@packagePartHASH$main$1 {frameSharedVar}
|
||||||
this = this = {frameSharedVar.FrameSharedVarPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
this = this = {frameSharedVar.FrameSharedVarPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||||
field = $var1: kotlin.jvm.internal.Ref$IntRef = {kotlin.jvm.internal.Ref$IntRef@uniqueID}1
|
field = $var1: kotlin.jvm.internal.Ref$IntRef = {kotlin.jvm.internal.Ref$IntRef@uniqueID}1 (sp = null)
|
||||||
field = element: int = 1
|
field = element: int = 1 (sp = Ref.!EXT!)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ inline fun foo(f: () -> Unit) {
|
|||||||
static = static = frameSharedVarLocalVar.FrameSharedVarLocalVarPackage$@packagePartHASH
|
static = static = frameSharedVarLocalVar.FrameSharedVarLocalVarPackage$@packagePartHASH
|
||||||
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
||||||
local = var1: kotlin.jvm.internal.Ref$IntRef = {kotlin.jvm.internal.Ref$IntRef@uniqueID}1
|
local = var1: kotlin.jvm.internal.Ref$IntRef = {kotlin.jvm.internal.Ref$IntRef@uniqueID}1
|
||||||
field = element: int = 1
|
field = element: int = 1 (sp = Ref.!EXT!)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -32,17 +32,17 @@ fun main(args: Array<String>) {
|
|||||||
// RESULT: 2: I
|
// RESULT: 2: I
|
||||||
frame = main():9, FrameSimplePackage$@packagePartHASH {frameSimple}
|
frame = main():9, FrameSimplePackage$@packagePartHASH {frameSimple}
|
||||||
static = static = frameSimple.FrameSimplePackage$@packagePartHASH
|
static = static = frameSimple.FrameSimplePackage$@packagePartHASH
|
||||||
field = topVal1: int = 1
|
field = topVal1: int = 1 (sp = null)
|
||||||
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
||||||
local = val1: int = 1
|
local = val1: int = 1
|
||||||
local = val2: java.lang.String = {@uniqueID}str
|
local = val2: java.lang.String = {@uniqueID}str
|
||||||
field = value: char[] = {char[3]@uniqueID}
|
field = value: char[] = {char[3]@uniqueID} (sp = String.!EXT!)
|
||||||
unknown = [0] = 's' 115
|
unknown = [0] = 's' 115
|
||||||
unknown = [1] = 't' 116
|
unknown = [1] = 't' 116
|
||||||
unknown = [2] = 'r' 114
|
unknown = [2] = 'r' 114
|
||||||
field = offset: int = 0
|
field = offset: int = 0 (sp = String.!EXT!)
|
||||||
field = count: int = 3
|
field = count: int = 3 (sp = String.!EXT!)
|
||||||
field = hash: int = 0
|
field = hash: int = 0 (sp = String.!EXT!)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ fun foo(f: () -> Unit) {
|
|||||||
// RESULT: 3: I
|
// RESULT: 3: I
|
||||||
frame = invoke():15, A$test$1 {frameThis0}
|
frame = invoke():15, A$test$1 {frameThis0}
|
||||||
this = this = {frameThis0.A$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
this = this = {frameThis0.A$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||||
field = this$0: frameThis0.A = {frameThis0.A@uniqueID}
|
field = this$0: frameThis0.A = {frameThis0.A@uniqueID} (sp = null)
|
||||||
field = prop1: int = 1
|
field = prop1: int = 1 (sp = frameThis0.kt, 7)
|
||||||
field = $val1: int = 1
|
field = $val1: int = 1 (sp = null)
|
||||||
local = val2: int = 1
|
local = val2: int = 1
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ fun foo(f: () -> Unit) {
|
|||||||
// RESULT: 2: I
|
// RESULT: 2: I
|
||||||
frame = invoke():14, A$testExt$1 {frameThis0Ext}
|
frame = invoke():14, A$testExt$1 {frameThis0Ext}
|
||||||
this = this = {frameThis0Ext.A$testExt$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
this = this = {frameThis0Ext.A$testExt$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||||
field = this$0: frameThis0Ext.A = {frameThis0Ext.A@uniqueID}
|
field = this$0: frameThis0Ext.A = {frameThis0Ext.A@uniqueID} (sp = null)
|
||||||
field = prop1: int = 1
|
field = prop1: int = 1 (sp = frameThis0Ext.kt, 7)
|
||||||
field = receiver$0: frameThis0Ext.AExt = {frameThis0Ext.AExt@uniqueID}
|
field = receiver$0: frameThis0Ext.AExt = {frameThis0Ext.AExt@uniqueID} (sp = null)
|
||||||
field = prop2: int = 1
|
field = prop2: int = 1 (sp = frameThis0Ext.kt, 23)
|
||||||
field = $val1: int = 1
|
field = $val1: int = 1 (sp = null)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ fun foo(f: () -> Unit) {
|
|||||||
// RESULT: 3: I
|
// RESULT: 3: I
|
||||||
frame = invoke():16, A$test$1$1 {frameThis0This0}
|
frame = invoke():16, A$test$1$1 {frameThis0This0}
|
||||||
this = this = {frameThis0This0.A$test$1$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
this = this = {frameThis0This0.A$test$1$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||||
field = this$0: frameThis0This0.A$test$1 = {frameThis0This0.A$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
field = this$0: frameThis0This0.A$test$1 = {frameThis0This0.A$test$1@uniqueID}kotlin.Function0<kotlin.Unit> (sp = null)
|
||||||
field = this$0: frameThis0This0.A = {frameThis0This0.A@uniqueID}
|
field = this$0: frameThis0This0.A = {frameThis0This0.A@uniqueID} (sp = null)
|
||||||
field = prop1: int = 1
|
field = prop1: int = 1 (sp = frameThis0This0.kt, 7)
|
||||||
field = $val1: int = 1
|
field = $val1: int = 1 (sp = null)
|
||||||
field = $val2: int = 1
|
field = $val2: int = 1 (sp = null)
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import com.intellij.openapi.roots.libraries.LibraryUtil
|
|||||||
import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor
|
import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor
|
||||||
import com.intellij.openapi.roots.JdkOrderEntry
|
import com.intellij.openapi.roots.JdkOrderEntry
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.debugger.SourcePosition
|
||||||
|
|
||||||
abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
||||||
|
|
||||||
@@ -54,25 +55,29 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val sourcePosition = PositionUtil.getSourcePosition(this)
|
val sourcePosition = PositionUtil.getSourcePosition(this)
|
||||||
if (sourcePosition == null) {
|
println(renderSourcePosition(sourcePosition), ProcessOutputTypes.SYSTEM)
|
||||||
return@runReadAction println("SourcePosition is null", ProcessOutputTypes.SYSTEM)
|
|
||||||
}
|
|
||||||
|
|
||||||
val virtualFile = sourcePosition.getFile().getVirtualFile()
|
|
||||||
if (virtualFile == null) {
|
|
||||||
return@runReadAction println("VirtualFile for position is null", ProcessOutputTypes.SYSTEM)
|
|
||||||
}
|
|
||||||
|
|
||||||
val libraryEntry = LibraryUtil.findLibraryEntry(virtualFile, getProject())
|
|
||||||
if (libraryEntry != null && (libraryEntry is JdkOrderEntry ||
|
|
||||||
libraryEntry.getPresentableName() == JetJdkAndLibraryProjectDescriptor.LIBRARY_NAME)) {
|
|
||||||
return@runReadAction println(FileUtil.getNameWithoutExtension(virtualFile.getName()) + ".!EXT!", ProcessOutputTypes.SYSTEM)
|
|
||||||
}
|
|
||||||
|
|
||||||
println(virtualFile.getName() + ":" + sourcePosition.getLine(), ProcessOutputTypes.SYSTEM)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun renderSourcePosition(sourcePosition: SourcePosition?): String {
|
||||||
|
if (sourcePosition == null) {
|
||||||
|
return "null"
|
||||||
|
}
|
||||||
|
|
||||||
|
val virtualFile = sourcePosition.getFile().getVirtualFile()
|
||||||
|
if (virtualFile == null) {
|
||||||
|
return "VirtualFile for position is null"
|
||||||
|
}
|
||||||
|
|
||||||
|
val libraryEntry = LibraryUtil.findLibraryEntry(virtualFile, getProject())
|
||||||
|
if (libraryEntry != null && (libraryEntry is JdkOrderEntry ||
|
||||||
|
libraryEntry.getPresentableName() == JetJdkAndLibraryProjectDescriptor.LIBRARY_NAME)) {
|
||||||
|
return FileUtil.getNameWithoutExtension(virtualFile.getName()) + ".!EXT!"
|
||||||
|
}
|
||||||
|
|
||||||
|
return virtualFile.getName() + ":" + sourcePosition.getLine()
|
||||||
|
}
|
||||||
|
|
||||||
protected fun finish() {
|
protected fun finish() {
|
||||||
onBreakpoint {
|
onBreakpoint {
|
||||||
resume(this)
|
resume(this)
|
||||||
|
|||||||
+16
-4
@@ -58,8 +58,10 @@ import com.intellij.psi.PsiManager
|
|||||||
import com.intellij.debugger.DebuggerManagerEx
|
import com.intellij.debugger.DebuggerManagerEx
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.openapi.application.ModalityState
|
import com.intellij.openapi.application.ModalityState
|
||||||
import com.intellij.debugger.ui.tree.render.ClassRenderer
|
|
||||||
import com.intellij.debugger.settings.NodeRendererSettings
|
import com.intellij.debugger.settings.NodeRendererSettings
|
||||||
|
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl
|
||||||
|
import com.intellij.debugger.impl.DebuggerContextImpl
|
||||||
|
import com.intellij.debugger.SourcePosition
|
||||||
|
|
||||||
public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() {
|
public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() {
|
||||||
private val logger = Logger.getLogger(javaClass<KotlinEvaluateExpressionCache>())!!
|
private val logger = Logger.getLogger(javaClass<KotlinEvaluateExpressionCache>())!!
|
||||||
@@ -221,13 +223,17 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestB
|
|||||||
invokeRatherLater(this) {
|
invokeRatherLater(this) {
|
||||||
tree.rebuild(debuggerContext)
|
tree.rebuild(debuggerContext)
|
||||||
expandAll(tree, Runnable {
|
expandAll(tree, Runnable {
|
||||||
PRINTER.printTree(tree)
|
try {
|
||||||
resume(this@printFrame)
|
Printer(debuggerContext).printTree(tree)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
resume(this@printFrame)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val PRINTER = object {
|
private inner class Printer(val debuggerContext: DebuggerContextImpl) {
|
||||||
fun printTree(tree: DebuggerTree) {
|
fun printTree(tree: DebuggerTree) {
|
||||||
val root = tree.getMutableModel()!!.getRoot() as DebuggerTreeNodeImpl
|
val root = tree.getMutableModel()!!.getRoot() as DebuggerTreeNodeImpl
|
||||||
printNode(root, 0)
|
printNode(root, 0)
|
||||||
@@ -246,6 +252,8 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestB
|
|||||||
is LocalVariableDescriptor -> logDescriptor(descriptor, "$curIndent local = $label\n")
|
is LocalVariableDescriptor -> logDescriptor(descriptor, "$curIndent local = $label\n")
|
||||||
is StaticDescriptor -> logDescriptor(descriptor, "$curIndent static = $label\n")
|
is StaticDescriptor -> logDescriptor(descriptor, "$curIndent static = $label\n")
|
||||||
is ThisDescriptorImpl -> logDescriptor(descriptor, "$curIndent this = $label\n")
|
is ThisDescriptorImpl -> logDescriptor(descriptor, "$curIndent this = $label\n")
|
||||||
|
is FieldDescriptorImpl -> logDescriptor(descriptor, "$curIndent field = $label"
|
||||||
|
+ " (sp = ${render(descriptor.getSourcePosition(myProject, debuggerContext))})\n")
|
||||||
is FieldDescriptor -> logDescriptor(descriptor, "$curIndent field = $label\n")
|
is FieldDescriptor -> logDescriptor(descriptor, "$curIndent field = $label\n")
|
||||||
else -> logDescriptor(descriptor, "$curIndent unknown = $label\n")
|
else -> logDescriptor(descriptor, "$curIndent unknown = $label\n")
|
||||||
}
|
}
|
||||||
@@ -259,6 +267,10 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestB
|
|||||||
printNode(e.nextElement() as DebuggerTreeNodeImpl, indent)
|
printNode(e.nextElement() as DebuggerTreeNodeImpl, indent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun render(sp: SourcePosition?): String {
|
||||||
|
return renderSourcePosition(sp).replace(":", ", ")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkExceptions(exceptions: MutableMap<String, Throwable>) {
|
private fun checkExceptions(exceptions: MutableMap<String, Throwable>) {
|
||||||
|
|||||||
Reference in New Issue
Block a user