summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-04-26 13:31:11 -0400
committerRich Hickey <richhickey@gmail.com>2010-04-26 13:31:11 -0400
commit29dcb68be1eb9e2bfbe5bc627a1f1d6b3e0b7a29 (patch)
tree68e1e5baec52ea938910298c147d87a5770d7cf5
parent787938361128c2bc21ed896dd4523651b59cb420 (diff)
support parameter annotations in deftype/record
-rw-r--r--src/clj/clojure/core.clj25
-rw-r--r--src/jvm/clojure/lang/Compiler.java20
2 files changed, 34 insertions, 11 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 48da4fc3..7ce2573e 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -3843,16 +3843,21 @@
(add-annotation av (name k) v))
(add-annotation av "value" v)))
-(defn- add-annotations [visitor m]
- (doseq [[k v] m]
- (when (symbol? k)
- (when-let [c (resolve k)]
- (when (is-annotation? c)
- ;this is known duck/reflective as no common base of ASM Visitors
- (let [av (.visitAnnotation visitor (descriptor c)
- (is-runtime-annotation? c))]
- (process-annotation av v)
- (.visitEnd av)))))))
+(defn- add-annotations
+ ([visitor m] (add-annotations visitor m nil))
+ ([visitor m i]
+ (doseq [[k v] m]
+ (when (symbol? k)
+ (when-let [c (resolve k)]
+ (when (is-annotation? c)
+ ;this is known duck/reflective as no common base of ASM Visitors
+ (let [av (if i
+ (.visitParameterAnnotation visitor i (descriptor c)
+ (is-runtime-annotation? c))
+ (.visitAnnotation visitor (descriptor c)
+ (is-runtime-annotation? c)))]
+ (process-annotation av v)
+ (.visitEnd av))))))))
(defn alter-var-root
"Atomically alters the root binding of var v by applying f to its
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index ffb5c928..035f78d8 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -5441,7 +5441,7 @@ static PathNode commonPath(PathNode n1, PathNode n2){
static void addAnnotation(Object visitor, IPersistentMap meta){
try{
- if(ADD_ANNOTATIONS.isBound())
+ if(meta != null && ADD_ANNOTATIONS.isBound())
ADD_ANNOTATIONS.invoke(visitor, meta);
}
catch (Exception e)
@@ -5450,6 +5450,17 @@ static void addAnnotation(Object visitor, IPersistentMap meta){
}
}
+static void addParameterAnnotation(Object visitor, IPersistentMap meta, int i){
+ try{
+ if(meta != null && ADD_ANNOTATIONS.isBound())
+ ADD_ANNOTATIONS.invoke(visitor, meta, i);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+}
+
private static Expr analyzeSymbol(Symbol sym) throws Exception{
Symbol tag = tagOf(sym);
if(sym.ns == null) //ns-qualified syms are always Vars
@@ -6322,6 +6333,7 @@ public static class NewInstanceMethod extends ObjMethod{
Class[] exclasses;
static Symbol dummyThis = Symbol.intern(null,"dummy_this_dlskjsdfower");
+ private IPersistentVector parms;
public NewInstanceMethod(ObjExpr objx, ObjMethod parent){
super(objx, parent);
@@ -6471,6 +6483,7 @@ public static class NewInstanceMethod extends ObjMethod{
LOOP_LOCALS.set(argLocals);
method.name = name.name;
method.methodMeta = RT.meta(name);
+ method.parms = parms;
method.argLocals = argLocals;
method.body = (new BodyExpr.Parser()).parse(C.RETURN, body);
return method;
@@ -6521,6 +6534,11 @@ public static class NewInstanceMethod extends ObjMethod{
extypes,
cv);
addAnnotation(gen,methodMeta);
+ for(int i = 0; i < parms.count(); i++)
+ {
+ IPersistentMap meta = RT.meta(parms.nth(i));
+ addParameterAnnotation(gen, meta, i);
+ }
gen.visitCode();
Label loopLabel = gen.mark();
gen.visitLineNumber(line, loopLabel);