Add equals and hashcode to PType (#1691)

This commit is contained in:
Islon Scherer
2026-06-24 11:31:11 +02:00
committed by GitHub
parent f7cac257ad
commit dd6939ab3f
3 changed files with 170 additions and 0 deletions
@@ -80,6 +80,17 @@ public abstract class PType implements Serializable {
public String toString() {
return ValueFormatter.basic().formatStringValue(literal, "");
}
@Override
public boolean equals(@org.jspecify.annotations.Nullable Object obj) {
if (obj == this) return true;
return obj instanceof StringLiteral that && literal.equals(that.literal);
}
@Override
public int hashCode() {
return literal.hashCode();
}
}
public static final class Class extends PType {
@@ -125,6 +136,19 @@ public abstract class PType implements Serializable {
}
return result;
}
@Override
public boolean equals(@org.jspecify.annotations.Nullable Object obj) {
if (obj == this) return true;
return obj instanceof Class that
&& pClass.equals(that.pClass)
&& typeArguments.equals(that.typeArguments);
}
@Override
public int hashCode() {
return 31 * pClass.hashCode() + typeArguments.hashCode();
}
}
public static final class Nullable extends PType {
@@ -146,6 +170,17 @@ public abstract class PType implements Serializable {
? "(" + baseType + ")?"
: baseType + "?";
}
@Override
public boolean equals(@org.jspecify.annotations.Nullable Object obj) {
if (obj == this) return true;
return obj instanceof Nullable that && baseType.equals(that.baseType);
}
@Override
public int hashCode() {
return baseType.hashCode();
}
}
public static final class Constrained extends PType {
@@ -176,6 +211,19 @@ public abstract class PType implements Serializable {
+ String.join(", ", constraints)
+ ")";
}
@Override
public boolean equals(@org.jspecify.annotations.Nullable Object obj) {
if (obj == this) return true;
return obj instanceof Constrained that
&& baseType.equals(that.baseType)
&& constraints.equals(that.constraints);
}
@Override
public int hashCode() {
return 31 * baseType.hashCode() + constraints.hashCode();
}
}
public static final class Alias extends PType {
@@ -223,6 +271,19 @@ public abstract class PType implements Serializable {
}
return result;
}
@Override
public boolean equals(@org.jspecify.annotations.Nullable Object obj) {
if (obj == this) return true;
return obj instanceof Alias that
&& typeAlias.equals(that.typeAlias)
&& typeArguments.equals(that.typeArguments);
}
@Override
public int hashCode() {
return 31 * typeAlias.hashCode() + typeArguments.hashCode();
}
}
public static final class Function extends PType {
@@ -251,6 +312,19 @@ public abstract class PType implements Serializable {
+ ") -> "
+ returnType;
}
@Override
public boolean equals(@org.jspecify.annotations.Nullable Object obj) {
if (obj == this) return true;
return obj instanceof Function that
&& parameterTypes.equals(that.parameterTypes)
&& returnType.equals(that.returnType);
}
@Override
public int hashCode() {
return 31 * parameterTypes.hashCode() + returnType.hashCode();
}
}
public static final class Union extends PType {
@@ -270,6 +344,17 @@ public abstract class PType implements Serializable {
public String toString() {
return elementTypes.stream().map(Object::toString).collect(Collectors.joining(" | "));
}
@Override
public boolean equals(@org.jspecify.annotations.Nullable Object obj) {
if (obj == this) return true;
return obj instanceof Union that && elementTypes.equals(that.elementTypes);
}
@Override
public int hashCode() {
return elementTypes.hashCode();
}
}
public static final class TypeVariable extends PType {
@@ -293,5 +378,16 @@ public abstract class PType implements Serializable {
public String toString() {
return typeParameter.getName();
}
@Override
public boolean equals(@org.jspecify.annotations.Nullable Object obj) {
if (obj == this) return true;
return obj instanceof TypeVariable that && typeParameter.equals(that.typeParameter);
}
@Override
public int hashCode() {
return typeParameter.hashCode();
}
}
}
@@ -0,0 +1,55 @@
amends "../snippetTest.pkl"
import "pkl:ref"
local class D extends ref.Domain {
function renderReference(reference: ref.Reference<D, Any>): String = reference.getData().toString()
}
local const d: D = new {}
local typealias Ref<T> = ref.Reference<D, T>
local class Holder {
num: Int
text: String
lit: "literal"
small: Int8
optional: Mapping<String, Int?>
listing: Listing<Int>
union: Listing<String> | Listing<Int>
}
local const h: Holder = new {
num = 1
text = "t"
lit = "literal"
small = 8
optional { ["k"] = 5 }
listing { 1; 2 }
union = new Listing<Int> { 1 }
}
local hRef1: Ref<Holder> = ref.Reference(d, Holder, h)
local hRef2: Ref<Holder> = ref.Reference(d, Holder, h)
facts {
["equality"] {
hRef1 == hRef2
hRef1.num == hRef2.num
hRef1.lit == hRef2.lit
hRef1.small == hRef2.small
hRef1.optional["k"] == hRef2.optional["k"]
hRef1.listing[0] == hRef2.listing[0]
hRef1.union == hRef2.union
}
["inequality"] {
hRef1.num != hRef2.text
}
["set deduplication"] {
Set(hRef1.num, hRef2.num).length == 1
Set(hRef1.union, hRef2.union).length == 1
Set(hRef1.num, hRef2.text).length == 2
}
}
@@ -0,0 +1,19 @@
facts {
["equality"] {
true
true
true
true
true
true
true
}
["inequality"] {
true
}
["set deduplication"] {
true
true
true
}
}