Repository: groovy Updated Branches: refs/heads/master 4da8d37d0 -> f9656fb23
Minor refactoring Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/f9656fb2 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/f9656fb2 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/f9656fb2 Branch: refs/heads/master Commit: f9656fb233d7545b7574b6e5019a0736aa0d2845 Parents: 4da8d37 Author: sunlan <[email protected]> Authored: Thu Nov 30 13:35:15 2017 +0800 Committer: sunlan <[email protected]> Committed: Thu Nov 30 13:35:15 2017 +0800 ---------------------------------------------------------------------- src/main/groovy/lang/MetaClassImpl.java | 52 +++++++++++++------- .../runtime/metaclass/ClosureMetaClass.java | 41 +-------------- 2 files changed, 34 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/f9656fb2/src/main/groovy/lang/MetaClassImpl.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/MetaClassImpl.java b/src/main/groovy/lang/MetaClassImpl.java index f76a0b2..d60f252 100644 --- a/src/main/groovy/lang/MetaClassImpl.java +++ b/src/main/groovy/lang/MetaClassImpl.java @@ -3310,43 +3310,57 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass { private Object chooseMostSpecificParams(String name, List matchingMethods, Class[] arguments) { + return doChooseMostSpecificParams(theClass.getName(), name, matchingMethods, arguments, false); + } + protected static Object doChooseMostSpecificParams(String theClassName, String name, List matchingMethods, Class[] arguments, boolean checkParametersCompatible) { long matchesDistance = -1; LinkedList matches = new LinkedList(); for (Object method : matchingMethods) { - ParameterTypes paramTypes = (ParameterTypes) method; - long dist = MetaClassHelper.calculateParameterDistance(arguments, paramTypes); + final ParameterTypes parameterTypes = (ParameterTypes) method; + if (checkParametersCompatible && !MetaClassHelper.parametersAreCompatible(arguments, parameterTypes.getNativeParameterTypes())) continue; + long dist = MetaClassHelper.calculateParameterDistance(arguments, parameterTypes); if (dist == 0) return method; - if (matches.isEmpty()) { - matches.add(method); - matchesDistance = dist; - } else if (dist < matchesDistance) { - matchesDistance = dist; - matches.clear(); - matches.add(method); - } else if (dist == matchesDistance) { - matches.add(method); - } - + matchesDistance = handleMatches(matchesDistance, matches, method, dist); } - if (matches.size() == 1) { + + int size = matches.size(); + if (1 == size) { return matches.getFirst(); } - if (matches.isEmpty()) { + if (0 == size) { return null; } //more than one matching method found --> ambiguous! + throw new GroovyRuntimeException(createErrorMessageForAmbiguity(theClassName, name, arguments, matches)); + } + + protected static String createErrorMessageForAmbiguity(String theClassName, String name, Class[] arguments, LinkedList matches) { StringBuilder msg = new StringBuilder("Ambiguous method overloading for method "); - msg.append(theClass.getName()).append("#").append(name) + msg.append(theClassName).append("#").append(name) .append(".\nCannot resolve which method to invoke for ") .append(InvokerHelper.toString(arguments)) .append(" due to overlapping prototypes between:"); - for (final Object matche : matches) { - Class[] types = ((ParameterTypes) matche).getNativeParameterTypes(); + for (final Object match : matches) { + CachedClass[] types = ((ParameterTypes) match).getParameterTypes(); msg.append("\n\t").append(InvokerHelper.toString(types)); } - throw new GroovyRuntimeException(msg.toString()); + return msg.toString(); + } + + protected static long handleMatches(long matchesDistance, LinkedList matches, Object method, long dist) { + if (matches.isEmpty()) { + matches.add(method); + matchesDistance = dist; + } else if (dist < matchesDistance) { + matchesDistance = dist; + matches.clear(); + matches.add(method); + } else if (dist == matchesDistance) { + matches.add(method); + } + return matchesDistance; } private static boolean isGenericGetMethod(MetaMethod method) { http://git-wip-us.apache.org/repos/asf/groovy/blob/f9656fb2/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 d7383f2..c418392 100644 --- a/src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java +++ b/src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java @@ -168,49 +168,10 @@ public final class ClosureMetaClass extends MetaClassImpl { } private Object chooseMostSpecificParams(String name, List matchingMethods, Class[] arguments) { - long matchesDistance = -1; - LinkedList matches = new LinkedList(); - for (Iterator iter = matchingMethods.iterator(); iter.hasNext();) { - Object method = iter.next(); - final ParameterTypes parameterTypes = (ParameterTypes) method; - Class[] paramTypes = parameterTypes.getNativeParameterTypes(); - if (!MetaClassHelper.parametersAreCompatible(arguments, paramTypes)) continue; - long dist = MetaClassHelper.calculateParameterDistance(arguments, parameterTypes); - if (dist == 0) return method; - if (matches.isEmpty()) { - matches.add(method); - matchesDistance = dist; - } else if (dist < matchesDistance) { - matchesDistance = dist; - matches.clear(); - matches.add(method); - } else if (dist == matchesDistance) { - matches.add(method); - } - - } - if (matches.size() == 1) { - return matches.getFirst(); - } - if (matches.isEmpty()) { - return null; - } - - // more than one matching method found --> ambiguous! - String msg = "Ambiguous method overloading for method "; - msg += theClass.getName() + "#" + name; - msg += ".\nCannot resolve which method to invoke for "; - msg += InvokerHelper.toString(arguments); - msg += " due to overlapping prototypes between:"; - for (Object match : matches) { - CachedClass[] types = ((ParameterTypes) match).getParameterTypes(); - msg += "\n\t" + InvokerHelper.toString(types); - } - throw new GroovyRuntimeException(msg); + return doChooseMostSpecificParams(theClass.getName(), name, matchingMethods, arguments, true); } } - public ClosureMetaClass(MetaClassRegistry registry, Class theClass) { super(registry, theClass); }
