Created
September 14, 2015 08:55
-
-
Save melix/0191b27de0ef9bf8f71f to your computer and use it in GitHub Desktop.
Support for instance method references
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: src/main/org/codehaus/groovy/runtime/MethodClosure.java | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
--- src/main/org/codehaus/groovy/runtime/MethodClosure.java (revision Local version) | |
+++ src/main/org/codehaus/groovy/runtime/MethodClosure.java (revision Shelved version) | |
@@ -19,8 +19,8 @@ | |
package org.codehaus.groovy.runtime; | |
import groovy.lang.Closure; | |
+import groovy.lang.MetaClass; | |
import groovy.lang.MetaMethod; | |
- | |
import java.util.List; | |
@@ -31,24 +31,31 @@ | |
* @author <a href="mailto:[email protected]">James Strachan</a> | |
*/ | |
public class MethodClosure extends Closure { | |
+ private final static Class[] EMPTY_CLASS_ARRAY = new Class[0]; | |
public static boolean ALLOW_RESOLVE = false; | |
private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; | |
- private String method; | |
+ private final Object owner; | |
+ private final String method; | |
+ private final boolean classReceiver; | |
public MethodClosure(Object owner, String method) { | |
super(owner); | |
this.method = method; | |
+ this.owner = owner; | |
- final Class clazz = owner.getClass()==Class.class?(Class) owner:owner.getClass(); | |
+ classReceiver = owner.getClass() == Class.class; | |
+ Class clazz = classReceiver ?(Class) owner:owner.getClass(); | |
maximumNumberOfParameters = 0; | |
parameterTypes = EMPTY_CLASS_ARRAY; | |
- List<MetaMethod> methods = InvokerHelper.getMetaClass(clazz).respondsTo(owner, method); | |
+ MetaClass ownerMetaClass = InvokerHelper.getMetaClass(clazz); | |
+ List<MetaMethod> methods = ownerMetaClass.respondsTo(owner, method); | |
for(MetaMethod m : methods) { | |
+ if (classReceiver && !m.isStatic()) continue; | |
if (m.getParameterTypes().length > maximumNumberOfParameters) { | |
Class[] pt = m.getNativeParameterTypes(); | |
maximumNumberOfParameters = pt.length; | |
@@ -56,13 +63,27 @@ | |
} | |
} | |
} | |
- | |
+ | |
public String getMethod() { | |
return method; | |
} | |
protected Object doCall(Object arguments) { | |
- return InvokerHelper.invokeMethod(getOwner(), method, arguments); | |
+ return InvokerHelper.invokeMethod(owner, method, arguments); | |
+ } | |
+ | |
+ @Override | |
+ public Object call(final Object... args) { | |
+ if (parameterTypes == EMPTY_CLASS_ARRAY && classReceiver && args.length > 0 && args[0].getClass() == owner) { | |
+ // support String.&toUpperCase style method closures | |
+ // This implementation is limited to unambiguous cases in order to avoid relying on catching a | |
+ // MissingMethodException then potentially rethrowing it | |
+ Object instanceReceiver = args[0]; | |
+ Object[] argsLeft = new Object[args.length - 1]; | |
+ System.arraycopy(args, 1, argsLeft, 0, argsLeft.length); | |
+ return InvokerHelper.invokeMethod(instanceReceiver, method, argsLeft); | |
+ } | |
+ return super.call(args); | |
} | |
private Object readResolve() { | |
@@ -71,7 +92,7 @@ | |
} | |
throw new UnsupportedOperationException(); | |
} | |
- | |
+ | |
public Object getProperty(String property) { | |
if ("method".equals(property)) { | |
return getMethod(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment