Skip to content

Commit 3438f20

Browse files
committed
CLJS-2078: add resolve macro
add resolve macro. Make var-ast public and add a var-meta helper we can use to get the var meta from the resolve macro.
1 parent 89cd5ec commit 3438f20

2 files changed

Lines changed: 41 additions & 19 deletions

File tree

src/main/clojure/cljs/analyzer.cljc

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,32 @@
11341134

11351135
(defmulti parse (fn [op & rest] op))
11361136

1137-
(defn- var-ast
1137+
(defn var-meta
1138+
([var]
1139+
(var-meta var nil))
1140+
([var expr-env]
1141+
(let [sym (:name var)
1142+
ks [:ns :doc :file :line :column]
1143+
m (merge
1144+
(let [user-meta (:meta var)
1145+
uks (keys user-meta)]
1146+
(zipmap uks
1147+
(map #(list 'quote (get user-meta %)) uks)))
1148+
(assoc (zipmap ks (map #(list 'quote (get var %)) ks))
1149+
:name `(quote ~(symbol (name (:name var))))
1150+
:test `(when ~sym (.-cljs$lang$test ~sym))
1151+
:arglists (let [arglists (:arglists var)
1152+
arglists' (if (= 'quote (first arglists))
1153+
(second arglists)
1154+
arglists)]
1155+
(list 'quote
1156+
(doall (map with-meta arglists'
1157+
(:arglists-meta var)))))))]
1158+
(if expr-env
1159+
(analyze expr-env m)
1160+
m))))
1161+
1162+
(defn var-ast
11381163
[env sym]
11391164
;; we need to dissoc locals for the `(let [x 1] (def x x))` case, because we
11401165
;; want the var's AST and `resolve-var` will check locals first. - António Monteiro
@@ -1144,23 +1169,7 @@
11441169
(when-some [var-ns (:ns var)]
11451170
{:var (analyze expr-env sym)
11461171
:sym (analyze expr-env `(quote ~(symbol (name var-ns) (name (:name var)))))
1147-
:meta (let [ks [:ns :doc :file :line :column]
1148-
m (merge
1149-
(let [user-meta (:meta var)
1150-
uks (keys user-meta)]
1151-
(zipmap uks
1152-
(map #(list 'quote (get user-meta %)) uks)))
1153-
(assoc (zipmap ks (map #(list 'quote (get var %)) ks))
1154-
:name `(quote ~(symbol (name (:name var))))
1155-
:test `(when ~sym (.-cljs$lang$test ~sym))
1156-
:arglists (let [arglists (:arglists var)
1157-
arglists' (if (= 'quote (first arglists))
1158-
(second arglists)
1159-
arglists)]
1160-
(list 'quote
1161-
(doall (map with-meta arglists'
1162-
(:arglists-meta var)))))))]
1163-
(analyze expr-env m))})))
1172+
:meta (var-meta var expr-env)})))
11641173

11651174
(defmethod parse 'var
11661175
[op env [_ sym :as form] _ _]

src/main/clojure/cljs/core.cljc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
require use refer-clojure
3838

3939
if-some when-some test ns-interns ns-unmap var vswap! macroexpand-1 macroexpand
40-
some?
40+
some? resolve
4141
#?@(:cljs [alias coercive-not coercive-not= coercive-= coercive-boolean
4242
truth_ js-arguments js-delete js-in js-debugger exists? divide js-mod
4343
unsafe-bit-and bit-shift-right-zero-fill mask bitpos caching-hash
@@ -3144,3 +3144,16 @@
31443144

31453145
#?(:clj (. (var defmacro) (setMacro))
31463146
:cljs (set! (. defmacro -cljs$lang$macro) true))
3147+
3148+
(core/defmacro resolve
3149+
"Returns the var to which a symbol will be resolved in the namespace else nil."
3150+
[[_ sym]]
3151+
(core/let [env &env
3152+
[var meta] (try
3153+
(core/let [var (ana/resolve-var env sym (ana/confirm-var-exists-throw)) ]
3154+
[var (ana/var-meta var)])
3155+
(catch #?@(:clj [Throwable t] :cljs [:default e])
3156+
[(ana/resolve-var env sym) nil]))
3157+
resolved (vary-meta (:name var) assoc ::ana/no-resolve true)]
3158+
`(when (exists? ~resolved)
3159+
(cljs.core/Var. ~resolved '~resolved ~meta))))

0 commit comments

Comments
 (0)