Repository: groovy
Updated Branches:
  refs/heads/master 2fb0075b6 -> 268b202b9


GROOVY-6396: same linkedlist code different behavior between groovy and java 
(closes #419)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/1c22fb31
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/1c22fb31
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/1c22fb31

Branch: refs/heads/master
Commit: 1c22fb31cc79dd01a4b5ffb973c415df0ed13a1a
Parents: 2fb0075
Author: paulk <pa...@asert.com.au>
Authored: Tue Sep 13 19:40:31 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Mon Sep 19 07:30:29 2016 +1000

----------------------------------------------------------------------
 .../groovy/runtime/DefaultGroovyMethods.java    | 55 +++++++++++++++-----
 src/test/groovy/ListTest.groovy                 | 11 ++--
 src/test/groovy/bugs/Groovy6396Bug.groovy       | 33 ++++++++++++
 .../tailrec/RecursiveListExamples.groovy        |  2 +-
 .../tailrec/TailRecursiveExamples.groovy        |  2 +-
 5 files changed, 85 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/1c22fb31/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java 
b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 4cc5e9b..b37e32a 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -8928,11 +8928,15 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Removes the last item from the List. Using add() and pop()
-     * is similar to push and pop on a Stack.
-     * <pre class="groovyTestCase">def list = ["a", false, 2]
-     * assert list.pop() == 2
-     * assert list == ["a", false]</pre>
+     * Removes the initial item from the List, similar to pop on a Stack.
+     * <pre class="groovyTestCase">
+     * def list = ["a", false, 2]
+     * assert list.pop() == 'a'
+     * assert list == [false, 2]
+     * </pre>
+     *
+     * Note: The behavior of this method changed in Groovy 2.5 to align with 
Java.
+     * If you need the old behavior use 'removeLast'.
      *
      * @param self a List
      * @return the item removed from the List
@@ -8943,6 +8947,27 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
         if (self.isEmpty()) {
             throw new NoSuchElementException("Cannot pop() an empty List");
         }
+        return self.remove(0);
+    }
+
+    /**
+     * Removes the last item from the List. Using add() and pop()
+     * is similar to push and pop on a Stack.
+     * <pre class="groovyTestCase">
+     * def list = ["a", false, 2]
+     * assert list.removeLast() == 2
+     * assert list == ["a", false]
+     * </pre>
+     *
+     * @param self a List
+     * @return the item removed from the List
+     * @throws NoSuchElementException if the list is empty and you try to 
pop() it.
+     * @since 2.5.0
+     */
+    public static <T> T removeLast(List<T> self) {
+        if (self.isEmpty()) {
+            throw new NoSuchElementException("Cannot pop() an empty List");
+        }
         return self.remove(self.size() - 1);
     }
 
@@ -8981,20 +9006,24 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Appends an item to the List. Synonym for add().
-     * <pre class="groovyTestCase">def list = [3, 4, 2]
+     * Prepends an item to the start of the List, similar to push on a stack.
+     * <pre class="groovyTestCase">
+     * def list = [3, 4, 2]
      * list.push("x")
-     * assert list == [3, 4, 2, "x"]</pre>
+     * assert list == ['x', 3, 4, 2]
+     * </pre>
+     *
+     * Note: The behavior of this method changed in Groovy 2.5 to align with 
Java.
+     * If you need the old behavior use 'add'.
      *
      * @param self a List
-     * @param value element to be appended to this list.
-     * @return <tt>true</tt> (as per the general contract of the
-     *            <tt>Collection.add</tt> method).
-     * @throws NoSuchElementException if the list is empty and you try to 
pop() it.
+     * @param value element to be prepended to this list.
+     * @return <tt>true</tt> (for legacy compatibility reasons).
      * @since 1.5.5
      */
     public static <T> boolean push(List<T> self, T value) {
-        return self.add(value);
+        self.add(0, value);
+        return true;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/groovy/blob/1c22fb31/src/test/groovy/ListTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/ListTest.groovy b/src/test/groovy/ListTest.groovy
index 158239d..08fcb77 100644
--- a/src/test/groovy/ListTest.groovy
+++ b/src/test/groovy/ListTest.groovy
@@ -256,15 +256,20 @@ class ListTest extends GroovyTestCase {
     void testPop() {
         def l = []
         l << 'a' << 'b'
-        def value = l.pop()
+        def value = l.removeLast()
         assert value == 'b'
         assert l == ['a']
 
-        l.add('c')
+        l << 'b'
+        value = l.pop()
+        assert value == 'a'
+        assert l == ['b']
+
+        l.push('c')
         value = l.pop()
         assert value == 'c'
         value = l.pop()
-        assert value == 'a'
+        assert value == 'b'
         try {
             l.pop()
             fail("Should have thrown an exception")

http://git-wip-us.apache.org/repos/asf/groovy/blob/1c22fb31/src/test/groovy/bugs/Groovy6396Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy6396Bug.groovy 
b/src/test/groovy/bugs/Groovy6396Bug.groovy
new file mode 100644
index 0000000..dbf944b
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy6396Bug.groovy
@@ -0,0 +1,33 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.bugs
+
+class Groovy6396Bug extends GroovyTestCase {
+    void testClassUsageInInterfaceDef() {
+        assertScript """
+            def stack3 = new LinkedList<String>(['1', '2', '3'])
+            assert stack3.pop() == '1'
+            Deque stack4 = new LinkedList()
+            stack4.push(1)
+            stack4.push(2)
+            assert stack4.peek() == 2
+            assert stack4.pop() == 2
+        """
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/1c22fb31/src/test/org/codehaus/groovy/transform/tailrec/RecursiveListExamples.groovy
----------------------------------------------------------------------
diff --git 
a/src/test/org/codehaus/groovy/transform/tailrec/RecursiveListExamples.groovy 
b/src/test/org/codehaus/groovy/transform/tailrec/RecursiveListExamples.groovy
index 3c7cdbd..3804572 100644
--- 
a/src/test/org/codehaus/groovy/transform/tailrec/RecursiveListExamples.groovy
+++ 
b/src/test/org/codehaus/groovy/transform/tailrec/RecursiveListExamples.groovy
@@ -75,7 +75,7 @@ class RecursiveList {
     static Map rlist(List elements, Map result = empty) {
         if (!elements)
             return result
-        Object head = elements.pop()
+        Object head = elements.removeLast()
         rlist(elements, cons(head, result))
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/1c22fb31/src/test/org/codehaus/groovy/transform/tailrec/TailRecursiveExamples.groovy
----------------------------------------------------------------------
diff --git 
a/src/test/org/codehaus/groovy/transform/tailrec/TailRecursiveExamples.groovy 
b/src/test/org/codehaus/groovy/transform/tailrec/TailRecursiveExamples.groovy
index 8103cb0..7b00bb4 100644
--- 
a/src/test/org/codehaus/groovy/transform/tailrec/TailRecursiveExamples.groovy
+++ 
b/src/test/org/codehaus/groovy/transform/tailrec/TailRecursiveExamples.groovy
@@ -123,7 +123,7 @@ class DynamicTargetClass {
             return result
         else {
             def element = elements.pop()
-            result.add(element)
+            result.push(element)
             return revert(elements, result)
         }
     }

Reply via email to