This is an automated email from the ASF dual-hosted git repository. paulk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/groovy.git
commit f71a1b7366ac304c6b7e1660e5a4a59f83382b6f Author: Esko Toivonen <[email protected]> AuthorDate: Mon Apr 5 14:41:53 2021 +0300 GROOVY-9649: Make createRange aware of left side exclusivity Currently empty ranges are created only when to == from. This is because range indexing in lists behaves differently: while 0<..<-1 would normally be an empty range, we can index into lists with it and expect some output, since negative indices count from the end of the list towards its beginning. Note that while this is true for IntRanges, object ranges like 'a'<..<'b' become EmptyRanges. --- .../groovy/runtime/ScriptBytecodeAdapter.java | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java index 5041862..5161f65 100644 --- a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java +++ b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java @@ -636,28 +636,43 @@ public class ScriptBytecodeAdapter { } public static List createRange(Object from, Object to, boolean exclusiveLeft, boolean exclusiveRight) throws Throwable { - boolean inclusive = !exclusiveRight; if (from instanceof Integer && to instanceof Integer) { int ifrom = (Integer) from; int ito = (Integer) to; - if (inclusive || ifrom != ito) { + if ((!exclusiveLeft && !exclusiveRight) || ifrom != ito) { + // Currently, empty ranges where from != to and the range is full exclusive (e.g. 0<..<-1) are + // constructed as IntRanges. This is because these ranges can still be used to index into lists. return new IntRange(!exclusiveLeft, !exclusiveRight, ifrom, ito); } // else fall through for EmptyRange } - if (!inclusive && compareEqual(from, to)) { + if ((exclusiveLeft || exclusiveRight) && compareEqual(from, to)) { return new EmptyRange((Comparable) from); } if (from instanceof Number && to instanceof Number) { return new NumberRange(comparableNumber((Number) from), comparableNumber((Number) to), !exclusiveLeft, !exclusiveRight); } - if (!inclusive) { - if (compareGreaterThan(from, to)) { + Boolean greater = null; + if (exclusiveRight) { + greater = compareGreaterThan(from, to); + if (greater) { to = invokeMethod0(ScriptBytecodeAdapter.class, to, "next"); } else { to = invokeMethod0(ScriptBytecodeAdapter.class, to, "previous"); } } - + if (exclusiveLeft) { + if (greater == null) { + greater = compareGreaterThan(from, to); + } + if (compareEqual(from, to)) { + return new EmptyRange((Comparable) from); + } + if (greater) { + from = invokeMethod0(ScriptBytecodeAdapter.class, from, "previous"); + } else { + from = invokeMethod0(ScriptBytecodeAdapter.class, from, "next"); + } + } return new ObjectRange((Comparable) from, (Comparable) to); }
