(resolve-var env sym)
(resolve-var env sym confirm)
Resolve a var. Accepts a side-effecting confirm fn for producing
warnings about unresolved vars.
Source
(defn resolve-var
"Resolve a var. Accepts a side-effecting confirm fn for producing
warnings about unresolved vars."
([env sym] (resolve-var env sym nil))
([env sym confirm]
(let [locals (:locals env)]
(if #?(:clj (= "js" (namespace sym))
:cljs (identical? "js" (namespace sym)))
(do
(when (contains? locals (-> sym name symbol))
(warning :js-shadowed-by-local env {:name sym}))
(let [pre (->> (string/split (name sym) #"\.") (map symbol) vec)]
(when-not (has-extern? pre)
(swap! env/*compiler* update-in
(into [::namespaces (-> env :ns :name) :externs] pre) merge {}))
(merge
{:name sym
:ns 'js
:tag (with-meta (or (js-tag pre) (:tag (meta sym)) 'js) {:prefix pre})}
(when-let [ret-tag (js-tag pre :ret-tag)]
{:js-fn-var true
:ret-tag ret-tag}))))
(let [s (str sym)
lb (get locals sym)
current-ns (-> env :ns :name)]
(cond
(some? lb) lb
(some? (namespace sym))
(let [ns (namespace sym)
ns (if #?(:clj (= "clojure.core" ns)
:cljs (identical? "clojure.core" ns))
"cljs.core"
ns)
full-ns (resolve-ns-alias env ns
(or (and (js-module-exists? ns)
(gets @env/*compiler* :js-module-index ns :name))
(symbol ns)))]
(when (some? confirm)
(when (not= current-ns full-ns)
(confirm-ns env full-ns))
(confirm env full-ns (symbol (name sym))))
(resolve* sym full-ns current-ns))
(dotted-symbol? sym)
(let [idx (.indexOf s ".")
prefix (symbol (subs s 0 idx))
suffix (subs s (inc idx))]
(if-some [lb (get locals prefix)]
{:name (symbol (str (:name lb)) suffix)}
(if-some [full-ns (gets @env/*compiler* ::namespaces current-ns :imports prefix)]
{:name (symbol (str full-ns) suffix)}
(if-some [info (gets @env/*compiler* ::namespaces current-ns :defs prefix)]
(merge info
{:name (symbol (str current-ns) (str sym))
:ns current-ns})
(merge (gets @env/*compiler* ::namespaces prefix :defs (symbol suffix))
{:name (if (= "" prefix) (symbol suffix) (symbol (str prefix) suffix))
:ns prefix})))))
(some? (gets @env/*compiler* ::namespaces current-ns :uses sym))
(let [full-ns (gets @env/*compiler* ::namespaces current-ns :uses sym)]
(resolve* sym full-ns current-ns))
(some? (gets @env/*compiler* ::namespaces current-ns :renames sym))
(let [qualified-symbol (gets @env/*compiler* ::namespaces current-ns :renames sym)
full-ns (symbol (namespace qualified-symbol))
sym (symbol (name qualified-symbol))]
(resolve* sym full-ns current-ns))
(some? (gets @env/*compiler* ::namespaces current-ns :imports sym))
(recur env (gets @env/*compiler* ::namespaces current-ns :imports sym) confirm)
(some? (gets @env/*compiler* ::namespaces current-ns :defs sym))
(do
(when (some? confirm)
(confirm env current-ns sym))
(merge (gets @env/*compiler* ::namespaces current-ns :defs sym)
{:name (symbol (str current-ns) (str sym))
:ns current-ns}))
(core-name? env sym)
(do
(when (some? confirm)
(confirm env 'cljs.core sym))
(merge (gets @env/*compiler* ::namespaces 'cljs.core :defs sym)
{:name (symbol "cljs.core" (str sym))
:ns 'cljs.core}))
(invokeable-ns? s env)
(resolve-invokeable-ns s current-ns env)
:else
(do
(when (some? confirm)
(confirm env current-ns sym))
(merge (gets @env/*compiler* ::namespaces current-ns :defs sym)
{:name (symbol (str current-ns) (str sym))
:ns current-ns}))))))))