Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

"statically" maintain *ns* to yield proper namespacing of ::keywords,…

… fixes gh-72
  • Loading branch information...
commit a0a7539cb917e6e031cf3cd3331c071ed43b7567 1 parent 8ec79b4
@cemerick cemerick authored
Showing with 38 additions and 13 deletions.
  1. +38 −13 src/kibit/check.clj
View
51 src/kibit/check.clj
@@ -39,16 +39,37 @@
;; extracted using the clojure reader (ala `read`), and line numbers
;; 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.))
(defn read-file
"Generate a lazy sequence of top level forms from a
- LineNumberingPushbackReader"
- [^LineNumberingPushbackReader r]
- (lazy-seq
- (let [form (read r false eof)]
- (when-not (= form eof)
- (cons form (read-file r))))))
+ LineNumberingPushbackReader"
+ [^LineNumberingPushbackReader r init-ns]
+ (let [do-read (fn do-read [ns]
+ (lazy-seq
+ (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)
+ (cons form (do-read ns))))))]
+ (do-read (careful-refer (create-ns init-ns)))))
;; ### Analyzing the pieces
@@ -113,7 +134,8 @@
(def ^:private default-args
{:rules all-rules
:guard unique-alt?
- :resolution :subform})
+ :resolution :subform
+ :init-ns 'user})
;; ### Resolution
;; Kibit can report at various levels of resolution.
@@ -134,8 +156,10 @@
:subform core/simplify-one})
(def ^:private res->read-seq
- {:toplevel (fn [reader] (read-file (LineNumberingPushbackReader. reader)))
- :subform (fn [reader] (mapcat expr-seq (read-file (LineNumberingPushbackReader. reader))))})
+ {:toplevel (fn [reader init-ns]
+ (read-file (LineNumberingPushbackReader. reader) init-ns))
+ :subform (fn [reader init-ns]
+ (mapcat expr-seq (read-file (LineNumberingPushbackReader. reader) init-ns)))})
;; Checking the expressions
;; ------------------------
@@ -186,12 +210,12 @@
(defn check-reader
""
[reader & kw-opts]
- (let [{:keys [rules guard resolution]}
+ (let [{:keys [rules guard resolution init-ns]}
(merge default-args
(apply hash-map kw-opts))
simplify-fn #((res->simplify resolution) % rules)]
(keep #(check-aux % simplify-fn guard)
- ((res->read-seq resolution) reader))))
+ ((res->read-seq resolution) reader init-ns))))
(def ^:private default-data-reader-binding
(when (resolve '*default-data-reader-fn*)
@@ -200,7 +224,7 @@
(defn check-file
""
[source-file & kw-opts]
- (let [{:keys [rules guard resolution reporter]
+ (let [{:keys [rules guard resolution reporter init-ns]
:or {reporter reporters/cli-reporter}}
(merge default-args
(apply hash-map kw-opts))]
@@ -209,6 +233,7 @@
(doseq [simplify-map (check-reader reader
:rules rules
:guard guard
- :resolution resolution)]
+ :resolution resolution
+ :init-ns init-ns)]
(reporter (assoc simplify-map :file source-file)))))))
Please sign in to comment.
Something went wrong with that request. Please try again.