Skip to content

Commit 04751f3

Browse files
anmonteirodnolen
authored andcommitted
CLJS-1782: Self-host: allow namespaces to require their own macros
1 parent fb8a084 commit 04751f3

File tree

1 file changed

+43
-12
lines changed

1 file changed

+43
-12
lines changed

src/main/clojure/cljs/analyzer.cljc

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,7 +2230,19 @@
22302230
(apply merge-with merge m
22312231
(map (spec-parsers k)
22322232
(remove #{:reload :reload-all} libs))))
2233-
{} (remove (fn [[r]] (= r :refer-clojure)) args))]
2233+
{} (remove (fn [[r]] (= r :refer-clojure)) args))
2234+
;; patch `require-macros` and `use-macros` in Bootstrap for namespaces
2235+
;; that require their own macros
2236+
#?@(:cljs [[require-macros use-macros]
2237+
(map (fn [spec-map]
2238+
(if (:macros-ns opts)
2239+
(let [ns (symbol (subs (str name) 0 (- (count (str name)) 7)))]
2240+
(reduce (fn [m [k v]]
2241+
(cond-> m
2242+
(not (symbol-identical? v ns))
2243+
(assoc k v)))
2244+
{} spec-map))
2245+
spec-map)) [require-macros use-macros])])]
22342246
(set! *cljs-ns* name)
22352247
(let [ns-info
22362248
{:name name
@@ -2528,10 +2540,17 @@
25282540
fexpr (analyze enve f)
25292541
argc (count args)
25302542
fn-var? (-> fexpr :info :fn-var)
2531-
kw? (= 'cljs.core/Keyword (:tag fexpr))]
2543+
kw? (= 'cljs.core/Keyword (:tag fexpr))
2544+
cur-ns (-> env :ns :name)]
25322545
(when ^boolean fn-var?
2533-
(let [{:keys [^boolean variadic max-fixed-arity method-params name]} (:info fexpr)]
2534-
(when (and (not (valid-arity? argc method-params))
2546+
(let [{:keys [^boolean variadic max-fixed-arity method-params name ns macro]} (:info fexpr)]
2547+
;; don't warn about invalid arity when when compiling a macros namespace
2548+
;; that requires itself, as that code is not meant to be executed in the
2549+
;; `$macros` ns - António Monteiro
2550+
(when (and #?(:cljs (not (and (gstring/endsWith (str cur-ns) "$macros")
2551+
(symbol-identical? cur-ns ns)
2552+
(true? macro))))
2553+
(not (valid-arity? argc method-params))
25352554
(or (not variadic)
25362555
(and variadic (< argc max-fixed-arity))))
25372556
(warning :fn-arity env {:name name :argc argc}))))
@@ -2581,14 +2600,26 @@
25812600
lb (get lcls sym)]
25822601
(if-not (nil? lb)
25832602
(assoc ret :op :var :info lb)
2584-
(if-not (true? (:def-var env))
2585-
(let [sym-meta (meta sym)
2586-
info (if-not (contains? sym-meta ::analyzed)
2587-
(resolve-existing-var env sym)
2588-
(resolve-var env sym))]
2589-
(assoc ret :op :var :info info))
2590-
(let [info (resolve-var env sym)]
2591-
(assoc ret :op :var :info info)))))))
2603+
(let [sym-meta (meta sym)
2604+
sym-ns (namespace sym)
2605+
cur-ns (str (-> env :ns :name))
2606+
;; when compiling a macros namespace that requires itself, we need
2607+
;; to resolve calls to `my-ns.core/foo` to `my-ns.core$macros/foo`
2608+
;; to avoid undeclared variable warnings - António Monteiro
2609+
#?@(:cljs [sym (if (and sym-ns
2610+
(not= sym-ns "cljs.core")
2611+
(gstring/endsWith cur-ns "$macros")
2612+
(not (gstring/endsWith sym-ns "$macros"))
2613+
(= sym-ns (subs cur-ns 0 (- (count cur-ns) 7))))
2614+
(symbol (str sym-ns "$macros") (name sym))
2615+
sym)])
2616+
info (if-not (contains? sym-meta ::analyzed)
2617+
(resolve-existing-var env sym)
2618+
(resolve-var env sym))]
2619+
(if-not (true? (:def-var env))
2620+
(assoc ret :op :var :info info)
2621+
(let [info (resolve-var env sym)]
2622+
(assoc ret :op :var :info info))))))))
25922623

25932624
(defn excluded?
25942625
#?(:cljs {:tag boolean})

0 commit comments

Comments
 (0)