You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2020/05/18 04:10:50 UTC

[groovy] branch GROOVY_2_5_X updated: Fix GROOVY-8966 fix NumberRange with getAt (port to 2_5_X)

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
     new 0495ea1  Fix GROOVY-8966 fix NumberRange with getAt (port to 2_5_X)
0495ea1 is described below

commit 0495ea1c6adf16f875c533a11b1974cde3f743b3
Author: Bo Zhang <zh...@gmail.com>
AuthorDate: Wed Jan 15 23:10:13 2020 +0800

    Fix GROOVY-8966 fix NumberRange with getAt (port to 2_5_X)
    
    Previously, when a exclusive NumberRange constructed from non-int type (e.g. long)
    is used in List.getAt(), it will be incorrectly converted to inclusive. This commit
    fixes this issue by introducing a subListBorders() method to NumberRange, which is
    similar to IntRange.
    
    (cherry picked from commit a46c601eadf6b06a850a8a6e27dda8d35c7263d4)
---
 src/main/groovy/groovy/lang/IntRange.java               |  4 ++++
 src/main/groovy/groovy/lang/NumberRange.java            | 15 +++++++++++++++
 .../groovy/runtime/DefaultGroovyMethodsSupport.java     |  6 +++++-
 src/test/groovy/bugs/groovy8966/Groovy8966.groovy       | 17 +++++++++++++++++
 4 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/main/groovy/groovy/lang/IntRange.java b/src/main/groovy/groovy/lang/IntRange.java
index 79a57b0..da11291 100644
--- a/src/main/groovy/groovy/lang/IntRange.java
+++ b/src/main/groovy/groovy/lang/IntRange.java
@@ -219,6 +219,10 @@ public class IntRange extends AbstractList<Integer> implements Range<Integer> {
         if (inclusive == null) {
             throw new IllegalStateException("Should not call subListBorders on a non-inclusive aware IntRange");
         }
+        return subListBorders(from, to, inclusive, size);
+    }
+
+    static RangeInfo subListBorders(int from, int to, boolean inclusive, int size) {
         int tempFrom = from;
         if (tempFrom < 0) {
             tempFrom += size;
diff --git a/src/main/groovy/groovy/lang/NumberRange.java b/src/main/groovy/groovy/lang/NumberRange.java
index 52ef856..7b9c0e3 100644
--- a/src/main/groovy/groovy/lang/NumberRange.java
+++ b/src/main/groovy/groovy/lang/NumberRange.java
@@ -21,6 +21,7 @@ package groovy.lang;
 
 import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.runtime.IteratorClosureAdapter;
+import org.codehaus.groovy.runtime.RangeInfo;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -177,6 +178,20 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
     }
 
     /**
+     * A method for determining from and to information when using this IntRange to index an aggregate object of the specified size.
+     * Normally only used internally within Groovy but useful if adding range indexing support for your own aggregates.
+     *
+     * @param size the size of the aggregate being indexed
+     * @return the calculated range information (with 1 added to the to value, ready for providing to subList
+     */
+    public RangeInfo subListBorders(int size) {
+        if (stepSize.intValue() != 1) {
+            throw new IllegalStateException("Step must be 1 when used by subList!");
+        }
+        return IntRange.subListBorders(((Number) from).intValue(), ((Number) to).intValue(), inclusive, size);
+    }
+
+    /**
      * For a NumberRange with step size 1, creates a new NumberRange with the same
      * <code>from</code> and <code>to</code> as this NumberRange
      * but with a step size of <code>stepSize</code>.
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
index 3838fdc..afb3d81 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
@@ -20,6 +20,7 @@ package org.codehaus.groovy.runtime;
 
 import groovy.lang.EmptyRange;
 import groovy.lang.IntRange;
+import groovy.lang.NumberRange;
 import groovy.lang.Range;
 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
 
@@ -73,7 +74,10 @@ public class DefaultGroovyMethodsSupport {
     // helper method for getAt and putAt
     protected static RangeInfo subListBorders(int size, Range range) {
         if (range instanceof IntRange) {
-            return ((IntRange)range).subListBorders(size);
+            return ((IntRange) range).subListBorders(size);
+        }
+        if (range instanceof NumberRange) {
+            return ((NumberRange) range).subListBorders(size);
         }
         int from = normaliseIndex(DefaultTypeTransformation.intUnbox(range.getFrom()), size);
         int to = normaliseIndex(DefaultTypeTransformation.intUnbox(range.getTo()), size);
diff --git a/src/test/groovy/bugs/groovy8966/Groovy8966.groovy b/src/test/groovy/bugs/groovy8966/Groovy8966.groovy
new file mode 100644
index 0000000..bc65eab
--- /dev/null
+++ b/src/test/groovy/bugs/groovy8966/Groovy8966.groovy
@@ -0,0 +1,17 @@
+package groovy.bugs.groovy8966
+
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+@CompileStatic
+final class Groovy8966 extends GroovyTestCase {
+    @Test
+    void test() {
+        assertScript '''
+            def array = [0, 1, 2]
+            int a = 2
+            long b = 3
+            assert array[a..<b] == [2]
+        '''
+    }
+}
\ No newline at end of file