"statically" maintain *ns* to yield proper namespacing of ::keywords, fixes gh-72

This commit is contained in:
Chas Emerick 2013-02-13 17:20:36 -05:00
parent 8ec79b4293
commit a0a7539cb9

View file

@ -39,16 +39,37 @@
;; extracted using the clojure reader (ala `read`), and line numbers ;; extracted using the clojure reader (ala `read`), and line numbers
;; are added as `:line` metadata to the forms (via LNPR). ;; are added as `:line` metadata to the forms (via LNPR).
(defn- careful-refer
"Refers into the provided namespace all public vars from clojure.core
except for those that would clobber any existing interned vars in that
namespace. This is needed to ensure that symbols read within syntax-quote
end up being fully-qualified to clojure.core as appropriate, and only
to *ns* if they're not available there. AFAICT, this will work for all
symbols in syntax-quote except for those referring to vars that are referred
into the namespace."
[ns]
(binding [*ns* ns]
(refer 'clojure.core :exclude (or (keys (ns-interns ns)) ())))
ns)
(def eof (Object.)) (def eof (Object.))
(defn read-file (defn read-file
"Generate a lazy sequence of top level forms from a "Generate a lazy sequence of top level forms from a
LineNumberingPushbackReader" LineNumberingPushbackReader"
[^LineNumberingPushbackReader r] [^LineNumberingPushbackReader r init-ns]
(let [do-read (fn do-read [ns]
(lazy-seq (lazy-seq
(let [form (read r false eof)] (let [form (binding [*ns* ns]
(read r false eof))
[ns? new-ns k] (when (sequential? form) form)
ns (if (and (symbol? new-ns)
(or (= ns? 'ns) (= ns? 'in-ns)))
(careful-refer (create-ns new-ns))
ns)]
(when-not (= form eof) (when-not (= form eof)
(cons form (read-file r)))))) (cons form (do-read ns))))))]
(do-read (careful-refer (create-ns init-ns)))))
;; ### Analyzing the pieces ;; ### Analyzing the pieces
@ -113,7 +134,8 @@
(def ^:private default-args (def ^:private default-args
{:rules all-rules {:rules all-rules
:guard unique-alt? :guard unique-alt?
:resolution :subform}) :resolution :subform
:init-ns 'user})
;; ### Resolution ;; ### Resolution
;; Kibit can report at various levels of resolution. ;; Kibit can report at various levels of resolution.
@ -134,8 +156,10 @@
:subform core/simplify-one}) :subform core/simplify-one})
(def ^:private res->read-seq (def ^:private res->read-seq
{:toplevel (fn [reader] (read-file (LineNumberingPushbackReader. reader))) {:toplevel (fn [reader init-ns]
:subform (fn [reader] (mapcat expr-seq (read-file (LineNumberingPushbackReader. reader))))}) (read-file (LineNumberingPushbackReader. reader) init-ns))
:subform (fn [reader init-ns]
(mapcat expr-seq (read-file (LineNumberingPushbackReader. reader) init-ns)))})
;; Checking the expressions ;; Checking the expressions
;; ------------------------ ;; ------------------------
@ -186,12 +210,12 @@
(defn check-reader (defn check-reader
"" ""
[reader & kw-opts] [reader & kw-opts]
(let [{:keys [rules guard resolution]} (let [{:keys [rules guard resolution init-ns]}
(merge default-args (merge default-args
(apply hash-map kw-opts)) (apply hash-map kw-opts))
simplify-fn #((res->simplify resolution) % rules)] simplify-fn #((res->simplify resolution) % rules)]
(keep #(check-aux % simplify-fn guard) (keep #(check-aux % simplify-fn guard)
((res->read-seq resolution) reader)))) ((res->read-seq resolution) reader init-ns))))
(def ^:private default-data-reader-binding (def ^:private default-data-reader-binding
(when (resolve '*default-data-reader-fn*) (when (resolve '*default-data-reader-fn*)
@ -200,7 +224,7 @@
(defn check-file (defn check-file
"" ""
[source-file & kw-opts] [source-file & kw-opts]
(let [{:keys [rules guard resolution reporter] (let [{:keys [rules guard resolution reporter init-ns]
:or {reporter reporters/cli-reporter}} :or {reporter reporters/cli-reporter}}
(merge default-args (merge default-args
(apply hash-map kw-opts))] (apply hash-map kw-opts))]
@ -209,6 +233,7 @@
(doseq [simplify-map (check-reader reader (doseq [simplify-map (check-reader reader
:rules rules :rules rules
:guard guard :guard guard
:resolution resolution)] :resolution resolution
:init-ns init-ns)]
(reporter (assoc simplify-map :file source-file))))))) (reporter (assoc simplify-map :file source-file)))))))