diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-10-21 19:24:07 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-10-21 19:24:07 +0000 |
commit | 6bd66ef67649eecd6012ce10f3da39c325ea4675 (patch) | |
tree | 5c7217466ce872041c2b9200efb39f7182ff0400 /src | |
parent | 17e416d3cb89416063fd01a7b5ee4b40ffd0bf0f (diff) |
added handling of public methods of non-public classes with call via interface method
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/Reflector.java | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/src/jvm/clojure/lang/Reflector.java b/src/jvm/clojure/lang/Reflector.java index 1c0b5986..3b95acd9 100644 --- a/src/jvm/clojure/lang/Reflector.java +++ b/src/jvm/clojure/lang/Reflector.java @@ -16,6 +16,7 @@ import java.lang.reflect.*; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Arrays; public class Reflector{ @@ -26,32 +27,53 @@ public static Object invokeInstanceMethod(Object target, String methodName, Obje } private static Object invokeMatchingMethod(List methods, Object target, Object[] args) - throws IllegalAccessException, InvocationTargetException{ + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{ + Method m = null; + Object[] boxedArgs = null; if(methods.isEmpty()) { throw new IllegalArgumentException("No matching field or method found"); } else if(methods.size() == 1) { - Method m = (Method) methods.get(0); - return prepRet(m.invoke(target, boxArgs(m.getParameterTypes(), args))); + m = (Method) methods.get(0); + boxedArgs = boxArgs(m.getParameterTypes(),args); } else //overloaded w/same arity { for(Iterator i = methods.iterator(); i.hasNext();) { - Method m = (Method) i.next(); + m = (Method) i.next(); Class[] params = m.getParameterTypes(); if(isCongruent(params, args)) { - Object[] boxedArgs = boxArgs(params, args); - return prepRet(m.invoke(target, boxedArgs)); + boxedArgs = boxArgs(params, args); + break; } } + } + if(m == null) throw new IllegalArgumentException("No matching field or method found"); + if(!Modifier.isPublic(m.getDeclaringClass().getModifiers())) + { + //public method of non-public class, try to find it in an interface + Class c = m.getDeclaringClass(); + for(Class iface : c.getInterfaces()) + { + for(Method im : iface.getDeclaredMethods()) + { + if(im.getName().equals(m.getName()) + && Arrays.equals(m.getParameterTypes(),im.getParameterTypes())) + { + m = im; + break; + } + } + } } + return prepRet(m.invoke(target, boxedArgs)); } public static Object invokeConstructor(Class c, Object[] args) throws Exception{ |