Repository: groovy Updated Branches: refs/heads/master f9656fb23 -> 4b249700e
Minor refactoring Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/4b249700 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/4b249700 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/4b249700 Branch: refs/heads/master Commit: 4b249700e194cb8d2ae1c71416587f9f14e99180 Parents: f9656fb Author: sunlan <[email protected]> Authored: Thu Nov 30 14:45:23 2017 +0800 Committer: sunlan <[email protected]> Committed: Thu Nov 30 14:45:23 2017 +0800 ---------------------------------------------------------------------- src/main/groovy/lang/MetaClassImpl.java | 27 +-- .../runtime/metaclass/ClosureMetaClass.java | 166 +++++++++---------- 2 files changed, 93 insertions(+), 100 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/4b249700/src/main/groovy/lang/MetaClassImpl.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/MetaClassImpl.java b/src/main/groovy/lang/MetaClassImpl.java index d60f252..af984c9 100644 --- a/src/main/groovy/lang/MetaClassImpl.java +++ b/src/main/groovy/lang/MetaClassImpl.java @@ -1306,21 +1306,26 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass { MetaMethod method = null; if (arguments.length == 1 && arguments[0] instanceof List) { Object[] newArguments = ((List) arguments[0]).toArray(); - method = getMethodWithCaching(sender, methodName, newArguments, isCallToSuper); - if (method != null) { - method = new TransformMetaMethod(method) { - public Object invoke(Object object, Object[] arguments) { - Object firstArgument = arguments[0]; - List list = (List) firstArgument; - arguments = list.toArray(); - return super.invoke(object, arguments); - } - }; - } + method = createTransformMetaMethod(getMethodWithCaching(sender, methodName, newArguments, isCallToSuper)); } return method; } + protected MetaMethod createTransformMetaMethod(MetaMethod method) { + if (method == null) { + return null; + } + + return new TransformMetaMethod(method) { + public Object invoke(Object object, Object[] arguments) { + Object firstArgument = arguments[0]; + List list = (List) firstArgument; + arguments = list.toArray(); + return super.invoke(object, arguments); + } + }; + } + private Object invokePropertyOrMissing(Object object, String methodName, Object[] originalArguments, boolean fromInsideClass, boolean isCallToSuper) { // if no method was found, try to find a closure defined as a field of the class and run it Object value = null; http://git-wip-us.apache.org/repos/asf/groovy/blob/4b249700/src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java b/src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java index c418392..1a59c0b 100644 --- a/src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java +++ b/src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java @@ -47,7 +47,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -147,10 +146,8 @@ public final class ClosureMetaClass extends MetaClassImpl { return MetaClassHelper.chooseMostGeneralMethodWith1NullParam(methods); } else { List matchingMethods = new ArrayList(); - - final int len = methods.size(); final Object[] data = methods.getArray(); - for (int i = 0; i != len; ++i) { + for (int i = 0, len = methods.size(); i != len; ++i) { Object method = data[i]; // making this false helps find matches @@ -158,11 +155,14 @@ public final class ClosureMetaClass extends MetaClassImpl { matchingMethods.add(method); } } - if (matchingMethods.isEmpty()) { + + int size = matchingMethods.size(); + if (0 == size) { return null; - } else if (matchingMethods.size() == 1) { + } else if (1 == size) { return matchingMethods.get(0); } + return chooseMostSpecificParams(CLOSURE_DO_CALL_METHOD, matchingMethods, arguments); } } @@ -251,17 +251,7 @@ public final class ClosureMetaClass extends MetaClassImpl { if (method == null && arguments.length == 1 && arguments[0] instanceof List) { Object[] newArguments = ((List) arguments[0]).toArray(); Class[] newArgClasses = MetaClassHelper.convertToTypeArray(newArguments); - method = pickClosureMethod(newArgClasses); - if (method != null) { - method = new TransformMetaMethod(method) { - public Object invoke(Object object, Object[] arguments) { - Object firstArgument = arguments[0]; - List list = (List) firstArgument; - arguments = list.toArray(); - return super.invoke(object, arguments); - } - }; - } + method = createTransformMetaMethod(pickClosureMethod(newArgClasses)); } if (method == null) throw new MissingMethodException(methodName, theClass, arguments, false); } @@ -275,84 +265,82 @@ public final class ClosureMetaClass extends MetaClassImpl { MissingMethodException last = null; Object callObject = object; - if (method == null) { - final Object owner = closure.getOwner(); - final Object delegate = closure.getDelegate(); - final Object thisObject = closure.getThisObject(); - final int resolveStrategy = closure.getResolveStrategy(); - boolean invokeOnDelegate = false; - boolean invokeOnOwner = false; - boolean ownerFirst = true; - - switch (resolveStrategy) { - case Closure.TO_SELF: - break; - case Closure.DELEGATE_ONLY: - method = getDelegateMethod(closure, delegate, methodName, argClasses); - callObject = delegate; - if (method == null) { - invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject); - } - break; - case Closure.OWNER_ONLY: + final Object owner = closure.getOwner(); + final Object delegate = closure.getDelegate(); + final Object thisObject = closure.getThisObject(); + final int resolveStrategy = closure.getResolveStrategy(); + boolean invokeOnDelegate = false; + boolean invokeOnOwner = false; + boolean ownerFirst = true; + + switch (resolveStrategy) { + case Closure.TO_SELF: + break; + case Closure.DELEGATE_ONLY: + method = getDelegateMethod(closure, delegate, methodName, argClasses); + callObject = delegate; + if (method == null) { + invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject); + } + break; + case Closure.OWNER_ONLY: + method = getDelegateMethod(closure, owner, methodName, argClasses); + callObject = owner; + if (method == null) { + invokeOnOwner = owner != closure && (owner instanceof GroovyObject); + } + + break; + case Closure.DELEGATE_FIRST: + method = getDelegateMethod(closure, delegate, methodName, argClasses); + callObject = delegate; + if (method == null) { method = getDelegateMethod(closure, owner, methodName, argClasses); callObject = owner; - if (method == null) { - invokeOnOwner = owner != closure && (owner instanceof GroovyObject); - } - - break; - case Closure.DELEGATE_FIRST: - method = getDelegateMethod(closure, delegate, methodName, argClasses); - callObject = delegate; - if (method == null) { - method = getDelegateMethod(closure, owner, methodName, argClasses); - callObject = owner; - } - if (method == null) { - invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject); - invokeOnOwner = owner != closure && (owner instanceof GroovyObject); - ownerFirst = false; + } + if (method == null) { + invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject); + invokeOnOwner = owner != closure && (owner instanceof GroovyObject); + ownerFirst = false; + } + break; + default: // owner first + // owner first means we start with the outer most owner that is not a generated closure + // this owner is equal to the this object, so we check that one first. + method = getDelegateMethod(closure, thisObject, methodName, argClasses); + callObject = thisObject; + if (method == null) { + // try finding a delegate that has that method... we start from + // outside building a stack and try each delegate + LinkedList list = new LinkedList(); + for (Object current = closure; current != thisObject;) { + if (!(current instanceof Closure)) break; + Closure currentClosure = (Closure) current; + if (currentClosure.getDelegate() != null) list.add(current); + current = currentClosure.getOwner(); } - break; - default: // owner first - // owner first means we start with the outer most owner that is not a generated closure - // this owner is equal to the this object, so we check that one first. - method = getDelegateMethod(closure, thisObject, methodName, argClasses); - callObject = thisObject; - if (method == null) { - // try finding a delegate that has that method... we start from - // outside building a stack and try each delegate - LinkedList list = new LinkedList(); - for (Object current = closure; current != thisObject;) { - if (!(current instanceof Closure)) break; - Closure currentClosure = (Closure) current; - if (currentClosure.getDelegate() != null) list.add(current); - current = currentClosure.getOwner(); - } - while (!list.isEmpty() && method == null) { - Closure closureWithDelegate = (Closure) list.removeLast(); - Object currentDelegate = closureWithDelegate.getDelegate(); - method = getDelegateMethod(closureWithDelegate, currentDelegate, methodName, argClasses); - callObject = currentDelegate; - } - } - if (method == null) { - invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject); - invokeOnOwner = owner != closure && (owner instanceof GroovyObject); - } - } - if (method == null && (invokeOnOwner || invokeOnDelegate)) { - try { - if (ownerFirst) { - return invokeOnDelegationObjects(invokeOnOwner, owner, invokeOnDelegate, delegate, methodName, arguments); - } else { - return invokeOnDelegationObjects(invokeOnDelegate, delegate, invokeOnOwner, owner, methodName, arguments); + while (!list.isEmpty() && method == null) { + Closure closureWithDelegate = (Closure) list.removeLast(); + Object currentDelegate = closureWithDelegate.getDelegate(); + method = getDelegateMethod(closureWithDelegate, currentDelegate, methodName, argClasses); + callObject = currentDelegate; } - } catch (MissingMethodException mme) { - last = mme; } + if (method == null) { + invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject); + invokeOnOwner = owner != closure && (owner instanceof GroovyObject); + } + } + if (method == null && (invokeOnOwner || invokeOnDelegate)) { + try { + if (ownerFirst) { + return invokeOnDelegationObjects(invokeOnOwner, owner, invokeOnDelegate, delegate, methodName, arguments); + } else { + return invokeOnDelegationObjects(invokeOnDelegate, delegate, invokeOnOwner, owner, methodName, arguments); + } + } catch (MissingMethodException mme) { + last = mme; } }
