Changeset 12302
- Timestamp:
- 12/22/09 18:48:55 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/abcl/src/org/armedbear/lisp/Java.java
r12299 r12302 641 641 String methodName = methodArg.getStringValue(); 642 642 Class c = instance.getClass(); 643 // FIXME Use the actual args, not just the count! 644 method = findMethod(c, methodName, args.length - 2); 643 method = findMethod(c, methodName, args); 645 644 } else 646 645 method = (Method) JavaObject.getObject(methodArg); … … 678 677 } 679 678 680 // FIXME This just returns the first matching method that it finds. Allegro 681 // signals a continuable error if there are multiple matching methods. 682 private static Method findMethod(Class c, String methodName, int argCount) 683 { 679 private static Method findMethod(Class<?> c, String methodName, LispObject[] args) throws NoSuchMethodException { 680 int argCount = args.length - 2; 681 Object[] javaArgs = new Object[argCount]; 682 for (int i = 0; i < argCount; ++i) { 683 Object x = args[i + 2]; 684 if (x == NIL) { 685 javaArgs[i] = null; 686 } else { 687 javaArgs[i] = ((LispObject) x).javaInstance(); 688 } 689 } 684 690 Method[] methods = c.getMethods(); 691 Method result = null; 685 692 for (int i = methods.length; i-- > 0;) { 686 693 Method method = methods[i]; 687 if (method.getName().equals(methodName)) 688 if (method.getParameterTypes().length == argCount) 689 return method; 690 } 691 return null; 694 if (!method.getName().equals(methodName)) { 695 continue; 696 } 697 if (method.getParameterTypes().length != argCount) { 698 continue; 699 } 700 Class<?>[] methodTypes = (Class<?>[]) method.getParameterTypes(); 701 if (!isApplicableMethod(methodTypes, javaArgs)) { 702 continue; 703 } 704 if (result == null || isMoreSpecialized(method, result)) { 705 result = method; 706 } 707 } 708 if (result == null) { 709 throw new NoSuchMethodException(methodName); 710 } 711 return result; 712 } 713 714 private static boolean isApplicableMethod(Class<?>[] methodTypes, 715 Object[] args) { 716 for (int i = 0; i < methodTypes.length; ++i) { 717 Class<?> methodType = methodTypes[i]; 718 Object arg = args[i]; 719 if (methodType.isPrimitive()) { 720 Class<?> x = getBoxedClass(methodType); 721 if (!x.isInstance(arg)) { 722 return false; 723 } 724 } else if (arg != null && !methodType.isInstance(arg)) { 725 return false; 726 } 727 } 728 return true; 729 } 730 731 private static boolean isMoreSpecialized(Method x, Method y) { 732 Class<?>[] xtypes = x.getParameterTypes(); 733 Class<?>[] ytypes = y.getParameterTypes(); 734 for (int i = 0; i < xtypes.length; ++i) { 735 Class<?> xtype = xtypes[i]; 736 if (xtype.isPrimitive()) { 737 xtype = getBoxedClass(xtype); 738 } 739 Class<?> ytype = ytypes[i]; 740 if (ytype.isPrimitive()) { 741 ytype = getBoxedClass(ytype); 742 } 743 if (xtype.equals(ytype)) { 744 continue; 745 } 746 if (ytype.isAssignableFrom(xtype)) { 747 return true; 748 } 749 } 750 return false; 751 } 752 753 private static Class<?> getBoxedClass(Class<?> clazz) { 754 if (clazz.equals(int.class)) { 755 return Integer.class; 756 } else if (clazz.equals(boolean.class)) { 757 return Boolean.class; 758 } else if (clazz.equals(byte.class)) { 759 return Byte.class; 760 } else if (clazz.equals(char.class)) { 761 return Character.class; 762 } else if (clazz.equals(long.class)) { 763 return Long.class; 764 } else if (clazz.equals(float.class)) { 765 return Float.class; 766 } else if (clazz.equals(double.class)) { 767 return Double.class; 768 } else if (clazz.equals(short.class)) { 769 return Short.class; 770 } else { // if (methodType.equals(void.class)) 771 return Void.class; 772 } 692 773 } 693 774
Note: See TracChangeset
for help on using the changeset viewer.