You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2023/01/27 12:14:14 UTC
[commons-jexl] branch master updated: JEXL: simplified code for MethodKey, use Executable when possible (base for Method, Constructor)
This is an automated email from the ASF dual-hosted git repository.
henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
The following commit(s) were added to refs/heads/master by this push:
new ed1632be JEXL: simplified code for MethodKey, use Executable when possible (base for Method, Constructor)
ed1632be is described below
commit ed1632befc7db8d5d815d0f64f59efcd472a1bc5
Author: henrib <he...@apache.org>
AuthorDate: Fri Jan 27 13:14:08 2023 +0100
JEXL: simplified code for MethodKey, use Executable when possible (base for Method, Constructor)
---
.../jexl3/internal/introspection/MethodKey.java | 625 +++++++++------------
1 file changed, 281 insertions(+), 344 deletions(-)
diff --git a/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java b/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
index 6695c5cf..cf8473c0 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
@@ -17,6 +17,7 @@
package org.apache.commons.jexl3.internal.introspection;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -89,21 +90,13 @@ public final class MethodKey {
* Creates a key from a method.
* @param aMethod the method to generate the key from.
*/
- MethodKey(final Method aMethod) {
+ MethodKey(final Executable aMethod) {
this(aMethod.getName(), aMethod.getParameterTypes());
}
- /**
- * Creates a key from a constructor.
- * @param aCtor the constructor to generate the key from.
- */
- MethodKey(final Constructor<?> aCtor) {
- this(aCtor.getDeclaringClass().getName(), aCtor.getParameterTypes());
- }
-
/**
* Creates a key from a method name and a set of parameters.
- * @param aMethod the method to generate the key from
+ * @param aMethod the method to generate the key from, class name for constructors
* @param args the intended method parameters
*/
MethodKey(final String aMethod, final Class<?>[] args) {
@@ -187,10 +180,10 @@ public final class MethodKey {
* class introspection order, the isVarargs flag on the method itself will be false.
* To circumvent the potential problem, fetch the method with the same signature from the super-classes,
* - which will be different if override -and get the varargs flag from it.
- * @param method the method to check for varargs
+ * @param method the method or constructor to check for varargs
* @return true if declared varargs, false otherwise
*/
- public static boolean isVarArgs(final Method method) {
+ public static boolean isVarArgs(final Executable method) {
if (method == null) {
return false;
}
@@ -226,7 +219,7 @@ public final class MethodKey {
* @throws MethodKey.AmbiguousException if there is more than one.
*/
public Method getMostSpecificMethod(final Method[] methods) {
- return METHODS.getMostSpecific(this, methods);
+ return getMostSpecific(methods);
}
/**
@@ -236,7 +229,7 @@ public final class MethodKey {
* @throws MethodKey.AmbiguousException if there is more than one.
*/
public Constructor<?> getMostSpecificConstructor(final Constructor<?>[] methods) {
- return CONSTRUCTORS.getMostSpecific(this, methods);
+ return getMostSpecific(methods);
}
/**
@@ -397,7 +390,7 @@ public final class MethodKey {
}
/* Check for vararg conversion. */
if (possibleVarArg && formal.isArray()) {
- if (actual != null && actual.isArray()) {
+ if (actual.isArray()) {
actual = actual.getComponentType();
}
return isInvocationConvertible(formal.getComponentType(), actual, strict, false);
@@ -424,7 +417,7 @@ public final class MethodKey {
* by the introspector.
*/
public static class AmbiguousException extends RuntimeException {
- /** Version Id for serializable. */
+ /** Version identifier for serializable. */
private static final long serialVersionUID = -201801091655L;
/** Whether this exception should be considered severe. */
private final boolean severe;
@@ -449,376 +442,320 @@ public final class MethodKey {
}
/**
- * Utility for parameters matching.
- * @param <T> Method or Constructor
+ * Gets the most specific method that is applicable to actual argument types.<p>
+ * Attempts to find the most specific applicable method using the
+ * algorithm described in the JLS section 15.12.2 (with the exception that it can't
+ * distinguish a primitive type argument from an object type argument, since in reflection
+ * primitive type arguments are represented by their object counterparts, so for an argument of
+ * type (say) java.lang.Integer, it will not be able to decide between a method that takes int and a
+ * method that takes java.lang.Integer as a parameter.
+ * </p>
+ * <p>
+ * This turns out to be a relatively rare case where this is needed - however, functionality
+ * like this is needed.
+ * </p>
+ *
+ * @param methods a list of methods
+ * @return the most specific method.
+ * @throws MethodKey.AmbiguousException if there is more than one.
*/
- private abstract static class Parameters<T> {
- /**
- * Extract the parameter types from its applicable argument.
- * @param app a method or constructor
- * @return the parameters
- */
- protected abstract Class<?>[] getParameterTypes(T app);
-
- /**
- * Whether a constructor or method handles varargs.
- * @param app the constructor or method
- * @return true if varargs, false otherwise
- */
- protected abstract boolean isVarArgs(T app);
-
- /**
- * Gets the most specific method that is applicable to actual argument types.<p>
- * Attempts to find the most specific applicable method using the
- * algorithm described in the JLS section 15.12.2 (with the exception that it can't
- * distinguish a primitive type argument from an object type argument, since in reflection
- * primitive type arguments are represented by their object counterparts, so for an argument of
- * type (say) java.lang.Integer, it will not be able to decide between a method that takes int and a
- * method that takes java.lang.Integer as a parameter.
- * </p>
- * <p>
- * This turns out to be a relatively rare case where this is needed - however, functionality
- * like this is needed.
- * </p>
- *
- * @param key a method key, esp its parameters
- * @param methods a list of methods
- * @return the most specific method.
- * @throws MethodKey.AmbiguousException if there is more than one.
+ private <T extends Executable> T getMostSpecific(final T[] methods) {
+ final Class<?>[] args = getParameters();
+ final Deque<T> applicables = getApplicables(methods, args);
+ if (applicables.isEmpty()) {
+ return null;
+ }
+ if (applicables.size() == 1) {
+ return applicables.getFirst();
+ }
+ /*
+ * This list will contain the maximally specific methods. Hopefully at
+ * the end of the below loop, the list will contain exactly one method,
+ * (the most specific method) otherwise we have ambiguity.
*/
- T getMostSpecific(final MethodKey key, final T[] methods) {
- final Class<?>[] args = key.getParameters();
- final Deque<T> applicables = getApplicables(methods, args);
- if (applicables.isEmpty()) {
- return null;
+ final Deque<T> maximals = new LinkedList<>();
+ for (final T app : applicables) {
+ final Class<?>[] parms = app.getParameterTypes();
+ boolean lessSpecific = false;
+ final Iterator<T> maximal = maximals.iterator();
+ while (!lessSpecific && maximal.hasNext()) {
+ final T max = maximal.next();
+ switch (moreSpecific(args, parms, max.getParameterTypes())) {
+ case MORE_SPECIFIC:
+ /*
+ * This method is more specific than the previously
+ * known maximally specific, so remove the old maximum.
+ */
+ maximal.remove();
+ break;
+ case LESS_SPECIFIC:
+ /*
+ * This method is less specific than any of the
+ * currently known maximally specific methods, so we
+ * won't add it into the set of maximally specific
+ * methods
+ */
+ lessSpecific = true;
+ break;
+ default:
+ // nothing to do
+ }
}
-
- if (applicables.size() == 1) {
- return applicables.getFirst();
+ if (!lessSpecific) {
+ maximals.addLast(app);
}
+ }
+ // if we have more than one maximally specific method, this call is ambiguous...
+ if (maximals.size() > 1) {
+ throw ambiguousException(args, applicables);
+ }
+ return maximals.getFirst();
+ } // CSON: RedundantThrows
- /*
- * This list will contain the maximally specific methods. Hopefully at
- * the end of the below loop, the list will contain exactly one method,
- * (the most specific method) otherwise we have ambiguity.
- */
- final Deque<T> maximals = new LinkedList<>();
- for (final T app : applicables) {
- final Class<?>[] parms = getParameterTypes(app);
- boolean lessSpecific = false;
- final Iterator<T> maximal = maximals.iterator();
- while(!lessSpecific && maximal.hasNext()) {
- final T max = maximal.next();
- switch (moreSpecific(args, parms, getParameterTypes(max))) {
- case MORE_SPECIFIC:
- /*
- * This method is more specific than the previously
- * known maximally specific, so remove the old maximum.
- */
- maximal.remove();
- break;
-
- case LESS_SPECIFIC:
- /*
- * This method is less specific than some of the
- * currently known maximally specific methods, so we
- * won't add it into the set of maximally specific
- * methods
- */
-
- lessSpecific = true;
- break;
- default:
- // nothing to do
+ /**
+ * Creates an ambiguous exception.
+ * <p>
+ * This method computes the severity of the ambiguity. The only <em>non-severe</em> case is when there is
+ * at least one null argument and at most one applicable method or constructor has a corresponding 'Object'
+ * parameter.
+ * We thus consider that ambiguity is benign in presence of null arguments but severe in the case where
+ * the corresponding parameter is of type Object in more than one applicable overloads.
+ * <p>
+ * Rephrasing:
+ * <ul>
+ * <li>If all arguments are valid instances - no null argument -, ambiguity is severe.</li>
+ * <li>If there is at least one null argument, the ambiguity is severe if more than one method has a
+ * corresponding parameter of class 'Object'.</li>
+ * </ul>
+ *
+ * @param classes the argument args
+ * @param applicables the list of applicable methods or constructors
+ * @return an ambiguous exception
+ */
+ private static <T extends Executable>
+ AmbiguousException ambiguousException(final Class<?>[] classes, final Iterable<T> applicables) {
+ boolean severe = false;
+ int instanceArgCount = 0; // count the number of valid instances, aka not null
+ for (int c = 0; c < classes.length; ++c) {
+ final Class<?> argClazz = classes[c];
+ if (Void.class.equals(argClazz)) {
+ // count the number of methods for which the current arg maps to an Object parameter
+ int objectParmCount = 0;
+ for (final T app : applicables) {
+ final Class<?>[] parmClasses = app.getParameterTypes();
+ final Class<?> parmClass = parmClasses[c];
+ if (Object.class.equals(parmClass) && (objectParmCount++ == 2)) {
+ severe = true;
+ break;
}
}
-
- if (!lessSpecific) {
- maximals.addLast(app);
- }
- }
- // if we have more than one maximally specific method, this call is ambiguous...
- if (maximals.size() > 1) {
- throw ambiguousException(args, applicables);
+ } else {
+ instanceArgCount += 1;
}
- return maximals.getFirst();
- } // CSON: RedundantThrows
+ }
+ return new AmbiguousException(severe || instanceArgCount == classes.length);
+ }
- /**
- * Creates an ambiguous exception.
- * <p>
- * This method computes the severity of the ambiguity. The only <em>non-severe</em> case is when there is
- * at least one null argument and at most one applicable method or constructor has a corresponding 'Object'
- * parameter.
- * We thus consider that ambiguity is benign in presence of null arguments but in the case where
- * the corresponding parameter is of type Object in more than one applicable overloads.
- * <p>
- * Rephrasing:
- * <ul>
- * <li>If all arguments are valid instances - no null argument -, ambiguity is severe.</li>
- * <li>If there is at least one null argument, the ambiguity is severe if more than one method has a
- * corresponding parameter of class 'Object'.</li>
- * </ul>
- *
- * @param classes the argument args
- * @param applicables the list of applicable methods or constructors
- * @return an ambiguous exception
- */
- private AmbiguousException ambiguousException (final Class<?>[] classes, final Deque<T> applicables) {
- boolean severe = false;
- int instanceArgCount = 0; // count the number of valid instances, aka not null
- for(int c = 0; c < classes.length; ++c) {
- final Class<?> argClazz = classes[c];
- if (Void.class.equals(argClazz)) {
- // count the number of methods for which the current arg maps to an Object parameter
- int objectParmCount = 0;
- for (final T app : applicables) {
- final Class<?>[] parmClasses = getParameterTypes(app);
- final Class<?> parmClass = parmClasses[c];
- if (Object.class.equals(parmClass) && (objectParmCount++ == 2)) {
- severe = true;
- break;
- }
+ /**
+ * Determines which method signature (represented by a class array) is more
+ * specific. This defines a partial ordering on the method signatures.
+ *
+ * @param a the arguments signature
+ * @param c1 first method signature to compare
+ * @param c2 second method signature to compare
+ * @return MORE_SPECIFIC if c1 is more specific than c2, LESS_SPECIFIC if
+ * c1 is less specific than c2, INCOMPARABLE if they are incomparable.
+ */
+ private static int moreSpecific(final Class<?>[] a, final Class<?>[] c1, final Class<?>[] c2) {
+ // compare lengths to handle comparisons where the size of the arrays
+ // doesn't match, but the methods are both applicable due to the fact
+ // that one is a varargs method
+ if (c1.length > a.length) {
+ return LESS_SPECIFIC;
+ }
+ if (c2.length > a.length) {
+ return MORE_SPECIFIC;
+ }
+ if (c1.length > c2.length) {
+ return MORE_SPECIFIC;
+ }
+ if (c2.length > c1.length) {
+ return LESS_SPECIFIC;
+ }
+ // same length, keep ultimate param offset for vararg checks
+ final int length = c1.length;
+ final int ultimate = c1.length - 1;
+ // ok, move on and compare those of equal lengths
+ for (int i = 0; i < length; ++i) {
+ if (c1[i] != c2[i]) {
+ final boolean last = (i == ultimate);
+ // argument is null, prefer an Object param
+ if (a[i] == Void.class) {
+ if (c1[i] == Object.class && c2[i] != Object.class) {
+ return MORE_SPECIFIC;
+ }
+ if (c1[i] != Object.class && c2[i] == Object.class) {
+ return LESS_SPECIFIC;
}
- } else {
- instanceArgCount += 1;
+ }
+ // prefer primitive on non-null arg, non-primitive otherwise
+ boolean c1s = isPrimitive(c1[i], last);
+ boolean c2s = isPrimitive(c2[i], last);
+ if (c1s != c2s) {
+ return (c1s == (a[i] != Void.class)) ? MORE_SPECIFIC : LESS_SPECIFIC;
+ }
+ // if c2 can be converted to c1 but not the opposite,
+ // c1 is more specific than c2
+ c1s = isStrictConvertible(c2[i], c1[i], last);
+ c2s = isStrictConvertible(c1[i], c2[i], last);
+ if (c1s != c2s) {
+ return c1s ? MORE_SPECIFIC : LESS_SPECIFIC;
}
}
- return new AmbiguousException(severe || instanceArgCount == classes.length);
}
+ // Incomparable due to non-related arguments (i.e.foo(Runnable) vs. foo(Serializable))
+ return INCOMPARABLE;
+ }
- /**
- * Determines which method signature (represented by a class array) is more
- * specific. This defines a partial ordering on the method signatures.
- *
- * @param a the arguments signature
- * @param c1 first method signature to compare
- * @param c2 second method signature to compare
- * @return MORE_SPECIFIC if c1 is more specific than c2, LESS_SPECIFIC if
- * c1 is less specific than c2, INCOMPARABLE if they are incomparable.
- */
- private int moreSpecific(final Class<?>[] a, final Class<?>[] c1, final Class<?>[] c2) {
- // compare lengths to handle comparisons where the size of the arrays
- // doesn't match, but the methods are both applicable due to the fact
- // that one is a varargs method
- if (c1.length > a.length) {
- return LESS_SPECIFIC;
- }
- if (c2.length > a.length) {
- return MORE_SPECIFIC;
- }
- if (c1.length > c2.length) {
- return MORE_SPECIFIC;
+ /**
+ * Checks whether a parameter class is a primitive.
+ *
+ * @param c the parameter class
+ * @param possibleVarArg true if this is the last parameter which can be a primitive array (vararg call)
+ * @return true if primitive, false otherwise
+ */
+ private static boolean isPrimitive(final Class<?> c, final boolean possibleVarArg) {
+ if (c != null) {
+ if (c.isPrimitive()) {
+ return true;
}
- if (c2.length > c1.length) {
- return LESS_SPECIFIC;
+ if (possibleVarArg) {
+ final Class<?> t = c.getComponentType();
+ return t != null && t.isPrimitive();
}
- // same length, keep ultimate param offset for vararg checks
- final int length = c1.length;
- final int ultimate = c1.length - 1;
-
- // ok, move on and compare those of equal lengths
- for (int i = 0; i < length; ++i) {
- if (c1[i] != c2[i]) {
- final boolean last = (i == ultimate);
- // argument is null, prefer an Object param
- if (a[i] == Void.class) {
- if (c1[i] == Object.class && c2[i] != Object.class) {
- return MORE_SPECIFIC;
- }
- if (c1[i] != Object.class && c2[i] == Object.class) {
- return LESS_SPECIFIC;
- }
- }
- // prefer primitive on non null arg, non primitive otherwise
- boolean c1s = isPrimitive(c1[i], last);
- boolean c2s = isPrimitive(c2[i], last);
- if (c1s != c2s) {
- return (c1s == (a[i] != Void.class))? MORE_SPECIFIC : LESS_SPECIFIC;
- }
- // if c2 can be converted to c1 but not the opposite,
- // c1 is more specific than c2
- c1s = isStrictConvertible(c2[i], c1[i], last);
- c2s = isStrictConvertible(c1[i], c2[i], last);
- if (c1s != c2s) {
- return c1s ? MORE_SPECIFIC : LESS_SPECIFIC;
- }
- }
- }
- // Incomparable due to non-related arguments (i.e.foo(Runnable) vs. foo(Serializable))
- return INCOMPARABLE;
}
+ return false;
+ }
- /**
- * Checks whether a parameter class is a primitive.
- * @param c the parameter class
- * @param possibleVarArg true if this is the last parameter which can be a primitive array (vararg call)
- * @return true if primitive, false otherwise
- */
- private boolean isPrimitive(final Class<?> c, final boolean possibleVarArg) {
- if (c != null) {
- if (c.isPrimitive()) {
- return true;
- }
- if (possibleVarArg) {
- final Class<?> t = c.getComponentType();
- return t != null && t.isPrimitive();
- }
+ /**
+ * Returns all methods that are applicable to actual argument types.
+ *
+ * @param methods list of all candidate methods
+ * @param classes the actual types of the arguments
+ * @return a list that contains only applicable methods (number of
+ * formal and actual arguments matches, and argument types are assignable
+ * to formal types through a method invocation conversion).
+ */
+ private static <T extends Executable> Deque<T> getApplicables(final T[] methods, final Class<?>[] classes) {
+ final Deque<T> list = new LinkedList<>();
+ for (final T method : methods) {
+ if (isApplicable(method, classes)) {
+ list.add(method);
}
- return false;
}
+ return list;
+ }
- /**
- * Returns all methods that are applicable to actual argument types.
- *
- * @param methods list of all candidate methods
- * @param classes the actual types of the arguments
- * @return a list that contains only applicable methods (number of
- * formal and actual arguments matches, and argument types are assignable
- * to formal types through a method invocation conversion).
- */
- private Deque<T> getApplicables(final T[] methods, final Class<?>[] classes) {
- final Deque<T> list = new LinkedList<>();
- for (final T method : methods) {
- if (isApplicable(method, classes)) {
- list.add(method);
+ /**
+ * Returns true if the supplied method is applicable to actual
+ * argument types.
+ *
+ * @param method method that will be called
+ * @param actuals arguments signature for method
+ * @return true if method is applicable to arguments
+ */
+ private static <T extends Executable> boolean isApplicable(final T method, final Class<?>[] actuals) {
+ final Class<?>[] formals = method.getParameterTypes();
+ // if same number or args or
+ // there's just one more methodArg than class arg
+ // and the last methodArg is an array, then treat it as a vararg
+ if (formals.length == actuals.length) {
+ // this will properly match when the last methodArg
+ // is an array/varargs and the last class is the type of array
+ // (e.g. String when the method is expecting String...)
+ for (int i = 0; i < actuals.length; ++i) {
+ if (!isConvertible(formals[i], actuals[i], false)) {
+ // if we're on the last arg and the method expects an array
+ if (i == actuals.length - 1 && formals[i].isArray()) {
+ // check to see if the last arg is convertible
+ // to the array's component type
+ return isConvertible(formals[i], actuals[i], true);
+ }
+ return false;
}
}
- return list;
+ return true;
}
- /**
- * Returns true if the supplied method is applicable to actual
- * argument types.
- *
- * @param method method that will be called
- * @param actuals arguments signature for method
- * @return true if method is applicable to arguments
- */
- private boolean isApplicable(final T method, final Class<?>[] actuals) {
- final Class<?>[] formals = getParameterTypes(method);
- // if same number or args or
- // there's just one more methodArg than class arg
- // and the last methodArg is an array, then treat it as a vararg
- if (formals.length == actuals.length) {
- // this will properly match when the last methodArg
- // is an array/varargs and the last class is the type of array
- // (e.g. String when the method is expecting String...)
- for (int i = 0; i < actuals.length; ++i) {
- if (!isConvertible(formals[i], actuals[i], false)) {
- // if we're on the last arg and the method expects an array
- if (i == actuals.length - 1 && formals[i].isArray()) {
- // check to see if the last arg is convertible
- // to the array's component type
- return isConvertible(formals[i], actuals[i], true);
- }
- return false;
- }
- }
- return true;
- }
+ // number of formal and actual differ, method must be vararg
+ if (!method.isVarArgs()) {
+ return false;
+ }
- // number of formal and actual differ, method must be vararg
- if (!isVarArgs(method)) {
+ // fewer arguments than method parameters: vararg is null
+ if (formals.length > actuals.length) {
+ // only one parameter, the last (ie vararg) can be missing
+ if (formals.length - actuals.length > 1) {
return false;
}
-
- // less arguments than method parameters: vararg is null
- if (formals.length > actuals.length) {
- // only one parameter, the last (ie vararg) can be missing
- if (formals.length - actuals.length > 1) {
+ // check that all present args match up to the method parms
+ for (int i = 0; i < actuals.length; ++i) {
+ if (!isConvertible(formals[i], actuals[i], false)) {
return false;
}
- // check that all present args match up to the method parms
- for (int i = 0; i < actuals.length; ++i) {
- if (!isConvertible(formals[i], actuals[i], false)) {
- return false;
- }
- }
- return true;
}
+ return true;
+ }
- // more arguments given than the method accepts; check for varargs
- if (formals.length > 0 && actuals.length > 0) {
- // check that they all match up to the last method arg
- for (int i = 0; i < formals.length - 1; ++i) {
- if (!isConvertible(formals[i], actuals[i], false)) {
- return false;
- }
+ // more arguments given than the method accepts; check for varargs
+ if (formals.length > 0) {
+ // check that they all match up to the last method arg
+ for (int i = 0; i < formals.length - 1; ++i) {
+ if (!isConvertible(formals[i], actuals[i], false)) {
+ return false;
}
- // check that all remaining arguments are convertible to the vararg type
- // (last parm is an array since method is vararg)
- final Class<?> vararg = formals[formals.length - 1].getComponentType();
- for (int i = formals.length - 1; i < actuals.length; ++i) {
- if (!isConvertible(vararg, actuals[i], false)) {
- return false;
- }
+ }
+ // check that all remaining arguments are convertible to the vararg type
+ // (last parm is an array since method is vararg)
+ final Class<?> vararg = formals[formals.length - 1].getComponentType();
+ for (int i = formals.length - 1; i < actuals.length; ++i) {
+ if (!isConvertible(vararg, actuals[i], false)) {
+ return false;
}
- return true;
}
- // no match
- return false;
- }
-
- /**
- * @see #isInvocationConvertible(Class, Class, boolean)
- * @param formal the formal parameter type to which the actual
- * parameter type should be convertible
- * @param actual the actual parameter type.
- * @param possibleVarArg whether or not we're dealing with the last parameter
- * in the method declaration
- * @return see isMethodInvocationConvertible.
- */
- private boolean isConvertible(final Class<?> formal, final Class<?> actual, final boolean possibleVarArg) {
- // if we see Void.class, the argument was null
- return isInvocationConvertible(formal, actual.equals(Void.class) ? null : actual, possibleVarArg);
- }
-
- /**
- * @see #isStrictInvocationConvertible(Class, Class, boolean)
- * @param formal the formal parameter type to which the actual
- * parameter type should be convertible
- * @param actual the actual parameter type.
- * @param possibleVarArg whether or not we're dealing with the last parameter
- * in the method declaration
- * @return see isStrictMethodInvocationConvertible.
- */
- private boolean isStrictConvertible(final Class<?> formal, final Class<?> actual,
- final boolean possibleVarArg) {
- // if we see Void.class, the argument was null
- return isStrictInvocationConvertible(formal, actual.equals(Void.class) ? null : actual, possibleVarArg);
+ return true;
}
+ // no match
+ return false;
}
/**
- * The parameter matching service for methods.
+ * @param formal the formal parameter type to which the actual
+ * parameter type should be convertible
+ * @param actual the actual parameter type.
+ * @param possibleVarArg whether we're dealing with the last parameter
+ * in the method declaration
+ * @return see isMethodInvocationConvertible.
+ * @see #isInvocationConvertible(Class, Class, boolean)
*/
- private static final Parameters<Method> METHODS = new Parameters<Method>() {
- @Override
- protected Class<?>[] getParameterTypes(final Method app) {
- return app.getParameterTypes();
- }
-
- @Override
- public boolean isVarArgs(final Method app) {
- return MethodKey.isVarArgs(app);
- }
-
- };
+ private static boolean isConvertible(final Class<?> formal, final Class<?> actual, final boolean possibleVarArg) {
+ // if we see Void.class, the argument was null
+ return isInvocationConvertible(formal, actual.equals(Void.class) ? null : actual, possibleVarArg);
+ }
/**
- * The parameter matching service for constructors.
+ * @param formal the formal parameter type to which the actual
+ * parameter type should be convertible
+ * @param actual the actual parameter type.
+ * @param possibleVarArg whether we're dealing with the last parameter
+ * in the method declaration
+ * @return see isStrictMethodInvocationConvertible.
+ * @see #isStrictInvocationConvertible(Class, Class, boolean)
*/
- private static final Parameters<Constructor<?>> CONSTRUCTORS = new Parameters<Constructor<?>>() {
- @Override
- protected Class<?>[] getParameterTypes(final Constructor<?> app) {
- return app.getParameterTypes();
- }
-
- @Override
- public boolean isVarArgs(final Constructor<?> app) {
- return app.isVarArgs();
- }
+ private static boolean isStrictConvertible(final Class<?> formal, final Class<?> actual,
+ final boolean possibleVarArg) {
+ // if we see Void.class, the argument was null
+ return isStrictInvocationConvertible(formal, actual.equals(Void.class) ? null : actual, possibleVarArg);
+ }
- };
}