summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Halloway <stu@thinkrelevance.com>2010-05-22 15:34:05 -0400
committerStuart Halloway <stu@thinkrelevance.com>2010-05-24 10:45:49 -0400
commit8c9b0574a83f6c77576325b724c837cf4143eb33 (patch)
tree57103f744879f8a7ffb64366cea82e0f0bd0d66b
parent45b54867d27fabee2e9a6b1dd21b8377d9b3fd92 (diff)
propagate useful metadata to protocol fns #349
- also add :added metadata for fns with newly visible docstrings Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
-rw-r--r--src/clj/clojure/core_deftype.clj16
-rw-r--r--src/clj/clojure/java/io.clj12
-rw-r--r--test/clojure/test_clojure/protocols.clj9
-rw-r--r--test/clojure/test_clojure/protocols/examples.clj2
4 files changed, 25 insertions, 14 deletions
diff --git a/src/clj/clojure/core_deftype.clj b/src/clj/clojure/core_deftype.clj
index 161514db..4ca47637 100644
--- a/src/clj/clojure/core_deftype.clj
+++ b/src/clj/clojure/core_deftype.clj
@@ -525,7 +525,8 @@
keyword? (recur (assoc opts (first sigs) (second sigs)) (nnext sigs))
[opts sigs]))
sigs (reduce (fn [m s]
- (let [mname (with-meta (first s) nil)
+ (let [name-meta (meta (first s))
+ mname (with-meta (first s) nil)
[arglists doc]
(loop [as [] rs (rest s)]
(if (vector? (first rs))
@@ -533,10 +534,11 @@
[(seq as) (first rs)]))]
(when (some #{0} (map count arglists))
(throw (IllegalArgumentException. (str "Protocol fn: " mname " must take at least one arg"))))
- (assoc m (keyword mname)
- {:name (vary-meta mname assoc :doc doc :arglists arglists)
- :arglists arglists
- :doc doc})))
+ (assoc m (keyword mname)
+ (merge name-meta
+ {:name (vary-meta mname assoc :doc doc :arglists arglists)
+ :arglists arglists
+ :doc doc}))))
{} sigs)
meths (mapcat (fn [sig]
(let [m (munge (:name sig))]
@@ -562,8 +564,8 @@
:method-builders
~(apply hash-map
(mapcat
- (fn [s]
- [`(intern *ns* (with-meta '~(:name s) {:protocol (var ~name)}))
+ (fn [s]
+ [`(intern *ns* (with-meta '~(:name s) (merge '~s {:protocol (var ~name)})))
(emit-method-builder (:on-interface opts) (:name s) (:on s) (:arglists s))])
(vals sigs)))))
(-reset-methods ~name)
diff --git a/src/clj/clojure/java/io.clj b/src/clj/clojure/java/io.clj
index 97ae4e3e..4d6c551f 100644
--- a/src/clj/clojure/java/io.clj
+++ b/src/clj/clojure/java/io.clj
@@ -33,8 +33,8 @@
(defprotocol ^{:added "1.2"} Coercions
"Coerce between various 'resource-namish' things."
- (^File as-file [x] "Coerce argument to a file.")
- (^URL as-url [x] "Coerce argument to a URL."))
+ (^{:tag File, :added "1.2"} as-file [x] "Coerce argument to a file.")
+ (^{:tag URL, :added "1.2"} as-url [x] "Coerce argument to a URL."))
(extend-protocol Coercions
nil
@@ -72,10 +72,10 @@
Callers should generally prefer the higher level API provided by
reader, writer, input-stream, and output-stream."
- (make-reader [x opts] "Creates a BufferedReader. See also IOFactory docs.")
- (make-writer [x opts] "Creates a BufferedWriter. See also IOFactory docs.")
- (make-input-stream [x opts] "Creates a BufferedInputStream. See also IOFactory docs.")
- (make-output-stream [x opts] "Creates a BufferedOutputStream. See also IOFactory docs."))
+ (^{:added "1.2"} make-reader [x opts] "Creates a BufferedReader. See also IOFactory docs.")
+ (^{:added "1.2"} make-writer [x opts] "Creates a BufferedWriter. See also IOFactory docs.")
+ (^{:added "1.2"} make-input-stream [x opts] "Creates a BufferedInputStream. See also IOFactory docs.")
+ (^{:added "1.2"} make-output-stream [x opts] "Creates a BufferedOutputStream. See also IOFactory docs."))
(defn ^Reader reader
"Attempts to coerce its argument into an open java.io.Reader.
diff --git a/test/clojure/test_clojure/protocols.clj b/test/clojure/test_clojure/protocols.clj
index 90de0010..52aa346f 100644
--- a/test/clojure/test_clojure/protocols.clj
+++ b/test/clojure/test_clojure/protocols.clj
@@ -66,6 +66,15 @@
(getValue [_] v))
(deftest protocols-test
+ (testing "protocol fns have useful metadata"
+ (let [common-meta {:ns (find-ns 'clojure.test-clojure.protocols.examples)
+ :protocol #'ExampleProtocol}]
+ (are [m f] (= (merge (quote m) common-meta)
+ (meta (var f)))
+ {:name foo :arglists ([a]) :doc "method with one arg"} foo
+ {:name bar :arglists ([a b]) :doc "method with two args"} bar
+ {:name baz :arglists ([a] [a b]) :doc "method with multiple arities" :tag String} baz
+ {:name with-quux :arglists ([a]) :doc "method name with a hyphen"} with-quux)))
(testing "protocol fns throw IllegalArgumentException if no impl matches"
(is (thrown-with-msg?
IllegalArgumentException
diff --git a/test/clojure/test_clojure/protocols/examples.clj b/test/clojure/test_clojure/protocols/examples.clj
index 877559d0..b9644750 100644
--- a/test/clojure/test_clojure/protocols/examples.clj
+++ b/test/clojure/test_clojure/protocols/examples.clj
@@ -5,7 +5,7 @@
(foo [a] "method with one arg")
(bar [a b] "method with two args")
- (baz [a] [a b] "method with multiple arities")
+ (^String baz [a] [a b] "method with multiple arities")
(with-quux [a] "method name with a hyphen"))
(definterface ExampleInterface