Change behavior of equals/hashCode on adapted function references
Function references are now equal if they refer to the same function, and if the parameter/return type adaptation, which happens when a reference is used where some function type is expected, is exactly the same. This includes the number of expected positional parameters (which can be affected by defaults/varargs), whether the coercion of vararg parameter to Array type happened, and whether the coercion of return type to Unit happened. #KT-37543 Fixed
This commit is contained in:
committed by
Alexander Udalov
parent
c344b85d4e
commit
3269a7e693
@@ -62,20 +62,16 @@ public abstract class CallableReference implements KCallable, Serializable {
|
||||
|
||||
@SinceKotlin(version = "1.1")
|
||||
protected CallableReference(Object receiver) {
|
||||
this(receiver, null, null, null, 0);
|
||||
this(receiver, null, null, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param flags Bitmask where bits represent the following flags:<br/>
|
||||
* <li><ul>0 - the owner of this reference is a package, not a class.</ul></li>
|
||||
*/
|
||||
@SinceKotlin(version = "1.4")
|
||||
protected CallableReference(Object receiver, Class owner, String name, String signature, int flags) {
|
||||
protected CallableReference(Object receiver, Class owner, String name, String signature, boolean isTopLevel) {
|
||||
this.receiver = receiver;
|
||||
this.owner = owner;
|
||||
this.name = name;
|
||||
this.signature = signature;
|
||||
this.isTopLevel = (flags & 1) == 1;
|
||||
this.isTopLevel = isTopLevel;
|
||||
}
|
||||
|
||||
protected abstract KCallable computeReflected();
|
||||
|
||||
@@ -13,8 +13,26 @@ import kotlin.reflect.KFunction;
|
||||
public class FunctionReference extends CallableReference implements FunctionBase, KFunction {
|
||||
private final int arity;
|
||||
|
||||
/**
|
||||
* Bitmask where bits represent the following flags:<br/>
|
||||
* <li>
|
||||
* <ul>0 - whether the vararg to element parameter type conversion happened, i.e.<pre>
|
||||
* fun target(vararg xs: Int) {}
|
||||
* fun use(f: (Int, Int, Int) -> Unit) {}
|
||||
* use(::target)
|
||||
* </pre></ul>
|
||||
* <ul>1 - whether coercion of return type to Unit happened, i.e.<pre>
|
||||
* fun target(): Boolean = true
|
||||
* fun use(f: () -> Unit) {}
|
||||
* use(::target)
|
||||
* </pre></ul>
|
||||
* </li>
|
||||
*/
|
||||
@SinceKotlin(version = "1.4")
|
||||
private final int flags;
|
||||
|
||||
public FunctionReference(int arity) {
|
||||
this.arity = arity;
|
||||
this(arity, NO_RECEIVER, null, null, null, 0);
|
||||
}
|
||||
|
||||
@SinceKotlin(version = "1.1")
|
||||
@@ -24,8 +42,9 @@ public class FunctionReference extends CallableReference implements FunctionBase
|
||||
|
||||
@SinceKotlin(version = "1.4")
|
||||
public FunctionReference(int arity, Object receiver, Class owner, String name, String signature, int flags) {
|
||||
super(receiver, owner, name, signature, flags);
|
||||
super(receiver, owner, name, signature, (flags & 1) == 1);
|
||||
this.arity = arity;
|
||||
this.flags = flags >> 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,9 +100,11 @@ public class FunctionReference extends CallableReference implements FunctionBase
|
||||
if (obj instanceof FunctionReference) {
|
||||
FunctionReference other = (FunctionReference) obj;
|
||||
|
||||
return (getOwner() == null ? other.getOwner() == null : getOwner().equals(other.getOwner())) &&
|
||||
return Intrinsics.areEqual(getOwner(), other.getOwner()) &&
|
||||
getName().equals(other.getName()) &&
|
||||
getSignature().equals(other.getSignature()) &&
|
||||
flags == other.flags &&
|
||||
arity == other.arity &&
|
||||
Intrinsics.areEqual(getBoundReceiver(), other.getBoundReceiver());
|
||||
}
|
||||
if (obj instanceof KFunction) {
|
||||
|
||||
@@ -22,7 +22,7 @@ public abstract class PropertyReference extends CallableReference implements KPr
|
||||
|
||||
@SinceKotlin(version = "1.4")
|
||||
public PropertyReference(Object receiver, Class owner, String name, String signature, int flags) {
|
||||
super(receiver, owner, name, signature, flags);
|
||||
super(receiver, owner, name, signature, (flags & 1) == 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user