1 package org.python.core; 3 4 import java.lang.reflect.Method ; 5 import java.lang.reflect.Modifier ; 6 import java.util.Arrays ; 7 import java.util.Hashtable ; 8 import java.util.Enumeration ; 9 10 11 public class PyReflectedFunction extends PyObject 12 { 13 public String __name__; 14 public PyObject __doc__ = Py.None; 15 public ReflectedArgs[] argslist; 16 public int nargs; 17 18 public PyReflectedFunction(String name) { 19 __name__ = name; 20 argslist = new ReflectedArgs[1]; 21 nargs = 0; 22 } 23 24 public PyReflectedFunction(Method method) { 25 this(method.getName()); 26 addMethod(method); 27 } 28 29 public PyObject _doget(PyObject container) { 30 return _doget(container, null); 31 } 32 33 public PyObject _doget(PyObject container, PyObject wherefound) { 34 if (container == null) 35 return this; 36 return new PyMethod(container, this, wherefound); 37 } 38 39 public boolean _doset(PyObject container) { 40 throw Py.TypeError("java function not settable: "+__name__); 41 } 42 43 private ReflectedArgs makeArgs(Method m) { 44 return new ReflectedArgs(m, m.getParameterTypes(), 45 m.getDeclaringClass(), 46 Modifier.isStatic(m.getModifiers())); 47 } 48 49 public PyReflectedFunction copy() { 50 PyReflectedFunction func = new PyReflectedFunction(__name__); 51 func.__doc__ = __doc__; 52 func.nargs = nargs; 53 func.argslist = new ReflectedArgs[nargs]; 54 System.arraycopy(argslist, 0, func.argslist, 0, nargs); 55 return func; 56 } 57 58 public boolean handles(Method method) { 59 return handles(makeArgs(method)); 60 } 61 62 protected boolean handles(ReflectedArgs args) { 63 ReflectedArgs[] argsl = argslist; 64 int n = nargs; 65 for(int i=0; i<n; i++) { 66 int cmp = args.compareTo(argsl[i]); 67 if (cmp == 0) 68 return true; 69 if (cmp == +1) 70 return false; 71 } 72 return false; 73 } 74 75 public void addMethod(Method m) { 76 int mods = m.getModifiers(); 77 if (!Modifier.isPublic(mods) && !JavaAccessibility.accessIsMutable()) 79 return; 80 addArgs(makeArgs(m)); 81 } 82 83 protected void addArgs(ReflectedArgs args) { 84 ReflectedArgs[] argsl = argslist; 85 int n = nargs; 86 int i; 87 for(i=0; i<n; i++) { 88 int cmp = args.compareTo(argsl[i]); 89 if (cmp == 0) 90 return; 91 if (cmp == ReflectedArgs.REPLACE) { 92 argsl[i] = args; 93 return; 94 } 95 if (cmp == -1) 96 break; 97 } 98 99 int nn = n+1; 100 if (nn > argsl.length) { 101 argsl = new ReflectedArgs[nn+2]; 102 System.arraycopy(argslist, 0, argsl, 0, n); 103 argslist = argsl; 104 } 105 106 for(int j=n; j>i; j--) { 107 argsl[j] = argsl[j-1]; 108 } 109 110 argsl[i] = args; 111 nargs = nn; 112 } 113 114 public PyObject __call__(PyObject self, PyObject[] args, 115 String [] keywords) 116 { 117 ReflectedCallData callData = new ReflectedCallData(); 118 Object method = null; 119 120 ReflectedArgs[] argsl = argslist; 121 int n = nargs; 122 for (int i=0; i<n; i++) { 123 ReflectedArgs rargs = argsl[i]; 124 if (rargs.matches(self, args, keywords, callData)) { 126 method = rargs.data; 127 break; 128 } 129 } 130 if (method == null) { 131 throwError(callData.errArg, args.length, self != null, 132 keywords.length != 0); 133 } 134 135 Object cself = callData.self; 136 Method m = (Method )method; 137 if (self == null && cself != null && cself instanceof PyProxy && 140 !__name__.startsWith("super__")) { 141 PyInstance iself = ((PyProxy)cself)._getPyInstance(); 142 if (argslist[0].declaringClass != iself.instclass.proxyClass) { 143 String mname = ("super__"+__name__); 144 Method [] super__methods = (Method [])iself.instclass.super__methods.get(mname); 146 if (super__methods != null) { 147 Class [] msig = m.getParameterTypes(); 148 for (int i=0; i<super__methods.length;i++) { 149 if (java.util.Arrays.equals(msig,super__methods[i].getParameterTypes())) { 150 m = super__methods[i]; 151 break; 152 } 153 } 154 } 155 164 170 } 171 } 172 try { 173 174 Object o = m.invoke(cself, callData.getArgsArray()); 175 return Py.java2py(o); 176 } catch (Throwable t) { 177 throw Py.JavaError(t); 178 } 179 } 180 181 public PyObject __call__(PyObject[] args, String [] keywords) { 182 return __call__(null, args, keywords); 183 } 184 185 187 188 protected void throwError(String message) { 189 throw Py.TypeError(__name__+"(): "+message); 190 } 191 192 private static void addRange(StringBuffer buf, int min, int max, 193 String sep) 194 { 195 if (buf.length() > 0) { 196 buf.append(sep); 197 } 198 if (min < max) { 199 buf.append(Integer.toString(min)+"-"+max); 200 } else { 201 buf.append(min); 202 } 203 } 204 205 206 protected void throwArgCountError(int nArgs, boolean self) { 207 boolean[] legalArgs = new boolean[40]; 209 int maxArgs = -1; 210 int minArgs = 40; 211 212 ReflectedArgs[] argsl = argslist; 213 int n = nargs; 214 for (int i=0; i<n; i++) { 215 ReflectedArgs rargs = argsl[i]; 216 217 int l = rargs.args.length; 218 if (!self && !rargs.isStatic) { 219 l += 1; 220 } 221 222 legalArgs[l] = true; 223 if (l > maxArgs) 224 maxArgs = l; 225 if (l < minArgs) 226 minArgs = l; 227 } 228 229 StringBuffer buf = new StringBuffer (); 230 231 int startRange = minArgs; 232 int a = minArgs+1; 233 while (a < maxArgs) { 234 if (legalArgs[a]) { 235 a++; 236 continue; 237 } else { 238 addRange(buf, startRange, a-1, ", "); 239 a++; 240 while (a <= maxArgs) { 241 if (legalArgs[a]) { 242 startRange = a; 243 break; 244 } 245 a++; 246 } 247 } 248 } 249 addRange(buf, startRange, maxArgs, " or "); 250 throwError("expected "+buf+" args; got "+nArgs); 251 } 252 253 private static String ordinal(int n) { 254 switch(n+1) { 255 case 0: 256 return "self"; 257 case 1: 258 return "1st"; 259 case 2: 260 return "2nd"; 261 case 3: 262 return "3rd"; 263 default: 264 return Integer.toString(n+1)+"th"; 265 } 266 } 267 268 private static String niceName(Class arg) { 269 if (arg == String .class || arg == PyString.class) { 270 return "String"; 271 } 272 if (arg.isArray()) { 273 return niceName(arg.getComponentType())+"[]"; 274 } 275 return arg.getName(); 276 } 277 278 protected void throwBadArgError(int errArg, int nArgs, boolean self) { 279 Hashtable table = new Hashtable (); 280 ReflectedArgs[] argsl = argslist; 281 int n = nargs; 282 for(int i=0; i<n; i++) { 283 ReflectedArgs rargs = argsl[i]; 284 Class [] args = rargs.args; 285 int len = args.length; 286 289 if (len == nArgs) { 293 if (errArg == -1) { 294 table.put(rargs.declaringClass, rargs.declaringClass); 295 } else { 296 table.put(args[errArg], args[errArg]); 297 } 298 } 299 } 300 301 StringBuffer buf = new StringBuffer (); 302 Enumeration keys = table.keys(); 303 while (keys.hasMoreElements()) { 304 Class arg = (Class )keys.nextElement(); 305 String name = niceName(arg); 306 if (keys.hasMoreElements()) { 307 buf.append(name); 308 buf.append(", "); 309 } else { 310 if (buf.length() > 2) { 311 buf.setLength(buf.length()-2); 312 buf.append(" or "); 313 } 314 buf.append(name); 315 } 316 } 317 318 throwError(ordinal(errArg)+" arg can't be coerced to "+buf); 319 } 320 321 protected void throwError(int errArg, int nArgs, boolean self, 322 boolean keywords) 323 { 324 if (keywords) throwError("takes no keyword arguments"); 325 326 if (errArg == -2) { 327 throwArgCountError(nArgs, self); 328 } 329 330 335 336 throwBadArgError(errArg, nArgs, self); 337 } 338 339 public void printArgs() { 341 System.err.println("nargs: "+nargs); 342 for(int i=0; i<nargs; i++) { 343 ReflectedArgs args = argslist[i]; 344 System.err.println(args.toString()); 345 } 346 } 347 348 349 public String toString() { 350 return "<java function "+__name__+" "+Py.idstr(this)+">"; 352 } 353 } 354 | Popular Tags |