summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj41
-rw-r--r--src/clj/clojure/core_proxy.clj2
-rw-r--r--src/jvm/clojure/lang/Compiler.java58
-rw-r--r--src/jvm/clojure/lang/Namespace.java5
-rw-r--r--src/jvm/clojure/lang/RT.java4
5 files changed, 81 insertions, 29 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 8fee8bcb..62da5a61 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -1840,25 +1840,31 @@
~@body
(recur (unchecked-inc ~i)))))))
-(defn import
+(defn into
+ "Returns a new coll consisting of to-coll with all of the items of
+ from-coll conjoined."
+ [to from]
+ (let [ret to items (seq from)]
+ (if items
+ (recur (conj ret (first items)) (next items))
+ ret)))
+
+(defmacro import
"import-list => (package-symbol class-name-symbols*)
For each name in class-name-symbols, adds a mapping from name to the
class named by package.name to the current namespace. Use :import in the ns
macro in preference to calling this directly."
[& import-symbols-or-lists]
- (let [#^clojure.lang.Namespace ns *ns*]
- (doseq [spec import-symbols-or-lists]
- (if (symbol? spec)
- (let [n (name spec)
- dot (.lastIndexOf n (. clojure.lang.RT (intCast \.)))
- c (symbol (.substring n (inc dot)))]
- (. ns (importClass c (. clojure.lang.RT (classForName (name spec))))))
- (let [pkg (first spec)
- classes (next spec)]
- (doseq [c classes]
- (. ns (importClass c (. clojure.lang.RT (classForName (str pkg "." c)))))))))))
-
+ (let [specs (map #(if (and (seq? %) (= 'quote (first %))) (second %) %)
+ import-symbols-or-lists)]
+ `(do ~@(map #(list 'clojure.core/import* %)
+ (reduce (fn [v spec]
+ (if (symbol? spec)
+ (conj v (name spec))
+ (let [p (first spec) cs (rest spec)]
+ (into v (map #(str p "." %) cs)))))
+ [] specs)))))
(defn into-array
"Returns an array with components set to the values in aseq. The array's
@@ -1871,15 +1877,6 @@
([type aseq]
(clojure.lang.RT/seqToTypedArray type (seq aseq))))
-(defn into
- "Returns a new coll consisting of to-coll with all of the items of
- from-coll conjoined."
- [to from]
- (let [ret to items (seq from)]
- (if items
- (recur (conj ret (first items)) (next items))
- ret)))
-
(defn #^{:private true}
array [& items]
(into-array items))
diff --git a/src/clj/clojure/core_proxy.clj b/src/clj/clojure/core_proxy.clj
index 860621c4..93e3e0ba 100644
--- a/src/clj/clojure/core_proxy.clj
+++ b/src/clj/clojure/core_proxy.clj
@@ -255,7 +255,7 @@
pname (proxy-name super interfaces)]
(or (RT/loadClassForName pname)
(let [[cname bytecode] (generate-proxy super interfaces)]
- (. (RT/getRootClassLoader) (defineClass pname bytecode))))))
+ (. (deref clojure.lang.Compiler/LOADER) (defineClass pname bytecode))))))
(defn construct-proxy
"Takes a proxy class and any arguments for its superclass ctor and
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;