Permalink
Browse files

TNS-17: parse any top-level 'ns' declaration in file

The ns declaration no longer needs to be the first non-comment form in
the file. This is actually simpler than filtering out 'comment' forms
explicitly.

This also permits read-ns-decl to be called multiple times to search a
file for 'ns' declarations.

'ns' forms still have to be at the top-level of the file.
  • Loading branch information...
1 parent 3f94638 commit 3c08b722fe5c84ff52749fca2b00fe019ca85484 @stuartsierra stuartsierra committed Jul 11, 2014
@@ -25,17 +25,18 @@
(defn read-ns-decl
"Attempts to read a (ns ...) declaration from a
java.io.PushbackReader, and returns the unevaluated form. Returns
- nil if read fails or if a ns declaration cannot be found. The ns
- declaration must be the first Clojure form in the file, except for
- (comment ...) forms."
+ the first top-level ns form found. Returns nil if read fails or if a
+ ns declaration cannot be found. Note that read can execute code
+ (controlled by *read-eval*), and as such should be used only with
+ trusted sources."
[rdr]
(try
- (loop [] (let [form (doto (read rdr) str)] ; str forces errors, see TNS-1
- (cond
- (ns-decl? form) form
- (comment? form) (recur)
- :else nil)))
- (catch Exception e nil)))
+ (loop []
+ (let [form (doto (read rdr) str)] ; str forces errors, see TNS-1
+ (if (ns-decl? form)
+ form
+ (recur))))
+ (catch Exception e nil)))
;;; Parsing dependencies
@@ -1,6 +1,7 @@
(ns clojure.tools.namespace.parse-test
(:use [clojure.test :only (deftest is)]
- [clojure.tools.namespace.parse :only (deps-from-ns-decl)]))
+ [clojure.tools.namespace.parse :only (deps-from-ns-decl
+ read-ns-decl)]))
(def ns-decl-prefix-list
'(ns com.example.one
@@ -52,3 +53,23 @@
(deftest t-no-deps-returns-empty-set
(is (= #{} (deps-from-ns-decl '(ns com.example.one)))))
+
+(def multiple-ns-decls
+ '((ns one)
+ (ns two (:require one))
+ (ns three (:require [one :as o] [two :as t]))))
+
+(def multiple-ns-decls-string
+" (println \"Code before first ns\")
+ (ns one)
+ (println \"Some code\")
+ (defn hello-world [] \"Hello, World!\")
+ (ns two (:require one))
+ (println \"Some more code\")
+ (ns three (:require [one :as o] [two :as t]))")
+
+(deftest t-read-multiple-ns-decls
+ (with-open [rdr (java.io.PushbackReader.
+ (java.io.StringReader. multiple-ns-decls-string))]
+ (is (= multiple-ns-decls
+ (take-while identity (repeatedly #(read-ns-decl rdr)))))))

0 comments on commit 3c08b72

Please sign in to comment.