diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-05-08 20:10:48 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-05-08 20:10:48 +0000 |
commit | 56dc8bc5e6fdfd3e358e4c0d0428ce3067485f4d (patch) | |
tree | 699c718154eea4094a97ecf2b0416c7d14d8622a /src/jvm | |
parent | be302bb20730215bfa584ba0ca2c577f15b2d4c8 (diff) |
first steps in improving modularity - moving classname resolution towards consumer in: new, static calls, class literals and import. Note import is now a macro (but tolerant of quotes for backwards compatibility)
Diffstat (limited to 'src/jvm')
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 58 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Namespace.java | 5 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 4 |
3 files changed, 61 insertions, 6 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 66568e58..82d4a77a 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -53,6 +53,7 @@ static final Symbol FINALLY = Symbol.create("finally"); static final Symbol THROW = Symbol.create("throw"); static final Symbol MONITOR_ENTER = Symbol.create("monitor-enter"); static final Symbol MONITOR_EXIT = Symbol.create("monitor-exit"); +static final Symbol IMPORT = Symbol.create("clojure.core", "import*"); //static final Symbol INSTANCE = Symbol.create("instance?"); //static final Symbol THISFN = Symbol.create("thisfn"); @@ -91,6 +92,7 @@ static final public IPersistentMap specials = PersistentHashMap.create( FN, null, QUOTE, new ConstantExpr.Parser(), THE_VAR, new TheVarExpr.Parser(), + IMPORT, new ImportExpr.Parser(), DOT, new HostExpr.Parser(), ASSIGN, new AssignExpr.Parser(), // TRY_FINALLY, new TryFinallyExpr.Parser(), @@ -120,6 +122,7 @@ private static final Type SYMBOL_TYPE = Type.getType(Symbol.class); private static final Type IFN_TYPE = Type.getType(IFn.class); private static final Type RT_TYPE = Type.getType(RT.class); final static Type CLASS_TYPE = Type.getType(Class.class); +final static Type NS_TYPE = Type.getType(Namespace.class); final static Type REFLECTOR_TYPE = Type.getType(Reflector.class); final static Type THROWABLE_TYPE = Type.getType(Throwable.class); final static Type BOOLEAN_OBJECT_TYPE = Type.getType(Boolean.class); @@ -520,6 +523,48 @@ public static class KeywordExpr implements Expr{ } } +public static class ImportExpr implements Expr{ + public final String c; + final static Method forNameMethod = Method.getMethod("Class forName(String)"); + final static Method importClassMethod = Method.getMethod("Class importClass(Class)"); + final static Method derefMethod = Method.getMethod("Object deref()"); + + public ImportExpr(String c){ + this.c = c; + } + + public Object eval() throws Exception{ + Namespace ns = (Namespace) RT.CURRENT_NS.deref(); + ns.importClass(RT.classForName(c)); + return null; + } + + public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + gen.getStatic(RT_TYPE,"CURRENT_NS",VAR_TYPE); + gen.invokeVirtual(VAR_TYPE, derefMethod); + gen.checkCast(NS_TYPE); + gen.push(c); + gen.invokeStatic(CLASS_TYPE, forNameMethod); + gen.invokeVirtual(NS_TYPE, importClassMethod); + if(context == C.STATEMENT) + gen.pop(); + } + + public boolean hasJavaClass(){ + return false; + } + + public Class getJavaClass() throws ClassNotFoundException{ + throw new IllegalArgumentException("ImportExpr has no Java class"); + } + + static class Parser implements IParser{ + public Expr parse(C context, Object form) throws Exception{ + return new ImportExpr((String) RT.second(form)); + } + } +} + public static abstract class LiteralExpr implements Expr{ abstract Object val(); @@ -952,8 +997,8 @@ static class StaticFieldExpr extends FieldExpr implements AssignableExpr{ public final String fieldName; public final Class c; public final java.lang.reflect.Field field; - final static Method getStaticFieldMethod = Method.getMethod("Object getStaticField(String,String)"); - final static Method setStaticFieldMethod = Method.getMethod("Object setStaticField(String,String,Object)"); +// final static Method getStaticFieldMethod = Method.getMethod("Object getStaticField(String,String)"); +// final static Method setStaticFieldMethod = Method.getMethod("Object setStaticField(String,String,Object)"); final int line; public StaticFieldExpr(int line, Class c, String fieldName) throws Exception{ @@ -1238,8 +1283,9 @@ static class StaticMethodExpr extends MethodExpr{ public final String source; public final int line; public final java.lang.reflect.Method method; + final static Method forNameMethod = Method.getMethod("Class forName(String)"); final static Method invokeStaticMethodMethod = - Method.getMethod("Object invokeStaticMethod(String,String,Object[])"); + Method.getMethod("Object invokeStaticMethod(Class,String,Object[])"); public StaticMethodExpr(String source, int line, Class c, String methodName, IPersistentVector args) @@ -1338,6 +1384,7 @@ static class StaticMethodExpr extends MethodExpr{ else { gen.push(c.getName()); + gen.invokeStatic(CLASS_TYPE, forNameMethod); gen.push(methodName); emitArgsAsArray(args, fn, gen); if(context == C.RETURN) @@ -2083,7 +2130,8 @@ public static class NewExpr implements Expr{ public final Class c; final static Method invokeConstructorMethod = Method.getMethod("Object invokeConstructor(Class,Object[])"); - final static Method forNameMethod = Method.getMethod("Class classForName(String)"); +// final static Method forNameMethod = Method.getMethod("Class classForName(String)"); + final static Method forNameMethod = Method.getMethod("Class forName(String)"); public NewExpr(Class c, IPersistentVector args, int line) throws Exception{ @@ -2149,7 +2197,7 @@ public static class NewExpr implements Expr{ else { gen.push(c.getName()); - gen.invokeStatic(RT_TYPE, forNameMethod); + gen.invokeStatic(CLASS_TYPE, forNameMethod); MethodExpr.emitArgsAsArray(args, fn, gen); if(context == C.RETURN) { diff --git a/src/jvm/clojure/lang/Namespace.java b/src/jvm/clojure/lang/Namespace.java index 77335308..09d87037 100644 --- a/src/jvm/clojure/lang/Namespace.java +++ b/src/jvm/clojure/lang/Namespace.java @@ -105,6 +105,11 @@ public Class importClass(Symbol sym, Class c){ } +public Class importClass(Class c){ + String n = c.getName(); + return importClass(Symbol.intern(n.substring(n.lastIndexOf('.') + 1)), c); +} + public Var refer(Symbol sym, Var var){ return (Var) reference(sym, var); diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index e095ed04..d9e7594b 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -1475,7 +1475,9 @@ static public ClassLoader makeClassLoader(){ } static public ClassLoader baseLoader(){ - if(booleanCast(USE_CONTEXT_CLASSLOADER.deref())) + if(Compiler.LOADER.isBound()) + return (ClassLoader) Compiler.LOADER.deref(); + else if(booleanCast(USE_CONTEXT_CLASSLOADER.deref())) return Thread.currentThread().getContextClassLoader(); else if(ROOT_CLASSLOADER != null) return ROOT_CLASSLOADER; |