diff options
-rw-r--r-- | src/cli/runtime/Reflector.cs | 90 | ||||
-rw-r--r-- | src/org/clojure/runtime/Reflector.java | 92 |
2 files changed, 141 insertions, 41 deletions
diff --git a/src/cli/runtime/Reflector.cs b/src/cli/runtime/Reflector.cs index a342d5bf..d4bf11bf 100644 --- a/src/cli/runtime/Reflector.cs +++ b/src/cli/runtime/Reflector.cs @@ -16,42 +16,106 @@ namespace org.clojure.runtime {
public class Reflector{
-public static Object invokeInstanceMethod(String name, Object target, Object[] args) //throws Exception
{
Type t = target.GetType();
IList methods = getMethods(t, args.Length, name);
if(methods.Count == 0)
{
- throw new InvalidOperationException("No matching field or method found");
}
else if(methods.Count == 1)
{
MethodInfo m = (MethodInfo) methods[0];
return m.Invoke(target, boxArgs(m.GetParameters(), args));
}
else //overloaded w/same arity, let reflection choose most specific match
{
- return t.InvokeMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.InvokeMethod,
null, target, args);
}
}
+public static Object invokeInstanceMethod(String name, Object target, Object[] args) //throws Exception
{
Type t = target.GetType();
IList methods = getMethods(t, args.Length, name,false);
+ return invokeMatchingMethod(name, target, args, t, methods,false);
+ }
-public static Object invokeInstanceMember(String name, Object target) //throws Exception
{
//check for field first
Type t = target.GetType();
FieldInfo f = getField(t, name);
if(f != null) //field get
{
return f.GetValue(target);
}
- PropertyInfo p = getProperty(t, name);
+ private static object invokeMatchingMethod(String name, Object target, Object[] args, Type t, IList methods, bool statics)
+ {
+ if (methods.Count == 0)
+ {
+ throw new InvalidOperationException("No matching field or method found");
+ }
+ else if (methods.Count == 1)
+ {
+ MethodInfo m = (MethodInfo)methods[0];
+ return m.Invoke(target, boxArgs(m.GetParameters(), args));
+ }
+ else //overloaded w/same arity, let reflection choose most specific match
+ {
+ return t.InvokeMember(name, BindingFlags.Public | (statics ? BindingFlags.Static : BindingFlags.Instance)
+ | BindingFlags.FlattenHierarchy | BindingFlags.InvokeMethod,
+ null, target, args);
+ }
+ }
+
+public static Object invokeStaticMethod(String name, String className, Object[] args) //throws Exception
+ {
+ Type t = Type.GetType(className);
+ IList methods = getMethods(t, args.Length, name, true);
+ return invokeMatchingMethod(name, null, args, t, methods,true);
+ }
+
+public static Object getStaticField(String name, String className) //throws Exception
+ {
+ //check for field first
+ Type t = Type.GetType(className);
+ FieldInfo f = getField(t, name, true);
+ if (f != null) //field get
+ {
+ return f.GetValue(null);
+ }
+ PropertyInfo p = getProperty(t, name, true);
+ if (p != null)
+ {
+ return p.GetValue(null, null);
+ }
+ throw new InvalidOperationException("No matching field or property found");
+ }
+
+public static Object setStaticField(String name, String className, Object arg1) //throws Exception
+ {
+ //check for field first
+ Type t = Type.GetType(className);
+ FieldInfo f = getField(t, name, true);
+ if (f != null) //field get
+ {
+ f.SetValue(null, boxArg(f.FieldType, arg1));
+ return arg1;
+ }
+ PropertyInfo p = getProperty(t, name, true);
+ if (p != null)
+ {
+ p.SetValue(null, boxArg(p.PropertyType, arg1), null);
+ return arg1;
+ }
+ throw new InvalidOperationException("No matching field or property found");
+ }
+
+public static Object invokeInstanceMember(String name, Object target) //throws Exception
{
//check for field first
Type t = target.GetType();
FieldInfo f = getField(t, name,false);
if(f != null) //field get
{
return f.GetValue(target);
}
+ PropertyInfo p = getProperty(t, name,false);
if (p != null)
{
return p.GetValue(target, null);
- }
return invokeInstanceMethod(name, target, RT.EMPTY_ARRAY);
}
public static Object invokeInstanceMember(String name, Object target, Object arg1) //throws Exception
{
//check for field first
Type t = target.GetType();
FieldInfo f = getField(t, name);
+ }
return invokeInstanceMethod(name, target, RT.EMPTY_ARRAY);
}
public static Object invokeInstanceMember(String name, Object target, Object arg1) //throws Exception
{
//check for field first
Type t = target.GetType();
FieldInfo f = getField(t, name,false);
if (f != null) //field get
{
f.SetValue(target,boxArg(f.FieldType,arg1));
return arg1;
}
- PropertyInfo p = getProperty(t, name);
+ PropertyInfo p = getProperty(t, name,false);
if (p != null)
{
//could be indexed property, which we otherwise aren't dealing with yet
if(p.GetIndexParameters() != null && p.GetIndexParameters().Length == 1)
return p.GetValue(target, new Object[]{boxArg(p.GetIndexParameters()[0].ParameterType,arg1)});
p.SetValue(target,boxArg(p.PropertyType,arg1),null);
+ return arg1;
}
return invokeInstanceMethod(name, target, new Object[]{arg1});
}
public static Object invokeInstanceMember(String name, Object target, Object arg1, Object arg2) //throws Exception
{
return invokeInstanceMethod(name, target, new Object[]{arg1, arg2});
}
public static Object invokeInstanceMember(String name, Object target, Object arg1, Object arg2, Object arg3)
//throws Exception
{
return invokeInstanceMethod(name, target, new Object[]{arg1, arg2, arg3});
}
public static Object invokeInstanceMember(String name, Object target, Object arg1, Object arg2, Object arg3,
Object arg4)
//throws Exception
{
return invokeInstanceMethod(name, target, new Object[]{arg1, arg2, arg3, arg4});
}
public static Object invokeInstanceMember(String name, Object target, Object arg1, Object arg2, Object arg3,
Object arg4,
Cons arglist)
//throws Exception
{
Object[] args = new Object[4 + RT.length(arglist)];
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
for(int i = 4; arglist != null; i++, arglist = arglist.rest)
args[i] = arglist.first;
return invokeInstanceMethod(name, target, args);
}
- public static FieldInfo getField(Type t, string name)
+ public static FieldInfo getField(Type t, string name,bool statics)
{
- return t.GetField(name, BindingFlags.Public | BindingFlags.Instance |BindingFlags.FlattenHierarchy);
+ return t.GetField(name, BindingFlags.Public | (statics ? BindingFlags.Static : BindingFlags.Instance) | BindingFlags.FlattenHierarchy);
}
- public static PropertyInfo getProperty(Type t, string name)
+ public static PropertyInfo getProperty(Type t, string name, bool statics)
{
- return t.GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
+ return t.GetProperty(name, BindingFlags.Public | (statics ? BindingFlags.Static : BindingFlags.Instance) | BindingFlags.FlattenHierarchy);
}
- static public IList getMethods(Type t, int arity, String name)
+ static public IList getMethods(Type t, int arity, String name, bool getStatics)
{
- MethodInfo[] allmethods = t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
+ MethodInfo[] allmethods = t.GetMethods(BindingFlags.Public | (getStatics?BindingFlags.Static : BindingFlags.Instance)
+ | BindingFlags.FlattenHierarchy);
ArrayList methods = new ArrayList();
for (int i = 0; i < allmethods.Length; i++)
{
diff --git a/src/org/clojure/runtime/Reflector.java b/src/org/clojure/runtime/Reflector.java index 6e6e3781..292c0a3a 100644 --- a/src/org/clojure/runtime/Reflector.java +++ b/src/org/clojure/runtime/Reflector.java @@ -15,6 +15,7 @@ package org.clojure.runtime; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -24,39 +25,74 @@ public class Reflector{ public static Object invokeInstanceMethod(String name, Object target, Object[] args) throws Exception { Class c = target.getClass(); - List methods = getMethods(c, args.length, name); - if(methods.isEmpty()) - { - throw new IllegalArgumentException("No matching field or method found"); - } - else if(methods.size() == 1) + List methods = getMethods(c, args.length, name,false); + return invokeMatchingMethod(methods, target, args); + } + +private static Object invokeMatchingMethod(List methods, Object target, Object[] args) + throws IllegalAccessException, InvocationTargetException { + if(methods.isEmpty()) + { + throw new IllegalArgumentException("No matching field or method found"); + } + else if(methods.size() == 1) + { + Method m = (Method) methods.get(0); + return m.invoke(target, boxArgs(m.getParameterTypes(), args)); + } + else //overloaded w/same arity + { + for(Iterator i = methods.iterator(); i.hasNext();) + { + Method m = (Method) i.next(); + + Class[] params = m.getParameterTypes(); + if(isCongruent(params, args)) + { + Object[] boxedArgs = boxArgs(params, args); + return m.invoke(target, boxedArgs); + } + } + throw new IllegalArgumentException("No matching field or method found"); + + } +} + +public static Object invokeStaticMethod(String name, String className, Object[] args) throws Exception + { + Class c = Class.forName(className); + List methods = getMethods(c, args.length, name,true); + return invokeMatchingMethod(methods, null, args); + } + +public static Object getStaticField(String name, String className) throws Exception + { + Class c = Class.forName(className); + Field f = getField(c, name,true); + if(f != null) { - Method m = (Method) methods.get(0); - return m.invoke(target, boxArgs(m.getParameterTypes(), args)); + return f.get(null); } - else //overloaded w/same arity - { - for(Iterator i = methods.iterator(); i.hasNext();) - { - Method m = (Method) i.next(); - - Class[] params = m.getParameterTypes(); - if(isCongruent(params, args)) - { - Object[] boxedArgs = boxArgs(params, args); - return m.invoke(target, boxedArgs); - } - } - throw new IllegalArgumentException("No matching field or method found"); + throw new IllegalArgumentException("No matching field found"); + } + public static Object setStaticField(String name, String className, Object arg1) throws Exception + { + Class c = Class.forName(className); + Field f = getField(c, name,true); + if(f != null) + { + f.set(null, boxArg(f.getType(), arg1)); + return arg1; } + throw new IllegalArgumentException("No matching field found"); } public static Object invokeInstanceMember(String name, Object target) throws Exception { //check for field first Class c = target.getClass(); - Field f = getField(c, name); + Field f = getField(c, name,false); if(f != null) //field get { return f.get(target); @@ -68,7 +104,7 @@ public static Object invokeInstanceMember(String name, Object target, Object arg { //check for field first Class c = target.getClass(); - Field f = getField(c, name); + Field f = getField(c, name,false); if(f != null) //field set { f.set(target, boxArg(f.getType(), arg1)); @@ -111,26 +147,26 @@ public static Object invokeInstanceMember(String name, Object target, Object arg } -static public Field getField(Class c, String name) +static public Field getField(Class c, String name, boolean getStatics) { Field[] allfields = c.getFields(); for(int i = 0; i < allfields.length; i++) { if(name.equals(allfields[i].getName()) - && !Modifier.isStatic(allfields[i].getModifiers())) + && Modifier.isStatic(allfields[i].getModifiers()) == getStatics) return allfields[i]; } return null; } -static public List getMethods(Class c, int arity, String name) +static public List getMethods(Class c, int arity, String name, boolean getStatics) { Method[] allmethods = c.getMethods(); ArrayList methods = new ArrayList(); for(int i = 0; i < allmethods.length; i++) { if(name.equals(allmethods[i].getName()) - && !Modifier.isStatic(allmethods[i].getModifiers()) + && Modifier.isStatic(allmethods[i].getModifiers()) == getStatics && allmethods[i].getParameterTypes().length == arity) { methods.add(allmethods[i]); |