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) } }