in src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java [763:829]
private static int compareToWithEqualityCheck(Object left, Object right, boolean equalityCheckOnly) {
if (left == right) {
return 0;
} else if (left == null) {
return -1;
} else if (right == null) {
return 1;
}
Exception cause = null;
if (left instanceof Comparable || left instanceof Number) {
if (left instanceof Number) {
if (right instanceof Character || right instanceof Number) {
return DefaultGroovyMethods.compareTo((Number) left, castToNumber(right));
}
if (isValidCharacterString(right)) {
return DefaultGroovyMethods.compareTo((Number) left, ShortTypeHandling.castToChar(right));
}
} else if (left instanceof Character) {
if (isValidCharacterString(right)) {
return DefaultGroovyMethods.compareTo((Character) left, ShortTypeHandling.castToChar(right));
}
if (right instanceof Number) {
return DefaultGroovyMethods.compareTo((Character) left, (Number) right);
}
if (right instanceof String) {
return (left.toString()).compareTo((String) right);
}
if (right instanceof GString) {
return (left.toString()).compareTo(right.toString());
}
} else if (right instanceof Number) {
if (isValidCharacterString(left)) {
return DefaultGroovyMethods.compareTo(ShortTypeHandling.castToChar(left), (Number) right);
}
} else if (left instanceof String && (right instanceof String || right instanceof GString || right instanceof Character)) {
return ((String) left).compareTo(right.toString());
} else if (left instanceof GString && (right instanceof String || right instanceof GString || right instanceof Character)) {
return left.toString().compareTo(right.toString());
}
if (!equalityCheckOnly || left.getClass().isAssignableFrom(right.getClass())
|| (right.getClass() != Object.class && right.getClass().isAssignableFrom(left.getClass()) // GROOVY-4046
|| right instanceof Comparable) // GROOVY-7954
) {
// GROOVY-7876: when comparing for equality we try to only call compareTo when an assignable
// relationship holds but with a container/holder class and because of erasure, we might still end
// up with the prospect of a ClassCastException which we want to ignore but only if testing equality
try {
// GROOVY-9711: don't rely on Java method selection
return (int) InvokerHelper.invokeMethod(left, "compareTo", right);
} catch (ClassCastException cce) {
if (!equalityCheckOnly) cause = cce;
}
}
}
if (equalityCheckOnly) {
return -1; // anything other than 0
}
String message = MessageFormat.format("Cannot compare {0} with value ''{1}'' and {2} with value ''{3}''",
left.getClass().getName(), left, right.getClass().getName(), right);
if (cause != null) {
throw new IllegalArgumentException(message, cause);
} else {
throw new IllegalArgumentException(message);
}
}