From 5893841f90154984a8d209909986e691dab49d5e Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Tue, 7 Jan 2025 11:19:11 +0100 Subject: [PATCH] compareTo must implement a total ordering to be useful in Arrays.sort --- .../java/io/usethesource/vallang/type/Type.java | 17 +++++++++++++---- .../vallang/specification/TypeTest.java | 8 ++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/io/usethesource/vallang/type/Type.java b/src/main/java/io/usethesource/vallang/type/Type.java index 404c7d38..7eb05b12 100644 --- a/src/main/java/io/usethesource/vallang/type/Type.java +++ b/src/main/java/io/usethesource/vallang/type/Type.java @@ -637,28 +637,37 @@ public Type getTypeParameters() { } /** - * Compare against another type. + * Compare against another type, implementing a _total_ ordering for use in + * sorting operations. After sorting with this comparator, candidate matches + * are ordered by specificity (smaller types first). A total ordering is a + * precondition to using Arrays.sort(Comparator) and List.sort(Comparator). * - * A type is 'less' than another if it is a subtype, 'greater' if the other is + * First: a type is 'less' than another if it is a subtype, 'greater' if the other is * a subtype, or 'equal' if both are subtypes of each other. + * Second: If types are not comparable in terms of subtype, we sort them alphabetically + * by their toString() representation. * * Note: this class has a natural ordering that is inconsistent with equals. * equals() on types is exact equality, which may be different from * compareTo(o) == 0 + * Note: subtypes can be expected to be less than supertypes, but + * if a type is less than another, it does not imply a sub-type relation. * * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Type o) { if (isSubtypeOf(o)) { return o.isSubtypeOf(this) - ? 0 + ? toString().compareTo(o.toString()) : -1; } else if (o.isSubtypeOf(this)) { + assert !isSubtypeOf(o); return 1; } else { - return 0; + assert !isSubtypeOf(o) && !o.isSubtypeOf(this); + return toString().compareTo(o.toString()); } } diff --git a/src/test/java/io/usethesource/vallang/specification/TypeTest.java b/src/test/java/io/usethesource/vallang/specification/TypeTest.java index 4ce4c7ec..ad2a6f0a 100644 --- a/src/test/java/io/usethesource/vallang/specification/TypeTest.java +++ b/src/test/java/io/usethesource/vallang/specification/TypeTest.java @@ -67,7 +67,7 @@ public void compareTo(Type t, Type u) { assertTrue(t.compareTo(u) == -1); } else { - assertTrue(t.compareTo(u) == 0); + assertTrue(t.compareTo(u) == t.toString().compareTo(u.toString())); } } else if (u.isSubtypeOf(t)) { @@ -75,12 +75,12 @@ else if (u.isSubtypeOf(t)) { assertTrue(t.compareTo(u) == 1); } else { - assertTrue(t.compareTo(u) == 0); + assertTrue(t.compareTo(u) == t.toString().compareTo(u.toString())); } } else { - assertTrue(t.compareTo(u) == 0); - assertTrue(u.compareTo(t) == 0); + assertTrue(t.compareTo(u) == t.toString().compareTo(u.toString())); + assertTrue(u.compareTo(t) == u.toString().compareTo(t.toString())); } }