Skip to content
This repository has been archived by the owner on Oct 2, 2020. It is now read-only.

Commit

Permalink
Bind *ns* to file's ns during read
Browse files Browse the repository at this point in the history
Commit 54cba5c introduced a method of
detecting unqualified, unquoted symbols within syntax quotes that are
consumed in-namespace.

From the commit message:

> We can avoid this situation by walking the body and de-qualifying only
> the symbols that have been qualified in the current ns. This should
> not be problematic since unknown symbols are qualified in the current
> ns by default.

Now, the "current ns" is determined by the reader to be the value of
the *ns* var. When using Slamhound from an editor plugin, it can be
assumed that *ns* is set to the namespace of the current open buffer.
Unfortunately, when using Slamhound from a command line, *ns* is
actually set to the `user` ns.

This causes symbols that we expect to be qualified as `my.ns/foo` to
actually be qualified as `user/foo`. There have been scattered reports
of slamhound attempting to alias namespaces as `user`¹. In at least some
of these cases, this problem is likely to blame.

¹ #65 comes to mind
  • Loading branch information
guns committed Apr 30, 2014
1 parent a325967 commit ff5bef0
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
20 changes: 17 additions & 3 deletions src/slam/hound/asplode.clj
Expand Up @@ -216,6 +216,20 @@
stripped-ns (-> (apply dissoc ns-map ns-clauses)
(assoc :old old-ns)
(merge (preserve-ns-references old-ns)))
body (take-while #(not= ::done %)
(repeatedly #(read rdr false ::done)))]
[stripped-ns (doall body)])))
;; All unqualified, unquoted symbols are qualified to *ns* by the
;; reader during syntax-quote expansion, so we must be sure that
;; *ns* is set to the file's namespace in order for the regrow step
;; to work properly.
;;
;; Unfortunately, this means we are introducing the potentially
;; surprising side effect of creating a namespace on read. This
;; cannot be helped, as there is no way of creating a Namespace
;; object that is not added to the global map of namespaces.
;;
;; In practice, however, this is unlikely to be a problem;
;; slam.hound/regrow loads all namespaces on the classpath anyway.
body (binding [*ns* (create-ns (:name ns-map))]
(doall
(take-while #(not= ::done %)
(repeatedly #(read rdr false ::done)))))]
[stripped-ns body])))
7 changes: 6 additions & 1 deletion test/slam/hound/asplode_test.clj
Expand Up @@ -196,4 +196,9 @@
:exclude {clojure.core #{test compile}}
:meta {:doc "Testing some things going on here."}
:name slamhound.sample}
((do something))])))
((do something))]))
(testing "output is constant regardless of *ns*"
(let [buf "(ns slamhound.sample) (eval `foo)"]
(is (= (asplode (StringReader. buf))
(binding [*ns* (find-ns 'user)]
(asplode (StringReader. buf))))))))

0 comments on commit ff5bef0

Please sign in to comment.