Skip to content

Commit 865a563

Browse files
authored
Merge branch 'master' into adv-source-map-sources
2 parents d3fb65b + d912f92 commit 865a563

File tree

11 files changed

+377
-72
lines changed

11 files changed

+377
-72
lines changed

src/main/cljs/cljs/core.cljs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3110,7 +3110,7 @@ reduces them without incurring seq initialization"
31103110
([] "")
31113111
([x] (if (nil? x)
31123112
""
3113-
(.join #js [x] "")))
3113+
(.toString x)))
31143114
([x & ys]
31153115
(loop [sb (StringBuffer. (str x)) more ys]
31163116
(if more
@@ -6002,6 +6002,10 @@ reduces them without incurring seq initialization"
60026002
(-empty [coll]
60036003
())
60046004

6005+
ICounted
6006+
(-count [coll]
6007+
(- (-count vec) (+ i off)))
6008+
60056009
IChunkedSeq
60066010
(-chunked-first [coll]
60076011
(array-chunk node off))
@@ -9304,7 +9308,10 @@ reduces them without incurring seq initialization"
93049308

93059309
ICollection
93069310
(-conj [coll o]
9307-
(PersistentHashSet. meta (assoc hash-map o nil) nil))
9311+
(let [m (-assoc hash-map o nil)]
9312+
(if (identical? m hash-map)
9313+
coll
9314+
(PersistentHashSet. meta m nil))))
93089315

93099316
IEmptyableCollection
93109317
(-empty [coll] (-with-meta (.-EMPTY PersistentHashSet) meta))
@@ -9341,7 +9348,10 @@ reduces them without incurring seq initialization"
93419348

93429349
ISet
93439350
(-disjoin [coll v]
9344-
(PersistentHashSet. meta (-dissoc hash-map v) nil))
9351+
(let [m (-dissoc hash-map v)]
9352+
(if (identical? m hash-map)
9353+
coll
9354+
(PersistentHashSet. meta m nil))))
93459355

93469356
IFn
93479357
(-invoke [coll k]
@@ -9459,7 +9469,10 @@ reduces them without incurring seq initialization"
94599469

94609470
ICollection
94619471
(-conj [coll o]
9462-
(PersistentTreeSet. meta (assoc tree-map o nil) nil))
9472+
(let [m (-assoc tree-map o nil)]
9473+
(if (identical? m tree-map)
9474+
coll
9475+
(PersistentTreeSet. meta m nil))))
94639476

94649477
IEmptyableCollection
94659478
(-empty [coll] (PersistentTreeSet. meta (-empty tree-map) 0))
@@ -9513,7 +9526,10 @@ reduces them without incurring seq initialization"
95139526

95149527
ISet
95159528
(-disjoin [coll v]
9516-
(PersistentTreeSet. meta (dissoc tree-map v) nil))
9529+
(let [m (-dissoc tree-map v)]
9530+
(if (identical? m tree-map)
9531+
coll
9532+
(PersistentTreeSet. meta m nil))))
95179533

95189534
IFn
95199535
(-invoke [coll k]
@@ -12599,10 +12615,14 @@ reduces them without incurring seq initialization"
1259912615
(let [k (if-not (keyword? k) k (keyword->obj-map-key k))]
1260012616
(if (string? k)
1260112617
(if-not (nil? (scan-array 1 k strkeys))
12602-
(let [new-strobj (obj-clone strobj strkeys)]
12603-
(gobject/set new-strobj k v)
12604-
(ObjMap. meta strkeys new-strobj nil)) ;overwrite
12605-
(let [new-strobj (obj-clone strobj strkeys) ; append
12618+
(if (identical? v (gobject/get strobj k))
12619+
coll
12620+
; overwrite
12621+
(let [new-strobj (obj-clone strobj strkeys)]
12622+
(gobject/set new-strobj k v)
12623+
(ObjMap. meta strkeys new-strobj nil)))
12624+
; append
12625+
(let [new-strobj (obj-clone strobj strkeys)
1260612626
new-keys (aclone strkeys)]
1260712627
(gobject/set new-strobj k v)
1260812628
(.push new-keys k)
@@ -12808,10 +12828,12 @@ reduces them without incurring seq initialization"
1280812828
i (scan-array-equiv 2 k new-bucket)]
1280912829
(aset new-hashobj h new-bucket)
1281012830
(if (some? i)
12811-
(do
12812-
; found key, replace
12813-
(aset new-bucket (inc i) v)
12814-
(HashMap. meta count new-hashobj nil))
12831+
(if (identical? v (aget new-bucket (inc i)))
12832+
coll
12833+
(do
12834+
; found key, replace
12835+
(aset new-bucket (inc i) v)
12836+
(HashMap. meta count new-hashobj nil)))
1281512837
(do
1281612838
; did not find key, append
1281712839
(.push new-bucket k v)
@@ -12950,7 +12972,10 @@ reduces them without incurring seq initialization"
1295012972

1295112973
ICollection
1295212974
(-conj [coll o]
12953-
(Set. meta (assoc hash-map o o) nil))
12975+
(let [new-hash-map (assoc hash-map o o)]
12976+
(if (identical? new-hash-map hash-map)
12977+
coll
12978+
(Set. meta new-hash-map nil))))
1295412979

1295512980
IEmptyableCollection
1295612981
(-empty [coll] (with-meta (. Set -EMPTY) meta))
@@ -12989,7 +13014,10 @@ reduces them without incurring seq initialization"
1298913014

1299013015
ISet
1299113016
(-disjoin [coll v]
12992-
(Set. meta (-dissoc hash-map v) nil))
13017+
(let [new-hash-map (-dissoc hash-map v)]
13018+
(if (identical? new-hash-map hash-map)
13019+
coll
13020+
(Set. meta new-hash-map nil))))
1299313021

1299413022
IEditableCollection
1299513023
(-as-transient [coll]

src/main/clojure/cljs/analyzer.cljc

Lines changed: 127 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2781,6 +2781,17 @@
27812781
(if (and (.exists cljcf) (.isFile cljcf))
27822782
cljcf))))))
27832783

2784+
(defn external-dep?
2785+
"Returns true if the library is an :external? foreign dep. This means no source is provided
2786+
for the library, i.e. it will be provided by some script tag on the page, or loaded by some
2787+
other means into the JS execution environment."
2788+
#?(:cljs {:tag boolean})
2789+
[dep]
2790+
(let [js-index (:js-dependency-index @env/*compiler*)]
2791+
(if-some [[_ {:keys [foreign external?]}] (find js-index (name (-> dep lib&sublib first)))]
2792+
(and foreign external?)
2793+
false)))
2794+
27842795
(defn foreign-dep?
27852796
#?(:cljs {:tag boolean})
27862797
[dep]
@@ -2828,13 +2839,20 @@
28282839
(error env
28292840
(error-message :undeclared-ns {:ns-sym dep :js-provide (name dep)}))))))))))))
28302841

2842+
(defn global-ns? [x]
2843+
(and (symbol? x)
2844+
(or (= 'js x)
2845+
(= "js" (namespace x)))))
2846+
28312847
(defn missing-use? [lib sym cenv]
2832-
(let [js-lib (get-in cenv [:js-dependency-index (name lib)])]
2833-
(and (= (get-in cenv [::namespaces lib :defs sym] ::not-found) ::not-found)
2834-
(not (= (get js-lib :group) :goog))
2835-
(not (get js-lib :closure-lib))
2836-
(not (node-module-dep? lib))
2837-
(not (dep-has-global-exports? lib)))))
2848+
;; ignore globals referred via :refer-global
2849+
(when-not (global-ns? lib)
2850+
(let [js-lib (get-in cenv [:js-dependency-index (name lib)])]
2851+
(and (= (get-in cenv [::namespaces lib :defs sym] ::not-found) ::not-found)
2852+
(not (= (get js-lib :group) :goog))
2853+
(not (get js-lib :closure-lib))
2854+
(not (node-module-dep? lib))
2855+
(not (dep-has-global-exports? lib))))))
28382856

28392857
(defn missing-rename? [sym cenv]
28402858
(let [lib (symbol (namespace sym))
@@ -3047,6 +3065,90 @@
30473065
ret
30483066
(recur fs ret true)))))
30493067

3068+
(defn parse-global-refer-spec
3069+
[env args]
3070+
(let [xs (filter #(-> % first (= :refer-global)) args)
3071+
cnt (count xs)]
3072+
(cond
3073+
(> cnt 1)
3074+
(throw (error env "Only one :refer-global form is allowed per namespace definition"))
3075+
3076+
(== cnt 1)
3077+
(let [[_ & {:keys [only rename] :as parsed-spec}] (first xs)
3078+
only-set (set only)
3079+
err-str "Only (:refer-global :only [names]) and optionally `:rename {from to}` specs supported.
3080+
:rename symbols must be present in :only"]
3081+
(when-not (or (empty? only)
3082+
(and (vector? only)
3083+
(every? symbol only)))
3084+
(throw (error env err-str)))
3085+
(when-not (or (empty? rename)
3086+
(and (map? rename)
3087+
(every? symbol (mapcat identity rename))
3088+
(every? only-set (keys rename))))
3089+
(throw (error env (str err-str (pr-str parsed-spec)))))
3090+
(when-not (every? #{:only :rename} (keys parsed-spec))
3091+
(throw (error env (str err-str (pr-str parsed-spec)))))
3092+
{:use (zipmap only (repeat 'js))
3093+
:rename (into {}
3094+
(map (fn [[orig new-name]]
3095+
[new-name (symbol "js" (str orig))]))
3096+
rename)}))))
3097+
3098+
(defn parse-global-require-spec
3099+
[env cenv deps aliases spec]
3100+
(if (or (symbol? spec) (string? spec))
3101+
(recur env cenv deps aliases [spec])
3102+
(do
3103+
(basic-validate-ns-spec env false spec)
3104+
(let [[lib & opts] spec
3105+
{alias :as referred :refer renamed :rename
3106+
:or {alias (if (string? lib)
3107+
(symbol (munge lib))
3108+
lib)}}
3109+
(apply hash-map opts)
3110+
referred-without-renamed (seq (remove (set (keys renamed)) referred))
3111+
[rk uk renk] [:require :use :rename]]
3112+
(when-not (or (symbol? alias) (nil? alias))
3113+
(throw
3114+
(error env
3115+
(parse-ns-error-msg spec
3116+
":as must be followed by a symbol in :require / :require-macros"))))
3117+
(when (some? alias)
3118+
(let [lib' ((:fns @aliases) alias)]
3119+
(when (and (some? lib') (not= lib lib'))
3120+
(throw (error env (parse-ns-error-msg spec ":as alias must be unique"))))
3121+
(when (= alias 'js)
3122+
(when-not (= lib (get-in @aliases [:fns 'js])) ; warn only once
3123+
(warning :js-used-as-alias env {:spec spec})))
3124+
(swap! aliases update-in [:fns] conj [alias lib])))
3125+
(when-not (or (and (sequential? referred)
3126+
(every? symbol? referred))
3127+
(nil? referred))
3128+
(throw
3129+
(error env
3130+
(parse-ns-error-msg spec
3131+
":refer must be followed by a sequence of symbols in :require / :require-macros"))))
3132+
(swap! deps conj lib)
3133+
(let [ret (merge
3134+
(when (some? alias)
3135+
{rk (merge {alias lib} {lib lib})})
3136+
(when (some? referred-without-renamed)
3137+
{uk (apply hash-map (interleave referred-without-renamed (repeat lib)))})
3138+
(when (some? renamed)
3139+
{renk (reduce (fn [m [original renamed]]
3140+
(when-not (some #{original} referred)
3141+
(throw (error env
3142+
(str "Renamed symbol " original " not referred"))))
3143+
(assoc m renamed (symbol (str lib) (str original))))
3144+
{} renamed)}))]
3145+
(swap! cenv assoc-in [:js-dependency-index (str lib)]
3146+
{:external? true
3147+
:foreign true
3148+
:provides [(str lib)]
3149+
:global-exports {lib lib}})
3150+
ret)))))
3151+
30503152
(defn parse-require-spec [env macros? deps aliases spec]
30513153
(if (or (symbol? spec) (string? spec))
30523154
(recur env macros? deps aliases [spec])
@@ -3300,6 +3402,10 @@
33003402
(select-keys new deep-merge-keys))))
33013403
new))
33023404

3405+
(def ns-spec-cases
3406+
#{:use :use-macros :require :require-macros
3407+
:import :refer-global :require-global})
3408+
33033409
(defmethod parse 'ns
33043410
[_ env [_ name & args :as form] _ opts]
33053411
(when-not *allow-ns*
@@ -3334,6 +3440,7 @@
33343440
core-renames (reduce (fn [m [original renamed]]
33353441
(assoc m renamed (symbol "cljs.core" (str original))))
33363442
{} core-renames)
3443+
{global-uses :use global-renames :rename} (parse-global-refer-spec env args)
33373444
deps (atom [])
33383445
;; as-aliases can only be used *once* because they are about the reader
33393446
aliases (atom {:fns as-aliases :macros as-aliases})
@@ -3343,17 +3450,18 @@
33433450
(partial use->require env))
33443451
:use-macros (comp (partial parse-require-spec env true deps aliases)
33453452
(partial use->require env))
3346-
:import (partial parse-import-spec env deps)}
3347-
valid-forms (atom #{:use :use-macros :require :require-macros :import})
3453+
:import (partial parse-import-spec env deps)
3454+
:require-global #(parse-global-require-spec env env/*compiler* deps aliases %)}
3455+
valid-forms (atom #{:use :use-macros :require :require-macros :require-global :import})
33483456
reload (atom {:use nil :require nil :use-macros nil :require-macros nil})
33493457
reloads (atom {})
33503458
{uses :use requires :require renames :rename
33513459
use-macros :use-macros require-macros :require-macros
33523460
rename-macros :rename-macros imports :import :as params}
33533461
(reduce
33543462
(fn [m [k & libs :as libspec]]
3355-
(when-not (#{:use :use-macros :require :require-macros :import} k)
3356-
(throw (error env (str "Only :refer-clojure, :require, :require-macros, :use, :use-macros, and :import libspecs supported. Got " libspec " instead."))))
3463+
(when-not (#{:use :use-macros :require :require-macros :require-global :import} k)
3464+
(throw (error env (str "Only :refer-clojure, :require, :require-macros, :use, :use-macros, :require-global and :import libspecs supported. Got " libspec " instead."))))
33573465
(when-not (@valid-forms k)
33583466
(throw (error env (str "Only one " k " form is allowed per namespace definition"))))
33593467
(swap! valid-forms disj k)
@@ -3370,7 +3478,7 @@
33703478
(apply merge-with merge m
33713479
(map (spec-parsers k)
33723480
(remove #{:reload :reload-all} libs))))
3373-
{} (remove (fn [[r]] (= r :refer-clojure)) args))
3481+
{} (remove (fn [[r]] (#{:refer-clojure :refer-global} r)) args))
33743482
;; patch `require-macros` and `use-macros` in Bootstrap for namespaces
33753483
;; that require their own macros
33763484
#?@(:cljs [[require-macros use-macros]
@@ -3392,9 +3500,9 @@
33923500
:use-macros use-macros
33933501
:require-macros require-macros
33943502
:rename-macros rename-macros
3395-
:uses uses
3503+
:uses (merge uses global-uses)
33963504
:requires requires
3397-
:renames (merge renames core-renames)
3505+
:renames (merge renames core-renames global-renames)
33983506
:imports imports}]
33993507
(swap! env/*compiler* update-in [::namespaces name] merge ns-info)
34003508
(merge {:op :ns
@@ -3434,6 +3542,7 @@
34343542
core-renames (reduce (fn [m [original renamed]]
34353543
(assoc m renamed (symbol "cljs.core" (str original))))
34363544
{} core-renames)
3545+
{global-uses :use global-renames :rename} (parse-global-refer-spec env args)
34373546
deps (atom [])
34383547
;; as-aliases can only be used *once* because they are about the reader
34393548
aliases (atom {:fns as-aliases :macros as-aliases})
@@ -3443,7 +3552,8 @@
34433552
(partial use->require env))
34443553
:use-macros (comp (partial parse-require-spec env true deps aliases)
34453554
(partial use->require env))
3446-
:import (partial parse-import-spec env deps)}
3555+
:import (partial parse-import-spec env deps)
3556+
:require-global #(parse-global-require-spec env env/*compiler* deps aliases %)}
34473557
reload (atom {:use nil :require nil :use-macros nil :require-macros nil})
34483558
reloads (atom {})
34493559
{uses :use requires :require renames :rename
@@ -3464,7 +3574,7 @@
34643574
(apply merge-with merge m
34653575
(map (spec-parsers k)
34663576
(remove #{:reload :reload-all} libs))))
3467-
{} (remove (fn [[r]] (= r :refer-clojure)) args))]
3577+
{} (remove (fn [[r]] (#{:refer-clojure :refer-global} r)) args))]
34683578
(set! *cljs-ns* name)
34693579
(let [require-info
34703580
{:as-aliases as-aliases
@@ -3473,9 +3583,9 @@
34733583
:use-macros use-macros
34743584
:require-macros require-macros
34753585
:rename-macros rename-macros
3476-
:uses uses
3586+
:uses (merge uses global-uses)
34773587
:requires requires
3478-
:renames (merge renames core-renames)
3588+
:renames (merge renames core-renames global-renames)
34793589
:imports imports}]
34803590
(swap! env/*compiler* update-in [::namespaces name] merge-ns-info require-info env)
34813591
(merge {:op :ns*

0 commit comments

Comments
 (0)