(parse-ns src)
(parse-ns src opts)
(parse-ns src dest opts)
Helper for parsing only the essential namespace information from a
ClojureScript source file and returning a cljs.closure/IJavaScript compatible
map _not_ a namespace AST node.
By default does not load macros or perform any analysis of dependencies. If
opts parameter provided :analyze-deps and :load-macros keys their values will
be used for *analyze-deps* and *load-macros* bindings respectively. This
function does _not_ side-effect the ambient compilation environment unless
requested via opts where :restore is false.
Source
(defn parse-ns
"Helper for parsing only the essential namespace information from a
ClojureScript source file and returning a cljs.closure/IJavaScript compatible
map _not_ a namespace AST node.
By default does not load macros or perform any analysis of dependencies. If
opts parameter provided :analyze-deps and :load-macros keys their values will
be used for *analyze-deps* and *load-macros* bindings respectively. This
function does _not_ side-effect the ambient compilation environment unless
requested via opts where :restore is false."
([src]
(parse-ns src nil
(when env/*compiler*
(:options @env/*compiler*))))
([src opts] (parse-ns src nil opts))
([src dest opts]
(ensure
(let [src (if (symbol? src)
(util/ns->source src)
src)
ijs
(binding [env/*compiler* (if (false? (:restore opts))
env/*compiler*
(atom @env/*compiler*))
*cljs-ns* 'cljs.user
*cljs-file* src
*macro-infer*
(or (when (contains? opts :macro-infer)
(:macro-infer opts))
false)
*analyze-deps*
(or (when (contains? opts :analyze-deps)
(:analyze-deps opts))
false)
*load-macros*
(or (when (contains? opts :load-macros)
(:load-macros opts))
false)]
(let [rdr (when-not (sequential? src) (io/reader src))]
(try
(loop [forms (if rdr
(forms-seq* rdr (source-path src))
src)
ret (merge
{:file dest
:source-file (when rdr src)
:source-forms (when-not rdr src)
:macros-ns (:macros-ns opts)
:requires (cond-> #{'cljs.core}
(get-in @env/*compiler* [:options :emit-constants])
(conj constants-ns-sym))}
(when (and dest (.exists ^File dest))
{:lines (with-open [reader (io/reader dest)]
(-> reader line-seq count))}))]
(if (seq forms)
(let [env (empty-env)
ast (no-warn (analyze env (first forms) nil opts))]
(cond
(= :ns (:op ast))
(let [ns-name (:name ast)
ns-name (if (and (= 'cljs.core ns-name)
(= "cljc" (util/ext src)))
'cljs.core$macros
ns-name)
deps (merge (:uses ast) (:requires ast))]
(merge
{:ns (or ns-name 'cljs.user)
:provides [ns-name]
:requires (if (= 'cljs.core ns-name)
(set (vals deps))
(cond-> (conj (set (vals deps)) 'cljs.core)
(get-in @env/*compiler* [:options :emit-constants])
(conj constants-ns-sym)))
:file dest
:source-file (when rdr src)
:source-forms (when-not rdr src)
:ast ast
:macros-ns (or (:macros-ns opts)
(= 'cljs.core$macros ns-name))}
(when (and dest (.exists ^File dest))
{:lines (with-open [reader (io/reader dest)]
(-> reader line-seq count))})))
(= :ns* (:op ast))
(let [deps (merge (:uses ast) (:requires ast))]
(recur (rest forms)
(cond-> (update-in ret [:requires] into (set (vals deps)))
;; we need to defer generating the user namespace
;; until we actually need or it will break when
;; `src` is a sequence of forms - António Monteiro
(not (:ns ret))
(assoc :ns (gen-user-ns src) :provides [(gen-user-ns src)]))))
:else ret))
ret))
(finally
(when rdr
(.close ^Reader rdr))))))]
ijs))))