GROOVY-6175: invoking memoized closure property as method fails (closes #462)

Per the Closure class docs, to be able to use a Closure in short form, e.g., 
c(), in subclasses, you need to provide a doCall method with any signature you 
want to, if no doCall method is provided a closure must be used in its long 
form, e.g., c.call().


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

Branch: refs/heads/parrot
Commit: 84cffe08baf778a721c170675f3b1af385e08593
Parents: e3a9806
Author: John Wagenleitner <jwagenleit...@apache.org>
Authored: Wed Nov 23 20:52:31 2016 -0800
Committer: John Wagenleitner <jwagenleit...@apache.org>
Committed: Wed Nov 23 21:15:55 2016 -0800

----------------------------------------------------------------------
 .../groovy/runtime/memoize/Memoize.java         |  4 ++
 .../groovy/runtime/memoize/MemoizeTest.groovy   | 54 +++++++++++++++++++-
 2 files changed, 56 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/84cffe08/src/main/org/codehaus/groovy/runtime/memoize/Memoize.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/memoize/Memoize.java 
b/src/main/org/codehaus/groovy/runtime/memoize/Memoize.java
index 544e06c..c4dd3d9 100644
--- a/src/main/org/codehaus/groovy/runtime/memoize/Memoize.java
+++ b/src/main/org/codehaus/groovy/runtime/memoize/Memoize.java
@@ -137,6 +137,10 @@ public abstract class Memoize {
             }
             return result == MEMOIZE_NULL ? null : (V) result;
         }
+
+        public V doCall(final Object... args) {
+            return call(args);
+        }
     }
     
     private static class SoftReferenceMemoizeFunction<V> extends 
MemoizeFunction<V> {

http://git-wip-us.apache.org/repos/asf/groovy/blob/84cffe08/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy 
b/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy
index 8bc50d4..5c80530 100644
--- a/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy
+++ b/src/test/org/codehaus/groovy/runtime/memoize/MemoizeTest.groovy
@@ -63,10 +63,12 @@ public class MemoizeTest extends AbstractMemoizeTestCase {
         assert timesMethodBodyExecuted == 1
 
         timesMethodBodyExecuted = 0
-        lst.metaClass.getUsersByDeptAndMgrId = { String dept, int id ->
+        def code = { String dept, int id ->
             ++timesMethodBodyExecuted
             [dept, "${id}"]
-        }.memoize()
+        }
+
+        lst.metaClass.getUsersByDeptAndMgrId = code.memoize()
 
         assert lst.getUsersByDeptAndMgrId('123', 555) == ['123', '555']
         assert lst.getUsersByDeptAndMgrId('456', 999) == ['456', '999']
@@ -80,5 +82,53 @@ public class MemoizeTest extends AbstractMemoizeTestCase {
         assert lst.getUsersByDeptAndMgrId('456', 999) == ['456', '999']
 
         assert timesMethodBodyExecuted == 2
+
+        // test SoftReferenceMemoizeFunction
+        lst.metaClass.getUsersByDeptAndMgrId = code.memoizeAtLeast(4)
+
+        assert lst.getUsersByDeptAndMgrId('123', 555) == ['123', '555']
+        assert lst.getUsersByDeptAndMgrId('456', 999) == ['456', '999']
+
+        assert lst.getUsersByDeptAndMgrId('123', 555) == ['123', '555']
+        assert lst.getUsersByDeptAndMgrId('456', 999) == ['456', '999']
+
+        assert timesMethodBodyExecuted == 4
+    }
+
+    void testMemoizeClosureParameters() {
+        def clo = { String a, Date b, c -> 42 }.memoize()
+        assert clo.maximumNumberOfParameters == 3
+        assert clo.parameterTypes[0] == String
+        assert clo.parameterTypes[1] == Date
+        assert clo.parameterTypes[2] == Object
+
+        // test SoftReferenceMemoizeFunction
+        clo = { String a, Date b, c -> 42 }.memoizeAtLeast(2)
+        assert clo.maximumNumberOfParameters == 3
+        assert clo.parameterTypes[0] == String
+        assert clo.parameterTypes[1] == Date
+        assert clo.parameterTypes[2] == Object
+    }
+
+    // GROOVY-6175
+    void testMemoizeClosureAsProperty() {
+        def c = new ClassWithMemoizeClosureProperty();
+
+        assert c.mc() == 1
+        assert c.mc() == 1
+
+        assert c.mcSoftRef() == 1
+        assert c.mcSoftRef() == 1
+    }
+
+    private static class ClassWithMemoizeClosureProperty {
+        int timesCalled, timesCalledSoftRef
+        def mc = {
+            ++timesCalled
+        }.memoize()
+
+        def mcSoftRef = {
+            ++timesCalledSoftRef
+        }.memoizeAtLeast(4)
     }
 }

Reply via email to