Fix handling of ::keywords using aliases
This patch introduces namespace tracking to Marginalia's parser: ns, in-ns, require, use and alias forms are now evaluated in the proper namespace at read-time. This is necessary to handle ::keywords in full generality, since ::foo/bar is a valid token iff the symbol 'foo can be resolved to a namespace at read time: (in-ns 'test) ::foo/bar ; => invalid token results in read-time error (require '[some.namespace :as foo]) ::foo/bar ; => :some.namespace/foo NB. only top-level #{ns in-ns require use alias} forms are recognized.
This commit is contained in:
parent
142f09f75f
commit
3fff515edb
2 changed files with 16 additions and 2 deletions
|
@ -15,6 +15,9 @@
|
|||
(def top-level-comments (atom []))
|
||||
(def sub-level-comments (atom []))
|
||||
|
||||
(def user-ns (the-ns 'user))
|
||||
(def current-namespace (atom user-ns))
|
||||
|
||||
(def *comments* nil)
|
||||
|
||||
(defn read-comment [reader semicolon]
|
||||
|
@ -49,6 +52,14 @@
|
|||
(recur (.read rdr))
|
||||
:else (.unread rdr c))))
|
||||
|
||||
(defn maybe-change-namespace [form]
|
||||
(when (and (seq? form)
|
||||
('#{ns in-ns require use alias} (first form)))
|
||||
(binding [*ns* @current-namespace]
|
||||
(eval form))
|
||||
(when ('#{ns in-ns} (first form))
|
||||
(reset! current-namespace (the-ns (second form))))))
|
||||
|
||||
(defn parse* [reader]
|
||||
(take-while
|
||||
:form
|
||||
|
@ -58,12 +69,14 @@
|
|||
(binding [*comments* top-level-comments]
|
||||
(skip-spaces-and-comments reader))
|
||||
(let [start (.getLineNumber reader)
|
||||
form (binding [*comments* sub-level-comments]
|
||||
form (binding [*comments* sub-level-comments
|
||||
*ns* @current-namespace]
|
||||
(. clojure.lang.LispReader
|
||||
(read reader false nil false)))
|
||||
end (.getLineNumber reader)
|
||||
code {:form form :start start :end end}
|
||||
comments @top-level-comments]
|
||||
(maybe-change-namespace form)
|
||||
(swap! top-level-comments (constantly []))
|
||||
(if (empty? comments)
|
||||
[code]
|
||||
|
|
|
@ -8,4 +8,5 @@
|
|||
;(is (= (count (marginalia.parser/parse "(ns test)\n123")) 1)) still failing
|
||||
(is (= (count (marginalia.parser/parse "(ns test)\n123\n")) 1))
|
||||
(is (= (count (marginalia.parser/parse "(ns test)\n\"string\"")) 1))
|
||||
(is (= (count (marginalia.parser/parse "(ns test)\n\"some string\"")) 1)))
|
||||
(is (= (count (marginalia.parser/parse "(ns test)\n\"some string\"")) 1))
|
||||
(is (= (count (marginalia.parser/parse "(ns test (:require [marginalia.parser :as parser]))\n(defn foo [] ::parser/foo)")) 1)))
|
||||
|
|
Loading…
Reference in a new issue