Static method calls supported
This commit is contained in:
@@ -5,12 +5,18 @@
|
|||||||
<item name='com.sun.jdi.ReferenceType com.sun.jdi.ClassObjectReference classObject()'>
|
<item name='com.sun.jdi.ReferenceType com.sun.jdi.ClassObjectReference classObject()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
<item name='com.sun.jdi.ReferenceType java.util.List<com.sun.jdi.Method> methodsByName(java.lang.String, java.lang.String)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
<item name='com.sun.jdi.StackFrame com.sun.jdi.Location location()'>
|
<item name='com.sun.jdi.StackFrame com.sun.jdi.Location location()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
<item name='com.sun.jdi.Type java.lang.String signature()'>
|
<item name='com.sun.jdi.Type java.lang.String signature()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
<item name='com.sun.jdi.TypeComponent com.sun.jdi.ReferenceType declaringType()'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
<item name='com.sun.jdi.Value com.sun.jdi.Type type()'>
|
<item name='com.sun.jdi.Value com.sun.jdi.Type type()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -97,8 +97,30 @@ class JDIEval(
|
|||||||
_class.setValue(field, newValue.asJdiValue(vm))
|
_class.setValue(field, newValue.asJdiValue(vm))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun findMethod(methodDesc: MethodDescription): jdi.Method {
|
||||||
|
val _class = loadClass(methodDesc.ownerType).jdiClass!!.reflectedType()
|
||||||
|
val method = when (_class) {
|
||||||
|
is jdi.ClassType -> {
|
||||||
|
val m = _class.concreteMethodByName(methodDesc.name, methodDesc.desc)
|
||||||
|
if (m == null) listOf() else listOf(m)
|
||||||
|
}
|
||||||
|
else -> _class.methodsByName(methodDesc.name, methodDesc.desc)
|
||||||
|
}
|
||||||
|
if (method.isEmpty()) {
|
||||||
|
throwException(NoSuchMethodError("Method not found: $methodDesc"))
|
||||||
|
}
|
||||||
|
return method[0]
|
||||||
|
}
|
||||||
|
|
||||||
override fun invokeStaticMethod(methodDesc: MethodDescription, arguments: List<Value>): Value {
|
override fun invokeStaticMethod(methodDesc: MethodDescription, arguments: List<Value>): Value {
|
||||||
throw UnsupportedOperationException()
|
val method = findMethod(methodDesc)
|
||||||
|
if (!method.isStatic()) {
|
||||||
|
throwException(NoSuchMethodError("Method is not static: $methodDesc"))
|
||||||
|
}
|
||||||
|
val _class = method.declaringType()
|
||||||
|
if (_class !is jdi.ClassType) throwException(NoSuchMethodError("Static method is a non-class type: $method"))
|
||||||
|
|
||||||
|
return _class.invokeMethod(thread, method, arguments.map {v -> v.asJdiValue(vm)}, 0).asValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getField(instance: Value, fieldDesc: FieldDescription): Value {
|
override fun getField(instance: Value, fieldDesc: FieldDescription): Value {
|
||||||
|
|||||||
@@ -55,4 +55,25 @@ val Value.jdiObj: jdi.ObjectReference?
|
|||||||
get() = this.obj as jdi.ObjectReference?
|
get() = this.obj as jdi.ObjectReference?
|
||||||
|
|
||||||
val Value.jdiClass: jdi.ClassObjectReference?
|
val Value.jdiClass: jdi.ClassObjectReference?
|
||||||
get() = this.jdiObj as jdi.ClassObjectReference?
|
get() = this.jdiObj as jdi.ClassObjectReference?
|
||||||
|
|
||||||
|
fun Value.asJdiValue(vm: jdi.VirtualMachine): jdi.Value? {
|
||||||
|
return when (this) {
|
||||||
|
NULL_VALUE -> null
|
||||||
|
VOID_VALUE -> vm.mirrorOfVoid()
|
||||||
|
is IntValue -> when (asmType) {
|
||||||
|
Type.BOOLEAN_TYPE -> vm.mirrorOf(boolean)
|
||||||
|
Type.BYTE_TYPE -> vm.mirrorOf(int.toByte())
|
||||||
|
Type.SHORT_TYPE -> vm.mirrorOf(int.toShort())
|
||||||
|
Type.CHAR_TYPE -> vm.mirrorOf(int.toChar())
|
||||||
|
Type.INT_TYPE -> vm.mirrorOf(int)
|
||||||
|
else -> throw JDIFailureException("Unknown value type: $this")
|
||||||
|
}
|
||||||
|
is LongValue -> vm.mirrorOf(value)
|
||||||
|
is FloatValue -> vm.mirrorOf(value)
|
||||||
|
is DoubleValue -> vm.mirrorOf(value)
|
||||||
|
is ObjectValue -> value as jdi.ObjectReference
|
||||||
|
is NewObjectValue -> throw JDIFailureException("Illegal value: $this")
|
||||||
|
else -> throw JDIFailureException("Unknown value: $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user