1 package org.python.core; 2 3 import java.io.Serializable ; 4 import java.lang.reflect.Constructor ; 5 import java.lang.reflect.Field ; 6 import java.lang.reflect.Method ; 7 import java.lang.reflect.Modifier ; 8 import java.util.ArrayList ; 9 import java.util.HashMap ; 10 import java.util.Iterator ; 11 12 16 public class PyType extends PyObject { 17 18 19 public static final String exposed_name = "type"; 20 21 public static void typeSetup(PyObject dict, PyType.Newstyle marker) { 22 dict.__setitem__("__dict__", new PyGetSetDescr("__dict__", 23 PyType.class, "getDict", null)); 24 dict.__setitem__("__name__", new PyGetSetDescr("__name__", 25 PyType.class, "fastGetName", null)); 26 dict.__setitem__("__base__", new PyGetSetDescr("__base__", 27 PyType.class, "getBase", null)); 28 dict.__setitem__("__bases__", new PyGetSetDescr("__bases__", 29 PyType.class, "getBases", null)); 30 class exposed___getattribute__ extends PyBuiltinFunctionNarrow { 31 32 private PyType self; 33 34 public PyObject getSelf() { 35 return self; 36 } 37 38 exposed___getattribute__(PyType self, PyBuiltinFunction.Info info) { 39 super(info); 40 this.self = self; 41 } 42 43 public PyBuiltinFunction makeBound(PyObject self) { 44 return new exposed___getattribute__((PyType) self, info); 45 } 46 47 public PyObject __call__(PyObject arg0) { 48 try { 49 String name = (arg0.asName(0)); 50 PyObject ret = self.type___findattr__(name); 51 if (ret == null) 52 self.noAttributeError(name); 53 return ret; 54 } catch (PyObject.ConversionException e) { 55 String msg; 56 switch (e.index) { 57 case 0: 58 msg = "attribute name must be string"; 59 break; 60 default: 61 msg = "xxx"; 62 } 63 throw Py.TypeError(msg); 64 } 65 } 66 67 public PyObject inst_call(PyObject gself, PyObject arg0) { 68 PyType self = (PyType) gself; 69 try { 70 String name = (arg0.asName(0)); 71 PyObject ret = self.type___findattr__(name); 72 if (ret == null) 73 self.noAttributeError(name); 74 return ret; 75 } catch (PyObject.ConversionException e) { 76 String msg; 77 switch (e.index) { 78 case 0: 79 msg = "attribute name must be string"; 80 break; 81 default: 82 msg = "xxx"; 83 } 84 throw Py.TypeError(msg); 85 } 86 } 87 88 } 89 dict.__setitem__("__getattribute__", new PyMethodDescr( 90 "__getattribute__", PyType.class, 1, 1, 91 new exposed___getattribute__(null, null))); 92 class exposed___setattr__ extends PyBuiltinFunctionNarrow { 93 94 private PyType self; 95 96 public PyObject getSelf() { 97 return self; 98 } 99 100 exposed___setattr__(PyType self, PyBuiltinFunction.Info info) { 101 super(info); 102 this.self = self; 103 } 104 105 public PyBuiltinFunction makeBound(PyObject self) { 106 return new exposed___setattr__((PyType) self, info); 107 } 108 109 public PyObject __call__(PyObject arg0, PyObject arg1) { 110 try { 111 self.type___setattr__(arg0.asName(0), arg1); 112 return Py.None; 113 } catch (PyObject.ConversionException e) { 114 String msg; 115 switch (e.index) { 116 case 0: 117 msg = "attribute name must be string"; 118 break; 119 default: 120 msg = "xxx"; 121 } 122 throw Py.TypeError(msg); 123 } 124 } 125 126 public PyObject inst_call(PyObject gself, PyObject arg0, 127 PyObject arg1) { 128 PyType self = (PyType) gself; 129 try { 130 self.type___setattr__(arg0.asName(0), arg1); 131 return Py.None; 132 } catch (PyObject.ConversionException e) { 133 String msg; 134 switch (e.index) { 135 case 0: 136 msg = "attribute name must be string"; 137 break; 138 default: 139 msg = "xxx"; 140 } 141 throw Py.TypeError(msg); 142 } 143 } 144 145 } 146 dict.__setitem__("__setattr__", new PyMethodDescr("__setattr__", 147 PyType.class, 2, 2, new exposed___setattr__(null, null))); 148 class exposed___delattr__ extends PyBuiltinFunctionNarrow { 149 150 private PyType self; 151 152 public PyObject getSelf() { 153 return self; 154 } 155 156 exposed___delattr__(PyType self, PyBuiltinFunction.Info info) { 157 super(info); 158 this.self = self; 159 } 160 161 public PyBuiltinFunction makeBound(PyObject self) { 162 return new exposed___delattr__((PyType) self, info); 163 } 164 165 public PyObject __call__(PyObject arg0) { 166 try { 167 self.type___delattr__(arg0.asName(0)); 168 return Py.None; 169 } catch (PyObject.ConversionException e) { 170 String msg; 171 switch (e.index) { 172 case 0: 173 msg = "attribute name must be string"; 174 break; 175 default: 176 msg = "xxx"; 177 } 178 throw Py.TypeError(msg); 179 } 180 } 181 182 public PyObject inst_call(PyObject gself, PyObject arg0) { 183 PyType self = (PyType) gself; 184 try { 185 self.type___delattr__(arg0.asName(0)); 186 return Py.None; 187 } catch (PyObject.ConversionException e) { 188 String msg; 189 switch (e.index) { 190 case 0: 191 msg = "attribute name must be string"; 192 break; 193 default: 194 msg = "xxx"; 195 } 196 throw Py.TypeError(msg); 197 } 198 } 199 200 } 201 dict.__setitem__("__delattr__", new PyMethodDescr("__delattr__", 202 PyType.class, 1, 1, new exposed___delattr__(null, null))); 203 class exposed___subclasses__ extends PyBuiltinFunctionNarrow { 204 205 private PyType self; 206 207 public PyObject getSelf() { 208 return self; 209 } 210 211 exposed___subclasses__(PyType self, PyBuiltinFunction.Info info) { 212 super(info); 213 this.self = self; 214 } 215 216 public PyBuiltinFunction makeBound(PyObject self) { 217 return new exposed___subclasses__((PyType) self, info); 218 } 219 220 public PyObject __call__() { 221 return self.type_getSubclasses(); 222 } 223 224 public PyObject inst_call(PyObject gself) { 225 PyType self = (PyType) gself; 226 return self.type_getSubclasses(); 227 } 228 229 } 230 dict.__setitem__("__subclasses__", new PyMethodDescr("__subclasses__", 231 PyType.class, 0, 0, new exposed___subclasses__(null, null))); 232 class exposed___call__ extends PyBuiltinFunctionWide { 233 234 private PyType self; 235 236 public PyObject getSelf() { 237 return self; 238 } 239 240 exposed___call__(PyType self, PyBuiltinFunction.Info info) { 241 super(info); 242 this.self = self; 243 } 244 245 public PyBuiltinFunction makeBound(PyObject self) { 246 return new exposed___call__((PyType) self, info); 247 } 248 249 public PyObject inst_call(PyObject self, PyObject[] args) { 250 return inst_call(self, args, Py.NoKeywords); 251 } 252 253 public PyObject __call__(PyObject[] args) { 254 return __call__(args, Py.NoKeywords); 255 } 256 257 public PyObject __call__(PyObject[] args, String [] keywords) { 258 return self.type___call__(args, keywords); 259 } 260 261 public PyObject inst_call(PyObject gself, PyObject[] args, 262 String [] keywords) { 263 PyType self = (PyType) gself; 264 return self.type___call__(args, keywords); 265 } 266 267 } 268 dict.__setitem__("__call__", new PyMethodDescr("__call__", 269 PyType.class, -1, -1, new exposed___call__(null, null))); 270 dict.__setitem__("__new__", new PyNewWrapper(PyType.class, "__new__", 271 -1, -1) { 272 273 public PyObject new_impl(boolean init, PyType subtype, 274 PyObject[] args, String [] keywords) { 275 return type_new(this, init, subtype, args, keywords); 276 } 277 278 }); 279 } 280 281 public static PyObject type_new(PyObject new_, boolean init, 282 PyType subtype, PyObject[] args, String [] keywords) { 283 if (args.length == 1 && keywords.length == 0) { 284 return args[0].getType(); 285 } 286 if (args.length + keywords.length != 3) 287 throw Py.TypeError("type() takes exactly 1 or 3 arguments"); 288 ArgParser ap = new ArgParser("type()", args, keywords, "name", "bases", 289 "dict"); 290 String name = ap.getString(0); 291 PyObject bases = ap.getPyObject(1); 292 if (!(bases instanceof PyTuple)) 293 throw Py.TypeError("type(): bases must be tuple"); 294 PyObject dict = ap.getPyObject(2); 295 if (!(dict instanceof PyDictionary || dict instanceof PyStringMap)) 296 throw Py.TypeError("type(): dict must be dict"); 297 return newType(new_, subtype, name, (PyTuple) bases, dict); 298 299 } 300 301 302 public PyObject getStatic() { 303 PyType cur = this; 304 while (cur.underlying_class == null) { 305 cur = cur.base; 306 } 307 return cur; 308 } 309 310 public PyObject getBase() { 311 if (base == null) 312 return Py.None; 313 return base; 314 } 315 316 public PyObject getBases() { 317 if (bases == null) 318 return new PyTuple(); 319 return new PyTuple(bases); 320 } 321 322 public PyObject instDict() { 323 if (needs_userdict) { 324 return new PyStringMap(); 325 } 326 return null; 327 } 328 329 private String name; 330 private PyType base; 331 private PyObject[] bases; 332 private PyObject dict; 333 private PyObject[] mro; 334 private Class underlying_class; 335 336 private boolean non_instantiable = false; 337 338 boolean has_set, has_delete; 339 340 private boolean needs_finalizer; 341 342 private int nuserslots; 343 private boolean needs_userdict; 344 345 private java.lang.ref.ReferenceQueue subclasses_refq = new java.lang.ref.ReferenceQueue (); 346 private java.util.HashSet subclasses = new java.util.HashSet (); 347 348 private void cleanup_subclasses() { 349 java.lang.ref.Reference ref; 350 while ((ref = subclasses_refq.poll()) != null) { 351 subclasses.remove(ref); 352 } 353 } 354 355 public synchronized final PyObject type_getSubclasses() { 356 PyList result = new PyList(); 357 cleanup_subclasses(); 358 for (java.util.Iterator iter =subclasses.iterator(); iter.hasNext();) { 359 java.lang.ref.WeakReference type_ref = (java.lang.ref.WeakReference )iter.next(); 360 PyType subtype = (PyType)type_ref.get(); 361 if (subtype == null) 362 continue; 363 result.append(subtype); 364 } 365 return result; 366 } 367 368 private synchronized void attachSubclass(PyType subtype) { 369 cleanup_subclasses(); 370 subclasses.add( 371 new java.lang.ref.WeakReference (subtype, subclasses_refq)); 372 } 373 374 private interface OnType { 375 boolean onType(PyType type); 376 } 377 378 private synchronized void traverse_hierarchy(boolean top, OnType behavior) { 379 boolean stop = false; 380 if (!top) { 381 stop = behavior.onType(this); 382 } 383 if (stop) 384 return; 385 for (java.util.Iterator iter = subclasses.iterator(); 386 iter.hasNext(); 387 ) { 388 java.lang.ref.WeakReference type_ref = 389 (java.lang.ref.WeakReference ) iter.next(); 390 PyType subtype = (PyType) type_ref.get(); 391 if (subtype == null) 392 continue; 393 subtype.traverse_hierarchy(false, behavior); 394 } 395 } 396 397 private static void fill_classic_mro(ArrayList acc,PyClass classic_cl) { 398 if(!acc.contains(classic_cl)) 399 acc.add(classic_cl); 400 PyObject[] bases = classic_cl.__bases__.getArray(); 401 for (int i=0; i <bases.length; i++) { 402 fill_classic_mro(acc,(PyClass)bases[i]); 403 } 404 } 405 406 private static PyObject[] classic_mro(PyClass classic_cl) { 407 ArrayList acc = new ArrayList (); 408 409 410 return (PyObject[])acc.toArray(new PyObject[0]); 411 } 412 413 private static boolean tail_contains(PyObject[] lst,int whence,PyObject o) { 414 int n = lst.length; 415 for (int i=whence+1; i < n; i++) { 416 if (lst[i] == o) 417 return true; 418 } 419 return false; 420 } 421 422 private static PyException mro_error(PyObject[][] to_merge,int[] remain) { 423 StringBuffer msg = new StringBuffer ("Cannot create a"+ 424 " consistent method resolution\norder (MRO) for bases "); 425 PyDictionary set = new PyDictionary(); 426 for (int i=0; i < to_merge.length; i++) { 427 PyObject[] lst = to_merge[i]; 428 if(remain[i] < lst.length) 429 set.__setitem__(lst[remain[i]],Py.None); 430 } 431 PyObject iter = set.__iter__(); 432 PyObject cur; 433 boolean subq = false; 434 while ((cur = iter.__iternext__()) != null) { 435 PyObject name = cur.__findattr__("__name__"); 436 if (!subq) { 437 subq = true; 438 } else { 439 msg.append(", "); 440 } 441 msg.append(name==null?"?":name.toString()); 442 } 443 return Py.TypeError(msg.toString()); 444 } 445 446 private static void debug(PyObject[] objs) { 447 System.out.println(new PyList(objs).toString()); 448 } 449 450 final PyObject[] type_mro() { 451 PyObject[] bases = this.bases; 452 int n = bases.length; 453 for (int i=0; i < n; i++) { 454 PyObject cur = bases[i]; 455 for (int j = i+1; j<n; j++) { 456 if (bases[j] == cur) { 457 PyObject name = cur.__findattr__("__name__"); 458 throw Py.TypeError("duplicate base class " + 459 (name==null?"?":name.toString())); 460 } 461 } 462 } 463 464 int nmerge = n+1; 465 466 PyObject[][] to_merge = new PyObject[nmerge][]; 467 int[] remain = new int[nmerge]; 468 469 for (int i=0; i < n; i++) { 470 PyObject cur = bases[i]; 471 remain[i] = 0; 472 if (cur instanceof PyType) { 473 to_merge[i] = ((PyType)cur).mro; 474 } else if (cur instanceof PyClass) { 475 to_merge[i] = classic_mro((PyClass)cur); 476 } 477 } 478 479 to_merge[n] = bases; 480 remain[n] = 0; 481 482 ArrayList acc = new ArrayList (); 483 acc.add(this); 484 485 int empty_cnt=0; 486 487 scan : for (int i = 0; i < nmerge; i++) { 488 PyObject candidate; 489 PyObject[] cur = to_merge[i]; 490 if (remain[i] >= cur.length) { 491 empty_cnt++; 492 continue scan; 493 } 494 495 candidate = cur[remain[i]]; 496 for (int j = 0; j < nmerge; j++) 497 if (tail_contains(to_merge[j],remain[j],candidate)) 498 continue scan; 499 acc.add(candidate); 500 for (int j = 0; j < nmerge; j++) { 501 if (remain[j]<to_merge[j].length && 502 to_merge[j][remain[j]]==candidate) 503 remain[j]++; 504 } 505 i = -1; 507 empty_cnt = 0; 508 } 509 if (empty_cnt == nmerge) { 510 return (PyObject[])acc.toArray(bases); 511 } 512 throw mro_error(to_merge,remain); 513 } 514 515 private static PyType solid_base(PyType base) { 516 PyObject[] mro = base.mro; 517 for (int i=0; i<mro.length; i++) { 518 PyObject parent = mro[i]; 519 if (parent instanceof PyType) { 520 PyType parent_type =(PyType)parent; 521 if (parent_type.underlying_class != null || parent_type.nuserslots != 0) 522 return parent_type; 523 } 524 } 525 throw Py.TypeError("base without solid base"); 526 } 527 528 private static PyType best_base(PyObject[] bases_list) { 529 PyType winner=null; 530 PyType candidate=null; 531 PyType base=null; 532 for (int i=0; i < bases_list.length;i++) { 533 PyObject base_proto = bases_list[i]; 534 if (base_proto instanceof PyClass) 535 continue; 536 if (!(base_proto instanceof PyType)) 537 throw Py.TypeError("bases must be types"); 538 PyType base_i = (PyType)base_proto; 539 candidate = solid_base(base_i); 540 if (winner == null) { 541 winner = candidate; 542 base = base_i; 543 } else if (winner.isSubType(candidate)) { 544 ; 545 } else if (candidate.isSubType(winner)) { 546 winner = candidate; 547 base = base_i; 548 } else { 549 throw Py.TypeError("multiple bases have instance lay-out conflict"); 550 } 551 } 552 if (base == null) 553 throw Py.TypeError("a new-style class can't have only classic bases"); 554 return base; 555 } 556 557 public static PyObject newType(PyObject new_,PyType metatype,String name,PyTuple bases,PyObject dict) { 558 PyType object_type = fromClass(PyObject.class); 559 560 PyObject[] bases_list = bases.getArray(); 561 PyType winner = metatype; 562 for (int i=0; i<bases_list.length; i++) { 563 PyObject bases_i = bases_list[i]; 564 if (bases_i instanceof PyJavaClass) 565 throw Py.TypeError("can't mix new-style and java classes"); 566 if (bases_i instanceof PyClass) { 567 if (((PyClass)bases_i).proxyClass != null) 568 throw Py.TypeError("can't mix new-style and java classes"); 569 continue; 570 } 571 PyType curtype = bases_i.getType(); 572 if (winner.isSubType(curtype)) 573 continue; 574 if (curtype.isSubType(winner)) { 575 winner = curtype; 576 continue; 577 } 578 throw Py.TypeError("metaclass conflict: "+ 579 "the metaclass of a derived class "+ 580 "must be a (non-strict) subclass "+ 581 "of the metaclasses of all its bases"); 582 } 583 if (winner != metatype) { 584 PyObject winner_new_ = winner.lookup("__new__"); 585 if (winner_new_ !=null && winner_new_ != new_) { 586 return invoke_new_(new_,winner,false,new PyObject[] {new PyString(name),bases,dict},Py.NoKeywords); 587 } 588 metatype = winner; 589 } 590 if (bases_list.length == 0) { 591 bases_list = new PyObject[] {object_type}; 592 } 593 594 PyType base = best_base(bases_list); 595 596 598 boolean needs_userdict = base.needs_userdict; 599 if (!needs_userdict) { 600 for (int i=0; i<bases_list.length;i++) { 601 PyObject cur = bases_list[i]; 602 if (cur != base) { 603 if ((cur instanceof PyType && ((PyType)cur).needs_userdict) || cur instanceof PyClass) { 604 needs_userdict = true; 605 break; 606 } 607 } 608 } 609 } 610 611 int nuserslots = base.nuserslots; 612 613 needs_userdict = true; 614 615 if (dict.__finditem__("__module__") == null) { 616 PyFrame frame = Py.getFrame(); 617 if (frame != null) { 618 PyObject globals = frame.f_globals; 619 PyObject modname; 620 if ((modname = globals.__finditem__("__name__")) != null) { 621 dict.__setitem__("__module__", modname); 622 } 623 } 624 } 625 626 629 PyType newtype = new PyType(); 631 newtype.name = name; 632 newtype.base = base; 633 newtype.bases = bases_list; 634 635 newtype.needs_userdict = needs_userdict; 636 newtype.nuserslots = nuserslots; 637 638 newtype.dict = dict; 639 640 PyObject tmp = dict.__finditem__("__new__"); 642 if (tmp != null && tmp instanceof PyFunction) { dict.__setitem__("__new__",new PyStaticMethod(tmp)); 644 } 645 646 PyObject mro_meth = null; 647 PyObject[] newmro; 648 649 if (metatype.underlying_class != PyType.class) 650 mro_meth = metatype.lookup("mro"); 651 652 if (mro_meth == null) { 653 newmro = newtype.type_mro(); 654 } else { 655 newmro = Py.make_array(mro_meth.__get__(newtype,metatype).__call__()); 656 } 657 658 newtype.mro = newmro; 659 660 if (needs_userdict && newtype.lookup("__dict__")==null) { 662 dict.__setitem__("__dict__",new PyGetSetDescr(newtype,"__dict__",PyObject.class,"getDict",null)); 663 } 664 665 newtype.has_set = newtype.lookup("__set__") != null; 666 newtype.has_delete = newtype.lookup("__delete__") != null; 667 668 newtype.needs_finalizer = newtype.lookup("__del__") != null; 669 670 for (int i=0; i<bases_list.length;i++) { 671 PyObject cur = bases_list[i]; 672 if (cur instanceof PyType) 673 ((PyType)cur).attachSubclass(newtype); 674 } 675 676 return newtype; 677 } 678 679 680 public String fastGetName() { 681 return name; 682 } 683 684 public boolean isSubType(PyType supertype) { 685 PyObject[] mro = this.mro; 686 for (int i = 0; i < mro.length; i++) { 687 if (mro[i] == supertype) 688 return true; 689 } 690 return false; 691 } 692 693 700 public PyObject lookup(String name) { 701 PyObject[] mro = this.mro; 702 for (int i = 0; i < mro.length; i++) { 703 PyObject dict = mro[i].fastGetDict(); 704 if (dict != null) { 705 PyObject obj = dict.__finditem__(name); 706 if (obj != null) 707 return obj; 708 } 709 } 710 return null; 711 } 712 713 public PyObject super_lookup(PyType ref,String name) { 714 PyObject[] mro = this.mro; 715 int i; 716 for (i=0; i < mro.length; i++) { 717 if (mro[i] == ref) 718 break; 719 } 720 i++; 721 for (; i < mro.length; i++) { 722 PyObject dict = mro[i].fastGetDict(); 723 if (dict != null) { 724 PyObject obj = dict.__finditem__(name); 725 if (obj != null) 726 return obj; 727 } 728 } 729 return null; 730 } 731 732 private PyType(boolean dummy) { 733 super(true); 734 } 735 736 private PyType() { 737 } 738 739 private static String decapitalize(String s) { 740 char c0 = s.charAt(0); 741 if (Character.isUpperCase(c0)) { 742 if (s.length() > 1 && Character.isUpperCase(s.charAt(1))) 743 return s; 744 char[] cs = s.toCharArray(); 745 cs[0] = Character.toLowerCase(c0); 746 return new String (cs); 747 } else { 748 return s; 749 } 750 } 751 752 private static String normalize_name(String name) { 753 if (name.endsWith("$")) 754 name = name.substring(0, name.length() - 1); 755 return name.intern(); 756 } 757 758 private static Object exposed_decl_get_object(Class c, String name) { 759 try { 760 return c.getDeclaredField("exposed_" + name).get(null); 761 } catch (NoSuchFieldException e) { 762 return null; 763 } catch (Exception e) { 764 throw error(e); 765 } 766 } 767 768 private final static String [] EMPTY = new String [0]; 769 770 private static PyException error(Exception e) { 771 return Py.JavaError(e); 772 } 773 774 private static Method get_non_static_method( 775 Class c, 776 String name, 777 Class [] parmtypes) { 778 try { 779 Method meth = c.getMethod(name, parmtypes); 780 if (!Modifier.isStatic(meth.getModifiers())) 781 return meth; 782 } catch (NoSuchMethodException e) { 783 } 784 return null; 785 } 786 787 private static Method get_descr_method( 788 Class c, 789 String name, 790 Class [] parmtypes) { 791 Method meth = get_non_static_method(c, name, parmtypes); 792 if (meth != null && meth.getDeclaringClass() != PyObject.class) { 793 return meth; 794 } 795 return null; 796 } 797 798 private static boolean ignore(Method meth) { 799 Class [] exceptions = meth.getExceptionTypes(); 800 for (int j = 0; j < exceptions.length; j++) { 801 if (exceptions[j] == PyIgnoreMethodTag.class) { 802 return true; 803 } 804 } 805 return false; 806 } 807 808 private final static Class [] O = { PyObject.class }; 809 private final static Class [] OO = { PyObject.class, PyObject.class }; 810 811 private static void fillFromClass( 812 PyType newtype, 813 String name, 814 Class c, 815 Class base, 816 boolean newstyle, 817 Method setup, 818 String [] exposed_methods) { 819 820 if (base == null) { 821 base = c.getSuperclass(); 822 } 823 824 if (name == null) { 825 name = c.getName(); 826 } 827 828 if (name.startsWith("org.python.core.Py")) { 829 name = name.substring("org.python.core.Py".length()).toLowerCase(); 830 } else { 831 int lastdot = name.lastIndexOf('.'); 832 if (lastdot != -1) { 833 name = name.substring(lastdot+1); 834 } 835 } 836 837 newtype.name = name; 838 839 newtype.underlying_class = c; 840 841 boolean top = false; 842 843 PyType[] mro = null; 845 if (base == Object .class) { 846 mro = new PyType[] { newtype }; 847 top = true; 848 } else { 849 PyType basetype = fromClass(base); 850 mro = new PyType[basetype.mro.length + 1]; 851 System.arraycopy(basetype.mro, 0, mro, 1, basetype.mro.length); 852 mro[0] = newtype; 853 854 newtype.base = basetype; 855 newtype.bases = new PyObject[] { basetype }; 856 } 857 newtype.mro = mro; 858 859 HashMap propnames = null; 860 if (!newstyle) 861 propnames = new HashMap (); 862 863 boolean only_exposed_methods = newstyle; 864 865 PyObject dict = new PyStringMap(); 866 867 if (only_exposed_methods) { 868 for (int i = 0; i < exposed_methods.length; i++) { 869 String methname = exposed_methods[i]; 870 dict.__setitem__( 871 normalize_name(methname), 872 new PyReflectedFunction(methname)); 873 } 874 } 875 876 Method [] methods = c.getMethods(); 877 for (int i = 0; i < methods.length; i++) { 878 Method meth = methods[i]; 879 880 Class declaring = meth.getDeclaringClass(); 881 if (declaring != base 882 && base.isAssignableFrom(declaring) 883 && !ignore(meth)) { 884 String methname = meth.getName(); 885 String nmethname = normalize_name(methname); 886 PyReflectedFunction reflfunc = 887 (PyReflectedFunction) dict.__finditem__(nmethname); 888 boolean added = false; 889 if (reflfunc == null) { 890 if (!only_exposed_methods) { 891 dict.__setitem__( 892 nmethname, 893 new PyReflectedFunction(meth)); 894 added = true; 895 } 896 } else { 897 reflfunc.addMethod(meth); 898 added = true; 899 } 900 if (propnames != null 901 && added 902 && !Modifier.isStatic(meth.getModifiers())) { 903 int n = meth.getParameterTypes().length; 905 if (methname.startsWith("get") && n == 0) { 906 propnames.put(methname.substring(3), "getter"); 907 } else if ( 908 methname.startsWith("is") 909 && n == 0 910 && meth.getReturnType() == Boolean.TYPE) { 911 propnames.put(methname.substring(2), "getter"); 912 } else if (methname.startsWith("set") && n == 1) { 913 propnames.put(methname.substring(3), meth); 914 } 915 } 916 917 } 918 919 } 920 921 boolean has_set = false, has_delete = false; 922 if (!top) { 923 if (get_descr_method(c, "__set__", OO) != null || 924 get_descr_method(c, "_doset", OO) != null) { 925 has_set = true; 926 } 927 928 if (get_descr_method(c, "__delete__", O) != null || 929 get_descr_method(c, "_dodel", O) != null) { 930 has_delete = true; 931 } 932 } 933 934 for (int i = 0; i < methods.length; i++) { 935 Method meth = methods[i]; 936 937 String nmethname = normalize_name(meth.getName()); 938 PyReflectedFunction reflfunc = 939 (PyReflectedFunction) dict.__finditem__(nmethname); 940 if (reflfunc != null) { 941 reflfunc.addMethod(meth); 942 } 943 944 } 945 946 if (!newstyle) { Field [] fields = c.getFields(); 948 949 for (int i = 0; i < fields.length; i++) { 950 Field field = fields[i]; 951 Class declaring = field.getDeclaringClass(); 952 if (declaring != base && base.isAssignableFrom(declaring)) { 953 String fldname = field.getName(); 954 int fldmods = field.getModifiers(); 955 Class fldtype = field.getType(); 956 if (Modifier.isStatic(fldmods)) { 957 if (fldname.equals("__class__") 959 && fldtype == PyClass.class) { 960 continue; 961 } else if ( 962 fldname.startsWith("__doc__") 963 && fldname.length() > 7 964 && fldtype == PyString.class) { 965 String fname = fldname.substring(7).intern(); 966 PyObject memb = dict.__finditem__(fname); 967 if (memb != null 968 && memb instanceof PyReflectedFunction) { 969 PyString doc = null; 970 try { 971 doc = (PyString) field.get(null); 972 } catch (IllegalAccessException e) { 973 throw error(e); 974 } 975 ((PyReflectedFunction) memb).__doc__ = doc; 976 } 977 978 } 979 } 980 dict.__setitem__( 981 normalize_name(fldname), 982 new PyReflectedField(field)); 983 } 984 985 } 986 987 for (Iterator iter = propnames.keySet().iterator(); 988 iter.hasNext(); 989 ) { 990 String propname = (String ) iter.next(); 991 String npropname = normalize_name(decapitalize(propname)); 992 PyObject prev = dict.__finditem__(npropname); 993 if (prev != null && prev instanceof PyReflectedFunction) { 994 continue; 995 } 996 Method getter = null; 997 Method setter = null; 998 Class proptype = null; 999 getter = 1000 get_non_static_method(c, "get" + propname, new Class [] { 1001 }); 1002 if (getter == null) 1003 getter = 1004 get_non_static_method(c, "is" + propname, new Class [] { 1005 }); 1006 if (getter != null) { 1007 proptype = getter.getReturnType(); 1008 setter = 1009 get_non_static_method( 1010 c, 1011 "set" + propname, 1012 new Class [] { proptype }); 1013 } else { 1014 Object o = propnames.get(propname); 1015 if (o instanceof Method ) { 1016 setter = (Method ) o; 1017 proptype = setter.getParameterTypes()[0]; 1018 } 1019 } 1020 if (setter != null || getter != null) { 1021 dict.__setitem__( 1022 npropname, 1023 new PyBeanProperty( 1024 npropname, 1025 proptype, 1026 getter, 1027 setter)); 1028 1029 } else { 1030 } 1032 } 1033 1034 Constructor [] ctrs = c.getConstructors(); 1035 if (ctrs.length != 0) { 1036 final PyReflectedConstructor reflctr = 1037 new PyReflectedConstructor("_new_impl"); 1038 for (int i = 0; i < ctrs.length; i++) { 1039 reflctr.addConstructor(ctrs[i]); 1040 } 1041 PyObject new_ = new PyNewWrapper(c, "__new__", -1, -1) { 1042 1043 public PyObject new_impl( 1044 boolean init, 1045 PyType subtype, 1046 PyObject[] args, 1047 String [] keywords) { 1048 return reflctr.make(args, keywords); 1049 } 1050 }; 1051 1052 dict.__setitem__("__new__", new_); 1053 } 1054 1055 if (ClassDictInit.class.isAssignableFrom(c) 1056 && c != ClassDictInit.class) { 1057 try { 1058 Method m = 1059 c.getMethod( 1060 "classDictInit", 1061 new Class [] { PyObject.class }); 1062 m.invoke(null, new Object [] { dict }); 1063 } catch (Exception exc) { 1064 throw error(exc); 1065 } 1066 } 1067 1068 } else { 1069 if (setup != null) { 1070 try { 1071 setup.invoke(null, new Object [] { dict, null }); 1072 } catch (Exception e) { 1073 throw error(e); 1074 } 1075 } 1076 newtype.non_instantiable = dict.__finditem__("__new__") == null; 1077 1078 } 1079 1080 newtype.has_set = has_set; 1081 newtype.has_delete = has_delete; 1082 newtype.dict = dict; 1083 } 1084 1085 private static HashMap class_to_type; 1086 1087 public static interface Newstyle { 1088 } 1089 1090 private static PyType addFromClass(Class c) { 1091 Method setup = null; 1092 boolean newstyle = Newstyle.class.isAssignableFrom(c); 1093 Class base = null; 1094 String name = null; 1095 String [] exposed_methods = null; 1096 try { 1097 setup = 1098 c.getDeclaredMethod( 1099 "typeSetup", 1100 new Class [] { PyObject.class, Newstyle.class }); 1101 newstyle = true; 1102 } catch (NoSuchMethodException e) { 1103 } catch (Exception e) { 1104 throw error(e); 1105 } 1106 if (newstyle) { base = (Class ) exposed_decl_get_object(c, "base"); 1108 name = (String ) exposed_decl_get_object(c, "name"); 1109 if (base == null) { 1110 Class cur = c; 1111 while (cur != PyObject.class) { 1112 Class exposed_as = 1113 (Class ) exposed_decl_get_object(cur, "as"); 1114 if (exposed_as != null) { 1115 PyType exposed_as_type = fromClass(exposed_as); 1116 class_to_type.put(c, exposed_as_type); 1117 return exposed_as_type; 1118 } 1119 cur = cur.getSuperclass(); 1120 } 1121 } 1122 exposed_methods = (String []) exposed_decl_get_object(c, "methods"); 1123 if (exposed_methods == null) 1124 exposed_methods = EMPTY; 1125 } 1126 PyType newtype = c == PyType.class ? new PyType(true) : new PyType(); 1127 class_to_type.put(c, newtype); 1128 fillFromClass(newtype, name, c, base, newstyle, setup, exposed_methods); 1129 return newtype; 1130 } 1131 1132 1151 1152 public static synchronized PyType fromClass(Class c) { 1153 if (class_to_type == null) { 1154 class_to_type = new HashMap (); 1155 addFromClass(PyType.class); 1156 } 1157 PyType type = (PyType) class_to_type.get(c); 1158 if (type != null) 1159 return type; 1160 return addFromClass(c); 1161 } 1162 1163 final PyObject type___findattr__(String name) { 1165 PyType metatype = getType(); 1166 1167 PyObject metaattr = metatype.lookup(name); 1168 PyObject res = null; 1169 1170 if (metaattr != null) { 1171 if (metaattr.isDataDescr()) { 1172 res = metaattr.__get__(this, metatype); 1173 if (res != null) 1174 return res; 1175 } 1176 } 1177 1178 PyObject attr = lookup(name); 1179 1180 if (attr != null) { 1181 res = attr.__get__(null, this); 1182 if (res != null) 1183 return res; 1184 } 1185 1186 if (metaattr != null) { 1187 return metaattr.__get__(this, metatype); 1188 } 1189 1190 return null; 1191 } 1192 1193 final void type___setattr__(String name, PyObject value) { 1194 super.__setattr__(name, value); 1195 if (name == "__set__") { 1196 if (!has_set && lookup("__set__") != null) { 1197 traverse_hierarchy(false, new OnType() { 1198 public boolean onType(PyType type) { 1199 boolean old = type.has_set; 1200 type.has_set = true; 1201 return old; 1202 } 1203 }); 1204 } 1205 } else if (name == "__delete__") { 1206 if (!has_delete && lookup("__delete__") != null) { 1207 traverse_hierarchy(false, new OnType() { 1208 public boolean onType(PyType type) { 1209 boolean old = type.has_delete; 1210 type.has_delete = true; 1211 return old; 1212 } 1213 }); 1214 } 1215 } 1216 1217 } 1218 1219 final void type___delattr__(String name) { 1220 super.__delattr__(name); 1221 if (name == "__set__") { 1222 if (has_set && lookup("__set__") == null) { 1223 traverse_hierarchy(false, new OnType() { 1224 public boolean onType(PyType type) { 1225 boolean absent = 1226 type.getDict().__finditem__("__set__") == null; 1227 if (absent) { 1228 type.has_set = false; 1229 return false; 1230 } 1231 return true; 1232 } 1233 }); 1234 } 1235 } else if (name == "__delete__") { 1236 if (has_set && lookup("__delete__") == null) { 1237 traverse_hierarchy(false, new OnType() { 1238 public boolean onType(PyType type) { 1239 boolean absent = 1240 type.getDict().__finditem__("__delete__") == null; 1241 if (absent) { 1242 type.has_delete = false; 1243 return false; 1244 } 1245 return true; 1246 } 1247 }); 1248 } 1249 } 1250 } 1251 1252 protected void __rawdir__(PyDictionary accum) { 1253 PyObject[] mro = this.mro; 1254 for (int i = 0; i < mro.length; i++) { 1255 mro[i].addKeys(accum, "__dict__"); 1256 } 1257 } 1258 1259 1262 public PyObject fastGetDict() { 1263 return dict; 1264 } 1265 1266 1267 public PyObject getDict() { return dict; 1269 } 1270 1271 public Object __tojava__(Class c) { 1272 if (c == Object .class || c == Class .class || c == Serializable .class) { 1273 return underlying_class; 1274 } 1275 return super.__tojava__(c); 1276 } 1277 1278 public PyObject getModule() { 1279 if (underlying_class != null) 1280 return new PyString("__builtin__"); 1281 return dict.__finditem__("__module__"); 1282 } 1283 1284 public String getFullName () { 1285 if (underlying_class != null) 1286 return name; 1287 PyObject mod = getModule(); 1288 if (mod != null) 1289 return mod.__str__()+"."+name; 1290 return name; 1291 } 1292 1293 public String toString() { 1294 if (underlying_class != null) 1295 return "<type '" + name + "'>"; 1296 return "<class '" + getFullName() + "'>"; 1297 } 1298 1299 1302 public PyObject __findattr__(String name) { 1303 return type___findattr__(name); 1304 } 1305 1306 1309 public void __delattr__(String name) { 1310 type___delattr__(name); 1311 } 1312 1313 1316 public void __setattr__(String name, PyObject value) { 1317 type___setattr__(name, value); 1318 } 1319 1320 1323 public String safeRepr() throws PyIgnoreMethodTag { 1324 return "type object '" + name + "'"; } 1326 1327 private static PyObject invoke_new_(PyObject new_,PyType type,boolean init,PyObject[] args,String [] keywords) { 1328 PyObject newobj; 1329 if (new_ instanceof PyNewWrapper) { 1330 newobj = ((PyNewWrapper) new_).new_impl(init, type, args, keywords); 1331 } else { 1332 int n = args.length; 1333 PyObject[] type_prepended = new PyObject[n + 1]; 1334 System.arraycopy(args, 0, type_prepended, 1, n); 1335 type_prepended[0] = type; 1336 newobj = new_.__get__(null, type).__call__(type_prepended, keywords); 1337 } 1338 newobj.dispatch__init__(type,args,keywords); 1339 return newobj; 1340 } 1341 1342 1343 1346 public PyObject __call__(PyObject[] args, String [] keywords) { 1347 return type___call__(args,keywords); 1348 } 1349 1350 final PyObject type___call__(PyObject[] args, String [] keywords) { 1351 PyObject new_ = lookup("__new__"); 1352 if (non_instantiable || new_ == null) { 1353 throw Py.TypeError("cannot create '" + name + "' instances"); 1354 } 1356 1357 return invoke_new_(new_,this,true,args,keywords); 1358 } 1359 1360} 1361 | Popular Tags |