Fix EA-1005833: Try to find a field using also the receiver type (KT-21820)

This commit is contained in:
Yan Zhulanow
2017-11-28 20:16:31 +09:00
committed by Yan Zhulanow
parent d58665b5a8
commit 6941065e2c
+13 -14
View File
@@ -167,13 +167,12 @@ class JDIEval(
} }
} }
private fun findField(fieldDesc: FieldDescription): Field { private fun findField(fieldDesc: FieldDescription, receiver: ReferenceType? = null): Field {
val _class = fieldDesc.ownerType.asReferenceType() for (owner in listOfNotNull(receiver, fieldDesc.ownerType.asReferenceType())) {
val field = _class.fieldByName(fieldDesc.name) owner.fieldByName(fieldDesc.name)?.let { return it }
if (field == null) {
throwBrokenCodeException(NoSuchFieldError("Field not found: $fieldDesc"))
} }
return field
throwBrokenCodeException(NoSuchFieldError("Field not found: $fieldDesc"))
} }
private fun findStaticField(fieldDesc: FieldDescription): Field { private fun findStaticField(fieldDesc: FieldDescription): Field {
@@ -256,26 +255,26 @@ class JDIEval(
} }
override fun getField(instance: Value, fieldDesc: FieldDescription): Value { override fun getField(instance: Value, fieldDesc: FieldDescription): Value {
val field = findField(fieldDesc) val receiver = instance.jdiObj.checkNull()
val obj = instance.jdiObj.checkNull() val field = findField(fieldDesc, receiver.referenceType())
return mayThrow { return mayThrow {
try { try {
obj.getValue(field) receiver.getValue(field)
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
throw IllegalArgumentException("Possibly incompatible types: " + throw IllegalArgumentException("Possibly incompatible types: " +
"field declaring type = ${field.declaringType()}, " + "field declaring type = ${field.declaringType()}, " +
"instance type = ${obj.referenceType()}") "instance type = ${receiver.referenceType()}")
} }
}.ifFail(field, obj).asValue() }.ifFail(field, receiver).asValue()
} }
override fun setField(instance: Value, fieldDesc: FieldDescription, newValue: Value) { override fun setField(instance: Value, fieldDesc: FieldDescription, newValue: Value) {
val field = findField(fieldDesc) val receiver = instance.jdiObj.checkNull()
val obj = instance.jdiObj.checkNull() val field = findField(fieldDesc, receiver.referenceType())
val jdiValue = newValue.asJdiValue(vm, field.type().asType()) val jdiValue = newValue.asJdiValue(vm, field.type().asType())
mayThrow { obj.setValue(field, jdiValue) } mayThrow { receiver.setValue(field, jdiValue) }
} }
fun unboxType(boxedValue: Value, type: Type): Value { fun unboxType(boxedValue: Value, type: Type): Value {