Equality comparison for bound callable references takes into account bound receiver.

Fixed KT-14939: use expected receiver type when generating receiver code in get/set methods for bound property references.
Otherwise we have VerifyError for bound receiver 'null' of type 'Nothing?', which is mapped to 'java.lang.Void'.

TODO: proper equality comparison for property accessors ('x::prop.getter', 'x::prop.setter').
This commit is contained in:
Dmitry Petrov
2016-11-23 14:03:23 +03:00
parent ce6cf6475c
commit 3dd0c9d1c7
28 changed files with 525 additions and 20 deletions
@@ -39,6 +39,17 @@ public abstract class CallableReference implements KCallable {
// objects are written to it. The latter is guaranteed because both KFunctionImpl and KPropertyImpl have at least one final field.
private KCallable reflected;
protected final Object receiver$0;
private static final Object NO_RECEIVER = new Object();
public CallableReference() {
this(NO_RECEIVER);
}
protected CallableReference(Object receiver$0) {
this.receiver$0 = receiver$0;
}
protected abstract KCallable computeReflected();
public KCallable compute() {
@@ -26,6 +26,11 @@ public class FunctionReference extends CallableReference implements FunctionImpl
this.arity = arity;
}
public FunctionReference(int arity, Object receiver) {
super(receiver);
this.arity = arity;
}
@Override
public int getArity() {
return arity;
@@ -71,9 +76,11 @@ public class FunctionReference extends CallableReference implements FunctionImpl
if (obj == this) return true;
if (obj instanceof FunctionReference) {
FunctionReference other = (FunctionReference) obj;
return getOwner().equals(other.getOwner()) &&
getName().equals(other.getName()) &&
getSignature().equals(other.getSignature());
getSignature().equals(other.getSignature()) &&
Intrinsics.areEqual(receiver$0, other.receiver$0);
}
if (obj instanceof KFunction) {
return obj.equals(compute());
@@ -19,4 +19,10 @@ package kotlin.jvm.internal;
import kotlin.reflect.KMutableProperty;
public abstract class MutablePropertyReference extends PropertyReference implements KMutableProperty {
public MutablePropertyReference() {
}
public MutablePropertyReference(Object receiver$0) {
super(receiver$0);
}
}
@@ -21,6 +21,13 @@ import kotlin.reflect.KMutableProperty0;
import kotlin.reflect.KProperty0;
public abstract class MutablePropertyReference0 extends MutablePropertyReference implements KMutableProperty0 {
public MutablePropertyReference0() {
}
public MutablePropertyReference0(Object receiver$0) {
super(receiver$0);
}
@Override
protected KCallable computeReflected() {
return Reflection.mutableProperty0(this);
@@ -21,6 +21,13 @@ import kotlin.reflect.KMutableProperty1;
import kotlin.reflect.KProperty1;
public abstract class MutablePropertyReference1 extends MutablePropertyReference implements KMutableProperty1 {
public MutablePropertyReference1() {
}
public MutablePropertyReference1(Object receiver$0) {
super(receiver$0);
}
@Override
protected KCallable computeReflected() {
return Reflection.mutableProperty1(this);
@@ -20,6 +20,14 @@ import kotlin.reflect.KCallable;
import kotlin.reflect.KProperty;
public abstract class PropertyReference extends CallableReference implements KProperty {
public PropertyReference() {
super();
}
public PropertyReference(Object receiver$0) {
super(receiver$0);
}
@Override
protected KProperty getReflected() {
return (KProperty) super.getReflected();
@@ -42,7 +50,8 @@ public abstract class PropertyReference extends CallableReference implements KPr
PropertyReference other = (PropertyReference) obj;
return getOwner().equals(other.getOwner()) &&
getName().equals(other.getName()) &&
getSignature().equals(other.getSignature());
getSignature().equals(other.getSignature()) &&
Intrinsics.areEqual(receiver$0, other.receiver$0);
}
if (obj instanceof KProperty) {
return obj.equals(compute());
@@ -20,6 +20,14 @@ import kotlin.reflect.KCallable;
import kotlin.reflect.KProperty0;
public abstract class PropertyReference0 extends PropertyReference implements KProperty0 {
public PropertyReference0() {
super();
}
public PropertyReference0(Object receiver$0) {
super(receiver$0);
}
@Override
protected KCallable computeReflected() {
return Reflection.property0(this);
@@ -20,6 +20,13 @@ import kotlin.reflect.KCallable;
import kotlin.reflect.KProperty1;
public abstract class PropertyReference1 extends PropertyReference implements KProperty1 {
public PropertyReference1() {
}
public PropertyReference1(Object receiver$0) {
super(receiver$0);
}
@Override
protected KCallable computeReflected() {
return Reflection.property1(this);