summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Ruby <rubys@php.net>1999-12-06 05:00:40 +0000
committerSam Ruby <rubys@php.net>1999-12-06 05:00:40 +0000
commit0d7c37b0bf79a5e1f6e453ba07e385c0a3692e97 (patch)
tree322dbfa79f3ffcd4c371687c1d2af0994fac1ef6
parenteee0bdadc47fea97876150907c8d557427c24ff6 (diff)
downloadphp-git-0d7c37b0bf79a5e1f6e453ba07e385c0a3692e97.tar.gz
first pass at method overloading
-rw-r--r--ext/java/reflect.java94
-rw-r--r--ext/rpc/java/reflect.java94
2 files changed, 176 insertions, 12 deletions
diff --git a/ext/java/reflect.java b/ext/java/reflect.java
index f4b3829d3a..f4ec06d980 100644
--- a/ext/java/reflect.java
+++ b/ext/java/reflect.java
@@ -19,7 +19,7 @@
package net.php;
import java.lang.reflect.*;
-import java.util.ResourceBundle;
+import java.util.*;
import java.beans.*;
class reflect {
@@ -115,28 +115,110 @@ class reflect {
}
//
+ // Select the best match from a list of methods
+ //
+ private static Method select(Vector methods, Object args[]) {
+ if (methods.size() == 1) return (Method) methods.firstElement();
+
+ Method selected = null;
+ int best = Integer.MAX_VALUE;
+
+ for (Enumeration e = methods.elements(); e.hasMoreElements(); ) {
+ Method method = (Method)e.nextElement();
+ int weight=0;
+ Class parms[] = method.getParameterTypes();
+ for (int i=0; i<parms.length; i++) {
+ if (parms[i].isInstance(args[i])) {
+ for (Class c=parms[i]; (c=c.getSuperclass()) != null; ) {
+ if (!c.isInstance(args[i])) break;
+ weight++;
+ }
+ } else if (parms[i].isPrimitive()) {
+ Class c=parms[i];
+ if (args[i] instanceof Number) {
+ if (c==Boolean.TYPE) weight+=5;
+ if (c==Character.TYPE) weight+=4;
+ if (c==Byte.TYPE) weight+=3;
+ if (c==Short.TYPE) weight+=2;
+ if (c==Integer.TYPE) weight++;
+ if (c==Float.TYPE) weight++;
+ } else if (args[i] instanceof Boolean) {
+ if (c!=Boolean.TYPE) weight+=9999;
+ } else if (args[i] instanceof String) {
+ if (c== Character.TYPE || ((String)args[i]).length()>0)
+ weight+=((String)args[i]).length();
+ else
+ weight+=9999;
+ } else {
+ weight+=9999;
+ }
+ } else {
+ weight+=9999;
+ }
+ }
+
+ if (weight < best) {
+ if (weight == 0) return method;
+ best = weight;
+ selected = method;
+ }
+ }
+
+ return selected;
+ }
+
+ //
+ // Select the best match from a list of methods
+ //
+ private static Object[] coerce(Method method, Object args[]) {
+ Object result[] = args;
+ Class parms[] = method.getParameterTypes();
+ for (int i=0; i<args.length; i++) {
+ if (parms[i].isInstance(args[i])) continue;
+ if (args[i] instanceof Number && parms[i].isPrimitive()) {
+ if (result==args) result=(Object[])result.clone();
+ Class c = parms[i];
+ Number n = (Number)args[i];
+ if (c == Boolean.TYPE) result[i]=new Boolean(0.0!=n.floatValue());
+ if (c == Byte.TYPE) result[i]=new Byte(n.byteValue());
+ if (c == Short.TYPE) result[i]=new Short(n.shortValue());
+ if (c == Integer.TYPE) result[i]=new Integer(n.intValue());
+ if (c == Float.TYPE) result[i]=new Float(n.floatValue());
+ if (c == Long.TYPE && !(n instanceof Long))
+ result[i]=new Long(n.longValue());
+ }
+ }
+ return result;
+ }
+
+ //
// Invoke a method on a given object
//
public static void Invoke
(Object object, String method, Object args[], long result)
{
try {
+ Vector matches = new Vector();
+ // gather
for (Class jclass = object.getClass();;jclass=(Class)object) {
Method methods[] = jclass.getMethods();
for (int i=0; i<methods.length; i++) {
if (methods[i].getName().equalsIgnoreCase(method) &&
methods[i].getParameterTypes().length == args.length) {
- setResult(result, methods[i].invoke(object, args));
- return;
+ matches.addElement(methods[i]);
}
}
// try a second time with the object itself, if it is of type Class
- if (!(jclass instanceof Class) || (jclass==object)) break;
+ if (!(object instanceof Class) || (jclass==object)) break;
}
- throw new NoSuchMethodException(method);
+ Method selected = select(matches, args);
+ if (selected == null) throw new NoSuchMethodException(method);
+
+ Object coercedArgs[] = coerce(selected, args);
+ setResult(result, selected.invoke(object, coercedArgs));
} catch (Exception e) {
setException(result, e);
@@ -180,7 +262,7 @@ class reflect {
}
// try a second time with the object itself, if it is of type Class
- if (!(jclass instanceof Class) || (jclass==object)) break;
+ if (!(object instanceof Class) || (jclass==object)) break;
}
} catch (Exception e) {
diff --git a/ext/rpc/java/reflect.java b/ext/rpc/java/reflect.java
index f4b3829d3a..f4ec06d980 100644
--- a/ext/rpc/java/reflect.java
+++ b/ext/rpc/java/reflect.java
@@ -19,7 +19,7 @@
package net.php;
import java.lang.reflect.*;
-import java.util.ResourceBundle;
+import java.util.*;
import java.beans.*;
class reflect {
@@ -115,28 +115,110 @@ class reflect {
}
//
+ // Select the best match from a list of methods
+ //
+ private static Method select(Vector methods, Object args[]) {
+ if (methods.size() == 1) return (Method) methods.firstElement();
+
+ Method selected = null;
+ int best = Integer.MAX_VALUE;
+
+ for (Enumeration e = methods.elements(); e.hasMoreElements(); ) {
+ Method method = (Method)e.nextElement();
+ int weight=0;
+ Class parms[] = method.getParameterTypes();
+ for (int i=0; i<parms.length; i++) {
+ if (parms[i].isInstance(args[i])) {
+ for (Class c=parms[i]; (c=c.getSuperclass()) != null; ) {
+ if (!c.isInstance(args[i])) break;
+ weight++;
+ }
+ } else if (parms[i].isPrimitive()) {
+ Class c=parms[i];
+ if (args[i] instanceof Number) {
+ if (c==Boolean.TYPE) weight+=5;
+ if (c==Character.TYPE) weight+=4;
+ if (c==Byte.TYPE) weight+=3;
+ if (c==Short.TYPE) weight+=2;
+ if (c==Integer.TYPE) weight++;
+ if (c==Float.TYPE) weight++;
+ } else if (args[i] instanceof Boolean) {
+ if (c!=Boolean.TYPE) weight+=9999;
+ } else if (args[i] instanceof String) {
+ if (c== Character.TYPE || ((String)args[i]).length()>0)
+ weight+=((String)args[i]).length();
+ else
+ weight+=9999;
+ } else {
+ weight+=9999;
+ }
+ } else {
+ weight+=9999;
+ }
+ }
+
+ if (weight < best) {
+ if (weight == 0) return method;
+ best = weight;
+ selected = method;
+ }
+ }
+
+ return selected;
+ }
+
+ //
+ // Select the best match from a list of methods
+ //
+ private static Object[] coerce(Method method, Object args[]) {
+ Object result[] = args;
+ Class parms[] = method.getParameterTypes();
+ for (int i=0; i<args.length; i++) {
+ if (parms[i].isInstance(args[i])) continue;
+ if (args[i] instanceof Number && parms[i].isPrimitive()) {
+ if (result==args) result=(Object[])result.clone();
+ Class c = parms[i];
+ Number n = (Number)args[i];
+ if (c == Boolean.TYPE) result[i]=new Boolean(0.0!=n.floatValue());
+ if (c == Byte.TYPE) result[i]=new Byte(n.byteValue());
+ if (c == Short.TYPE) result[i]=new Short(n.shortValue());
+ if (c == Integer.TYPE) result[i]=new Integer(n.intValue());
+ if (c == Float.TYPE) result[i]=new Float(n.floatValue());
+ if (c == Long.TYPE && !(n instanceof Long))
+ result[i]=new Long(n.longValue());
+ }
+ }
+ return result;
+ }
+
+ //
// Invoke a method on a given object
//
public static void Invoke
(Object object, String method, Object args[], long result)
{
try {
+ Vector matches = new Vector();
+ // gather
for (Class jclass = object.getClass();;jclass=(Class)object) {
Method methods[] = jclass.getMethods();
for (int i=0; i<methods.length; i++) {
if (methods[i].getName().equalsIgnoreCase(method) &&
methods[i].getParameterTypes().length == args.length) {
- setResult(result, methods[i].invoke(object, args));
- return;
+ matches.addElement(methods[i]);
}
}
// try a second time with the object itself, if it is of type Class
- if (!(jclass instanceof Class) || (jclass==object)) break;
+ if (!(object instanceof Class) || (jclass==object)) break;
}
- throw new NoSuchMethodException(method);
+ Method selected = select(matches, args);
+ if (selected == null) throw new NoSuchMethodException(method);
+
+ Object coercedArgs[] = coerce(selected, args);
+ setResult(result, selected.invoke(object, coercedArgs));
} catch (Exception e) {
setException(result, e);
@@ -180,7 +262,7 @@ class reflect {
}
// try a second time with the object itself, if it is of type Class
- if (!(jclass instanceof Class) || (jclass==object)) break;
+ if (!(object instanceof Class) || (jclass==object)) break;
}
} catch (Exception e) {