Skip to content

Commit 68894f0

Browse files
committed
CLJS-891: Defs in "parent" namespaces clash with "child" namespaces with the same name?
check in both 'def and 'ns cases of the analyzer for namespace / var clashes
1 parent b0b135b commit 68894f0

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

src/clj/cljs/analyzer.clj

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@
6969
:protocol-duped-method true
7070
:protocol-multiple-impls true
7171
:single-segment-namespace true
72-
:munged-namespace true})
72+
:munged-namespace true
73+
:ns-var-clash true})
7374

7475
(def js-reserved
7576
#{"abstract" "boolean" "break" "byte" "case"
@@ -209,6 +210,10 @@
209210
(str "Namespace " name " contains a reserved JavaScript keyword,"
210211
" the corresponding Google Closure namespace will be munged to " munged)))
211212

213+
(defmethod error-message :ns-var-clash
214+
[warning-type {:keys [ns var] :as info}]
215+
(str "Namespace " ns " clashes with var " var))
216+
212217
(defn ^:private default-warning-handler [warning-type env extra]
213218
(when (warning-type *cljs-warnings*)
214219
(when-let [s (error-message warning-type extra)]
@@ -770,7 +775,12 @@
770775
protocol (-> sym meta :protocol)
771776
dynamic (-> sym meta :dynamic)
772777
ns-name (-> env :ns :name)
773-
locals (:locals env)]
778+
locals (:locals env)
779+
clash-ns (symbol (str ns-name "." sym))]
780+
(when (get-in @env/*compiler* [::namespaces clash-ns])
781+
(warning :ns-var-clash env
782+
{:ns (symbol (str ns-name "." sym))
783+
:var (symbol (str ns-name) (str sym))}))
774784
(when (namespace sym)
775785
(throw (error env "Can't def ns-qualified name")))
776786
(when-let [doc (:doc args)]
@@ -1406,6 +1416,17 @@
14061416
(update-in indexed [:require-macros] (fnil into []) require-specs))
14071417
args)))
14081418

1419+
(defn find-def-clash [env ns segments]
1420+
(let [to-check (map (fn [xs]
1421+
[(symbol (string/join "." (butlast xs)))
1422+
(symbol (last xs))])
1423+
(drop 2 (reductions conj [] segments)))]
1424+
(doseq [[clash-ns name] to-check]
1425+
(when (get-in @env/*compiler* [::namespaces clash-ns :defs name])
1426+
(warning :ns-var-clash env
1427+
{:ns ns
1428+
:var (symbol (str clash-ns) (str name))})))))
1429+
14091430
(defmethod parse 'ns
14101431
[_ env [_ name & args :as form] _ opts]
14111432
(when-not (symbol? name)
@@ -1414,7 +1435,8 @@
14141435
(when (= 1 (count segments))
14151436
(warning :single-segment-namespace env {:name name}))
14161437
(when (some js-reserved segments)
1417-
(warning :munged-namespace env {:name name})))
1438+
(warning :munged-namespace env {:name name}))
1439+
(find-def-clash env name segments))
14181440
(let [docstring (if (string? (first args)) (first args))
14191441
mdocstr (-> name meta :doc)
14201442
args (if docstring (next args) args)

0 commit comments

Comments
 (0)