summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-01-03 18:32:22 +0000
committerRich Hickey <richhickey@gmail.com>2008-01-03 18:32:22 +0000
commit368c7989e33ecb50b59de48a71fe3c96c6b0c483 (patch)
tree0d74ed0db4b5bd66ea79c65d1084874a3afff306 /src
parent3d14de92f6d7ce58b9f56f9e6112ddb8c5721a38 (diff)
same arity overload resolution in ctors and methods
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj2
-rw-r--r--src/jvm/clojure/lang/Compiler.java60
-rw-r--r--src/jvm/clojure/lang/RT.java3
-rw-r--r--src/jvm/clojure/lang/Reflector.java36
4 files changed, 78 insertions, 23 deletions
diff --git a/src/boot.clj b/src/boot.clj
index c1df6230..9e71bb93 100644
--- a/src/boot.clj
+++ b/src/boot.clj
@@ -908,7 +908,7 @@
(. q (put (f (first job))))
(recur))))
tasks (doseq dnu (map (fn [task]
- (. exec (submit task)))
+ (. exec (submit #^java.util.concurrent.Callable task)))
(replicate nthreads produce)))
consume (fn []
(if (sync nil (and (or @todo (pos? @out))
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 3df045ce..d9567c31 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -67,6 +67,7 @@ static final Symbol HASHMAP = Symbol.create("clojure", "hash-map");
static final Symbol VECTOR = Symbol.create("clojure", "vector");
static final Symbol _AMP_ = Symbol.create("&");
+static final Symbol ISEQ = Symbol.create("clojure.lang.ISeq");
//static final Symbol IMPORT = Symbol.create("import");
//static final Symbol USE = Symbol.create("use");
@@ -867,7 +868,17 @@ static class InstanceMethodExpr extends MethodExpr{
method = null;
//throw new IllegalArgumentException("No matching method found");
else
- method = (java.lang.reflect.Method) ((methods.size() == 1) ? methods.get(0) : null);
+ {
+ int methodidx = 0;
+ if(methods.size() > 1)
+ {
+ ArrayList<Class[]> params = new ArrayList();
+ for(int i = 0; i < methods.size(); i++)
+ params.add(((java.lang.reflect.Method) methods.get(i)).getParameterTypes());
+ methodidx = getMatchingParams(params, args);
+ }
+ method = (java.lang.reflect.Method) (methodidx >= 0 ? methods.get(methodidx) : null);
+ }
}
else
method = null;
@@ -928,7 +939,7 @@ static class StaticMethodExpr extends MethodExpr{
public StaticMethodExpr(int line, String className, String methodName, IPersistentVector args)
- throws ClassNotFoundException{
+ throws Exception{
this.className = className;
this.methodName = methodName;
this.args = args;
@@ -937,7 +948,16 @@ static class StaticMethodExpr extends MethodExpr{
List methods = Reflector.getMethods(Class.forName(className), args.count(), methodName, true);
if(methods.isEmpty())
throw new IllegalArgumentException("No matching method: " + methodName);
- method = (java.lang.reflect.Method) ((methods.size() == 1) ? methods.get(0) : null);
+
+ int methodidx = 0;
+ if(methods.size() > 1)
+ {
+ ArrayList<Class[]> params = new ArrayList();
+ for(int i = 0; i < methods.size(); i++)
+ params.add(((java.lang.reflect.Method) methods.get(i)).getParameterTypes());
+ methodidx = getMatchingParams(params, args);
+ }
+ method = (java.lang.reflect.Method) (methodidx >= 0 ? methods.get(methodidx) : null);
}
public Object eval() throws Exception{
@@ -1525,6 +1545,24 @@ static class ClassExpr implements Expr{
}
}
+static int getMatchingParams(ArrayList<Class[]> paramlists, IPersistentVector argexprs) throws Exception{
+ //presumes matching lengths
+ for(int i = 0; i < paramlists.size(); i++)
+ {
+ boolean match = true;
+ ISeq aseq = argexprs.seq();
+ for(int p = 0; match && p < argexprs.count() && aseq != null; ++p, aseq = aseq.rest())
+ {
+ Expr arg = (Expr) aseq.first();
+ Class aclass = arg.hasJavaClass()? arg.getJavaClass():Object.class;
+ match = Reflector.paramArgTypeMatch(paramlists.get(i)[p], aclass);
+ }
+ if(match)
+ return i;
+ }
+ return -1;
+}
+
static class NewExpr implements Expr{
final String className;
final IPersistentVector args;
@@ -1535,22 +1573,32 @@ static class NewExpr implements Expr{
final static Method forNameMethod = Method.getMethod("Class forName(String)");
- public NewExpr(String className, IPersistentVector args) throws ClassNotFoundException{
+ public NewExpr(String className, IPersistentVector args) throws Exception{
this.args = args;
this.className = className;
this.c = Class.forName(className);
Constructor[] allctors = c.getConstructors();
ArrayList ctors = new ArrayList();
+ ArrayList<Class[]> params = new ArrayList();
for(int i = 0; i < allctors.length; i++)
{
Constructor ctor = allctors[i];
if(ctor.getParameterTypes().length == args.count())
+ {
ctors.add(ctor);
+ params.add(ctor.getParameterTypes());
+ }
}
if(ctors.isEmpty())
throw new IllegalArgumentException("No matching ctor found");
- this.ctor = (ctors.size() == 1) ? (Constructor) ctors.get(0) : null;
+ int ctoridx = 0;
+ if(ctors.size() > 1)
+ {
+ ctoridx = getMatchingParams(params, args);
+ }
+
+ this.ctor = ctoridx >= 0 ? (Constructor) ctors.get(ctoridx) : null;
}
public Object eval() throws Exception{
@@ -2415,7 +2463,7 @@ static class FnMethod{
else
{
- LocalBinding lb = registerLocal(p, tagOf(p), null);
+ LocalBinding lb = registerLocal(p, state==PSTATE.REST?ISEQ:tagOf(p), null);
argLocals = argLocals.cons(lb);
switch(state)
{
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index 48a6b71f..9f517012 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -162,6 +162,9 @@ static public final Object[] EMPTY_ARRAY = new Object[]{};
//static public final Character[] chars;
static AtomicInteger id = new AtomicInteger(1);
+static{
+OUT.setTag(Symbol.create("java.io.PrintStream"));
+}
//static
// {
// chars = new Character[256];
diff --git a/src/jvm/clojure/lang/Reflector.java b/src/jvm/clojure/lang/Reflector.java
index 3c3239ab..32560cdb 100644
--- a/src/jvm/clojure/lang/Reflector.java
+++ b/src/jvm/clojure/lang/Reflector.java
@@ -288,21 +288,25 @@ static Object[] boxArgs(Class[] params, Object[] args){
return ret;
}
-static public boolean primBoxTypeMatch(Class primType, Class boxType){
- if(primType == int.class)
- return boxType == Integer.class || boxType == FixNum.class;
- else if(primType == float.class)
- return boxType == Float.class;
- else if(primType == double.class)
- return boxType == Double.class || boxType == DoubleNum.class;
- else if(primType == long.class)
- return boxType == Long.class || boxType == BigNum.class;
- else if(primType == char.class)
- return boxType == Character.class;
- else if(primType == short.class)
- return boxType == Short.class;
- else if(primType == byte.class)
- return boxType == Byte.class;
+static public boolean paramArgTypeMatch(Class paramType, Class argType){
+ if(paramType == argType || paramType.isAssignableFrom(argType))
+ return true;
+ if(paramType == int.class)
+ return argType == Integer.class || argType == FixNum.class;
+ else if(paramType == float.class)
+ return argType == Float.class;
+ else if(paramType == double.class)
+ return argType == Double.class || argType == DoubleNum.class;
+ else if(paramType == long.class)
+ return argType == Long.class || argType == BigNum.class;
+ else if(paramType == char.class)
+ return argType == Character.class;
+ else if(paramType == short.class)
+ return argType == Short.class;
+ else if(paramType == byte.class)
+ return argType == Byte.class;
+ else if(paramType == boolean.class)
+ return argType == Boolean.class;
return false;
}
@@ -327,7 +331,7 @@ static boolean isCongruent(Class[] params, Object[] args){
if(arg == null)
ret = false;
else
- ret = primBoxTypeMatch(paramType, argType);
+ ret = paramArgTypeMatch(paramType, argType);
}
else
{