Skip to content

Commit 0d7c37b

Browse files
author
Sam Ruby
committed
first pass at method overloading
1 parent eee0bda commit 0d7c37b

File tree

2 files changed

+176
-12
lines changed

2 files changed

+176
-12
lines changed

ext/java/reflect.java

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
package net.php;
2020

2121
import java.lang.reflect.*;
22-
import java.util.ResourceBundle;
22+
import java.util.*;
2323
import java.beans.*;
2424

2525
class reflect {
@@ -114,29 +114,111 @@ public static void CreateObject(String name, Object args[], long result) {
114114
}
115115
}
116116

117+
//
118+
// Select the best match from a list of methods
119+
//
120+
private static Method select(Vector methods, Object args[]) {
121+
if (methods.size() == 1) return (Method) methods.firstElement();
122+
123+
Method selected = null;
124+
int best = Integer.MAX_VALUE;
125+
126+
for (Enumeration e = methods.elements(); e.hasMoreElements(); ) {
127+
Method method = (Method)e.nextElement();
128+
int weight=0;
129+
Class parms[] = method.getParameterTypes();
130+
for (int i=0; i<parms.length; i++) {
131+
if (parms[i].isInstance(args[i])) {
132+
for (Class c=parms[i]; (c=c.getSuperclass()) != null; ) {
133+
if (!c.isInstance(args[i])) break;
134+
weight++;
135+
}
136+
} else if (parms[i].isPrimitive()) {
137+
Class c=parms[i];
138+
if (args[i] instanceof Number) {
139+
if (c==Boolean.TYPE) weight+=5;
140+
if (c==Character.TYPE) weight+=4;
141+
if (c==Byte.TYPE) weight+=3;
142+
if (c==Short.TYPE) weight+=2;
143+
if (c==Integer.TYPE) weight++;
144+
if (c==Float.TYPE) weight++;
145+
} else if (args[i] instanceof Boolean) {
146+
if (c!=Boolean.TYPE) weight+=9999;
147+
} else if (args[i] instanceof String) {
148+
if (c== Character.TYPE || ((String)args[i]).length()>0)
149+
weight+=((String)args[i]).length();
150+
else
151+
weight+=9999;
152+
} else {
153+
weight+=9999;
154+
}
155+
} else {
156+
weight+=9999;
157+
}
158+
}
159+
160+
if (weight < best) {
161+
if (weight == 0) return method;
162+
best = weight;
163+
selected = method;
164+
}
165+
}
166+
167+
return selected;
168+
}
169+
170+
//
171+
// Select the best match from a list of methods
172+
//
173+
private static Object[] coerce(Method method, Object args[]) {
174+
Object result[] = args;
175+
Class parms[] = method.getParameterTypes();
176+
for (int i=0; i<args.length; i++) {
177+
if (parms[i].isInstance(args[i])) continue;
178+
if (args[i] instanceof Number && parms[i].isPrimitive()) {
179+
if (result==args) result=(Object[])result.clone();
180+
Class c = parms[i];
181+
Number n = (Number)args[i];
182+
if (c == Boolean.TYPE) result[i]=new Boolean(0.0!=n.floatValue());
183+
if (c == Byte.TYPE) result[i]=new Byte(n.byteValue());
184+
if (c == Short.TYPE) result[i]=new Short(n.shortValue());
185+
if (c == Integer.TYPE) result[i]=new Integer(n.intValue());
186+
if (c == Float.TYPE) result[i]=new Float(n.floatValue());
187+
if (c == Long.TYPE && !(n instanceof Long))
188+
result[i]=new Long(n.longValue());
189+
}
190+
}
191+
return result;
192+
}
193+
117194
//
118195
// Invoke a method on a given object
119196
//
120197
public static void Invoke
121198
(Object object, String method, Object args[], long result)
122199
{
123200
try {
201+
Vector matches = new Vector();
124202

203+
// gather
125204
for (Class jclass = object.getClass();;jclass=(Class)object) {
126205
Method methods[] = jclass.getMethods();
127206
for (int i=0; i<methods.length; i++) {
128207
if (methods[i].getName().equalsIgnoreCase(method) &&
129208
methods[i].getParameterTypes().length == args.length) {
130-
setResult(result, methods[i].invoke(object, args));
131-
return;
209+
matches.addElement(methods[i]);
132210
}
133211
}
134212

135213
// try a second time with the object itself, if it is of type Class
136-
if (!(jclass instanceof Class) || (jclass==object)) break;
214+
if (!(object instanceof Class) || (jclass==object)) break;
137215
}
138216

139-
throw new NoSuchMethodException(method);
217+
Method selected = select(matches, args);
218+
if (selected == null) throw new NoSuchMethodException(method);
219+
220+
Object coercedArgs[] = coerce(selected, args);
221+
setResult(result, selected.invoke(object, coercedArgs));
140222

141223
} catch (Exception e) {
142224
setException(result, e);
@@ -180,7 +262,7 @@ public static void CreateObject(String name, Object args[], long result) {
180262
}
181263

182264
// try a second time with the object itself, if it is of type Class
183-
if (!(jclass instanceof Class) || (jclass==object)) break;
265+
if (!(object instanceof Class) || (jclass==object)) break;
184266
}
185267

186268
} catch (Exception e) {

ext/rpc/java/reflect.java

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
package net.php;
2020

2121
import java.lang.reflect.*;
22-
import java.util.ResourceBundle;
22+
import java.util.*;
2323
import java.beans.*;
2424

2525
class reflect {
@@ -114,29 +114,111 @@ public static void CreateObject(String name, Object args[], long result) {
114114
}
115115
}
116116

117+
//
118+
// Select the best match from a list of methods
119+
//
120+
private static Method select(Vector methods, Object args[]) {
121+
if (methods.size() == 1) return (Method) methods.firstElement();
122+
123+
Method selected = null;
124+
int best = Integer.MAX_VALUE;
125+
126+
for (Enumeration e = methods.elements(); e.hasMoreElements(); ) {
127+
Method method = (Method)e.nextElement();
128+
int weight=0;
129+
Class parms[] = method.getParameterTypes();
130+
for (int i=0; i<parms.length; i++) {
131+
if (parms[i].isInstance(args[i])) {
132+
for (Class c=parms[i]; (c=c.getSuperclass()) != null; ) {
133+
if (!c.isInstance(args[i])) break;
134+
weight++;
135+
}
136+
} else if (parms[i].isPrimitive()) {
137+
Class c=parms[i];
138+
if (args[i] instanceof Number) {
139+
if (c==Boolean.TYPE) weight+=5;
140+
if (c==Character.TYPE) weight+=4;
141+
if (c==Byte.TYPE) weight+=3;
142+
if (c==Short.TYPE) weight+=2;
143+
if (c==Integer.TYPE) weight++;
144+
if (c==Float.TYPE) weight++;
145+
} else if (args[i] instanceof Boolean) {
146+
if (c!=Boolean.TYPE) weight+=9999;
147+
} else if (args[i] instanceof String) {
148+
if (c== Character.TYPE || ((String)args[i]).length()>0)
149+
weight+=((String)args[i]).length();
150+
else
151+
weight+=9999;
152+
} else {
153+
weight+=9999;
154+
}
155+
} else {
156+
weight+=9999;
157+
}
158+
}
159+
160+
if (weight < best) {
161+
if (weight == 0) return method;
162+
best = weight;
163+
selected = method;
164+
}
165+
}
166+
167+
return selected;
168+
}
169+
170+
//
171+
// Select the best match from a list of methods
172+
//
173+
private static Object[] coerce(Method method, Object args[]) {
174+
Object result[] = args;
175+
Class parms[] = method.getParameterTypes();
176+
for (int i=0; i<args.length; i++) {
177+
if (parms[i].isInstance(args[i])) continue;
178+
if (args[i] instanceof Number && parms[i].isPrimitive()) {
179+
if (result==args) result=(Object[])result.clone();
180+
Class c = parms[i];
181+
Number n = (Number)args[i];
182+
if (c == Boolean.TYPE) result[i]=new Boolean(0.0!=n.floatValue());
183+
if (c == Byte.TYPE) result[i]=new Byte(n.byteValue());
184+
if (c == Short.TYPE) result[i]=new Short(n.shortValue());
185+
if (c == Integer.TYPE) result[i]=new Integer(n.intValue());
186+
if (c == Float.TYPE) result[i]=new Float(n.floatValue());
187+
if (c == Long.TYPE && !(n instanceof Long))
188+
result[i]=new Long(n.longValue());
189+
}
190+
}
191+
return result;
192+
}
193+
117194
//
118195
// Invoke a method on a given object
119196
//
120197
public static void Invoke
121198
(Object object, String method, Object args[], long result)
122199
{
123200
try {
201+
Vector matches = new Vector();
124202

203+
// gather
125204
for (Class jclass = object.getClass();;jclass=(Class)object) {
126205
Method methods[] = jclass.getMethods();
127206
for (int i=0; i<methods.length; i++) {
128207
if (methods[i].getName().equalsIgnoreCase(method) &&
129208
methods[i].getParameterTypes().length == args.length) {
130-
setResult(result, methods[i].invoke(object, args));
131-
return;
209+
matches.addElement(methods[i]);
132210
}
133211
}
134212

135213
// try a second time with the object itself, if it is of type Class
136-
if (!(jclass instanceof Class) || (jclass==object)) break;
214+
if (!(object instanceof Class) || (jclass==object)) break;
137215
}
138216

139-
throw new NoSuchMethodException(method);
217+
Method selected = select(matches, args);
218+
if (selected == null) throw new NoSuchMethodException(method);
219+
220+
Object coercedArgs[] = coerce(selected, args);
221+
setResult(result, selected.invoke(object, coercedArgs));
140222

141223
} catch (Exception e) {
142224
setException(result, e);
@@ -180,7 +262,7 @@ public static void CreateObject(String name, Object args[], long result) {
180262
}
181263

182264
// try a second time with the object itself, if it is of type Class
183-
if (!(jclass instanceof Class) || (jclass==object)) break;
265+
if (!(object instanceof Class) || (jclass==object)) break;
184266
}
185267

186268
} catch (Exception e) {

0 commit comments

Comments
 (0)