(defn
require
([name cb] (require name nil cb))
([name opts cb] (require nil name opts cb))
([bound-vars name opts cb] (require bound-vars name nil opts cb))
([bound-vars name reload opts cb]
(let
[bound-vars
(merge
{:*compiler* (env/default-compiler-env),
:*data-readers* tags/*cljs-data-readers*,
:*load-macros* (:load-macros opts true),
:*analyze-deps* (:analyze-deps opts true),
:*load-fn* (or (:load opts) *load-fn*),
:*eval-fn* (or (:eval opts) *eval-fn*)}
bound-vars)
aname
(cond-> name (:macros-ns opts) ana/macro-ns-name)]
(when (= :reload reload) (swap! *loaded* disj aname))
(when (= :reload-all reload) (reset! *loaded* #{}))
(when
(:verbose opts)
(debug-prn
(str
"Loading "
name
(when (:macros-ns opts) " macros")
" namespace")))
(if-not
(contains? @*loaded* aname)
(let
[env (:*env* bound-vars)]
(try
((:*load-fn* bound-vars)
{:name name,
:macros (:macros-ns opts),
:path (ns->relpath name)}
(fn
[resource]
(assert
(or (map? resource) (nil? resource))
"*load-fn* may only return a map or nil")
(if
resource
(let
[{:keys [lang source cache source-map file]} resource]
(condp
keyword-identical?
lang
:clj
(do
(pre-file-side-effects
(:*compiler* bound-vars)
aname
file
opts)
(eval-str*
bound-vars
source
name
(assoc opts :cljs-file file)
(fn
[res]
(post-file-side-effects file opts)
(if
(:error res)
(cb res)
(do (swap! *loaded* conj aname) (cb {:value true}))))))
:js
(process-macros-deps
bound-vars
cache
opts
(fn
[res]
(if
(:error res)
(cb res)
(process-libs-deps
bound-vars
cache
opts
(fn
[res]
(if
(:error res)
(cb res)
(let
[res
(try
((:*eval-fn* bound-vars) resource)
(when
cache
(load-analysis-cache!
(:*compiler* bound-vars)
aname
cache)
(ana/register-specs cache))
(when
source-map
(load-source-map!
(:*compiler* bound-vars)
aname
source-map))
(catch
:default
cause
(wrap-error
(ana/error
env
(str "Could not require " name)
cause))))]
(if
(:error res)
(cb res)
(do
(swap! *loaded* conj aname)
(cb {:value true}))))))))))
(cb
(wrap-error
(ana/error
env
(str
"Invalid :lang specified "
lang
", only :clj or :js allowed"))))))
(cb
(wrap-error
(ana/error
env
(ana/error-message
(if
(:macros-ns opts)
:undeclared-macros-ns
:undeclared-ns)
{:ns-sym name, :js-provide (cljs.core/name name)})))))))
(catch
:default
cause
(cb
(wrap-error
(ana/error env (str "Could not require " name) cause))))))
(cb {:value true})))))