Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9d3b8ec

Browse files
Matthew Huebertswannodette
Matthew Huebert
authored andcommittedJan 4, 2021
CLJS-3286: ns form does not merge ns-info
In self-host, the ns form overwrites existing mappings instead of merging them. As in Clojure, one should be able to call (ns X) to enter a namespace without modifying it.
1 parent 73cba74 commit 9d3b8ec

File tree

2 files changed

+48
-35
lines changed

2 files changed

+48
-35
lines changed
 

‎src/main/clojure/cljs/analyzer.cljc

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3036,6 +3036,38 @@
30363036
(symbol (str name-str "$macros"))
30373037
name)))
30383038

3039+
(defn- check-duplicate-aliases
3040+
[env old new]
3041+
(let [ns-name (:name old)]
3042+
(doseq [k [:requires :require-macros]]
3043+
(let [old-aliases (get old k)
3044+
new-aliases (get new k)]
3045+
(when-some [alias (some (set (keys new-aliases))
3046+
(->> old-aliases
3047+
(remove (fn [[k v :as entry]]
3048+
(or (= k v)
3049+
(= entry (find new-aliases k)))))
3050+
keys))]
3051+
(throw (error env
3052+
(str "Alias " alias " already exists in namespace " ns-name
3053+
", aliasing " (get old-aliases alias)))))))))
3054+
3055+
(defn- merge-ns-info [old new env]
3056+
(if (pos? (count old))
3057+
(let [deep-merge-keys
3058+
[:use-macros :require-macros :rename-macros
3059+
:uses :requires :renames :imports]]
3060+
#?(:clj
3061+
(when *check-alias-dupes*
3062+
(check-duplicate-aliases env old new)))
3063+
(merge
3064+
old
3065+
(select-keys new [:excludes])
3066+
(merge-with merge
3067+
(select-keys old deep-merge-keys)
3068+
(select-keys new deep-merge-keys))))
3069+
new))
3070+
30393071
(defmethod parse 'ns
30403072
[_ env [_ name & args :as form] _ opts]
30413073
(when-not *allow-ns*
@@ -3129,7 +3161,7 @@
31293161
:requires requires
31303162
:renames (merge renames core-renames)
31313163
:imports imports}]
3132-
(swap! env/*compiler* update-in [::namespaces name] merge ns-info)
3164+
(swap! env/*compiler* update-in [::namespaces name] merge-ns-info ns-info env)
31333165
(merge {:op :ns
31343166
:env env
31353167
:form form
@@ -3144,22 +3176,6 @@
31443176
(update-in [:requires]
31453177
(fn [m] (with-meta m {(@reload :require) true})))))))))
31463178

3147-
(defn- check-duplicate-aliases
3148-
[env old new]
3149-
(let [ns-name (:name old)]
3150-
(doseq [k [:requires :require-macros]]
3151-
(let [old-aliases (get old k)
3152-
new-aliases (get new k)]
3153-
(when-some [alias (some (set (keys new-aliases))
3154-
(->> old-aliases
3155-
(remove (fn [[k v :as entry]]
3156-
(or (= k v)
3157-
(= entry (find new-aliases k)))))
3158-
keys))]
3159-
(throw (error env
3160-
(str "Alias " alias " already exists in namespace " ns-name
3161-
", aliasing " (get old-aliases alias)))))))))
3162-
31633179
(defmethod parse 'ns*
31643180
[_ env [_ quoted-specs :as form] _ opts]
31653181
(when-let [not-quoted (->> (remove keyword? quoted-specs)
@@ -3222,24 +3238,8 @@
32223238
:uses uses
32233239
:requires requires
32243240
:renames (merge renames core-renames)
3225-
:imports imports}
3226-
ns-info
3227-
(let [ns-info' (get-in @env/*compiler* [::namespaces name])]
3228-
(if (pos? (count ns-info'))
3229-
(let [merge-keys
3230-
[:use-macros :require-macros :rename-macros
3231-
:uses :requires :renames :imports]]
3232-
#?(:clj
3233-
(when *check-alias-dupes*
3234-
(check-duplicate-aliases env ns-info' require-info)))
3235-
(merge
3236-
ns-info'
3237-
{:excludes excludes}
3238-
(merge-with merge
3239-
(select-keys ns-info' merge-keys)
3240-
(select-keys require-info merge-keys))))
3241-
require-info))]
3242-
(swap! env/*compiler* update-in [::namespaces name] merge ns-info)
3241+
:imports imports}]
3242+
(swap! env/*compiler* update-in [::namespaces name] merge-ns-info require-info env)
32433243
(merge {:op :ns*
32443244
:env env
32453245
:form form

‎src/test/self/self_host/test.cljs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,19 @@
871871
(is (== 1 value))
872872
(inc! l))))))
873873

874+
(deftest test-ns-merge
875+
(async done
876+
(cljs/eval-str st
877+
"(ns foo.bar (:require [bootstrap-test.core :refer [foo]]))
878+
(ns foo.bar)
879+
(foo 1 1)"
880+
nil
881+
{:eval node-eval
882+
:load node-load}
883+
(fn [{:keys [value error]}]
884+
(is (nil? error))
885+
(done)))))
886+
874887
(deftest test-cljs-1651
875888
(let [st (cljs/empty-state)]
876889
(async done

0 commit comments

Comments
 (0)
Please sign in to comment.