Skip to content

Commit b44d0e0

Browse files
anmonteiroswannodette
authored andcommitted
CLJS-1719: Port destructuring namespaced keys and symbols
1 parent 7084cfc commit b44d0e0

File tree

3 files changed

+82
-14
lines changed

3 files changed

+82
-14
lines changed

src/main/clojure/cljs/core.cljc

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -657,24 +657,40 @@
657657
(if (:as b)
658658
(conj ret (:as b) gmap)
659659
ret))))
660-
bes (reduce
661-
(core/fn [bes entry]
662-
(reduce #(assoc %1 %2 ((val entry) %2))
663-
(dissoc bes (key entry))
664-
((key entry) bes)))
665-
(dissoc b :as :or)
666-
{:keys #(if (core/keyword? %) % (keyword (core/str %))),
667-
:strs core/str, :syms #(core/list `quote %)})]
660+
bes (core/let [transforms
661+
(reduce
662+
(core/fn [transforms mk]
663+
(if (core/keyword? mk)
664+
(core/let [mkns (namespace mk)
665+
mkn (name mk)]
666+
(core/cond (= mkn "keys") (assoc transforms mk #(keyword (core/or mkns (namespace %)) (name %)))
667+
(= mkn "syms") (assoc transforms mk #(core/list `quote (symbol (core/or mkns (namespace %)) (name %))))
668+
(= mkn "strs") (assoc transforms mk core/str)
669+
:else transforms))
670+
transforms))
671+
{}
672+
(keys b))]
673+
(reduce
674+
(core/fn [bes entry]
675+
(reduce #(assoc %1 %2 ((val entry) %2))
676+
(dissoc bes (key entry))
677+
((key entry) bes)))
678+
(dissoc b :as :or)
679+
transforms))]
668680
(if (seq bes)
669681
(core/let [bb (key (first bes))
670682
bk (val (first bes))
671-
bv (if (contains? defaults bb)
672-
(core/list 'cljs.core/get gmap bk (defaults bb))
683+
local (if #?(:clj (core/instance? clojure.lang.Named bb)
684+
:cljs (cljs.core/implements? INamed bb))
685+
(symbol nil (name bb))
686+
bb)
687+
bv (if (contains? defaults local)
688+
(core/list 'cljs.core/get gmap bk (defaults local))
673689
(core/list 'cljs.core/get gmap bk))]
674-
(recur (core/cond
675-
(core/symbol? bb) (core/-> ret (conj (if (namespace bb) (symbol (name bb)) bb)) (conj bv))
676-
(core/keyword? bb) (core/-> ret (conj (symbol (name bb)) bv))
677-
:else (pb ret bb bv))
690+
(recur
691+
(if (core/or (core/keyword? bb) (core/symbol? bb)) ;(ident? bb)
692+
(core/-> ret (conj local bv))
693+
(pb ret bb bv))
678694
(next bes)))
679695
ret))))]
680696
(core/cond

src/test/cljs/cljs/core_test.cljs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,43 @@
989989
(is (= y 2))))
990990
)))
991991

992+
(deftest keywords-in-destructuring
993+
(let [m {:a 1 :b 2}]
994+
(let [{:keys [:a :b]} m]
995+
(is (= [1 2] [a b])))
996+
(let [{:keys [:a :b :c] :or {c 3}} m]
997+
(is (= [1 2 3] [a b c])))))
998+
999+
(deftest namespaced-keywords-in-destructuring
1000+
(let [m {:a/b 1 :c/d 2}]
1001+
(let [{:keys [:a/b :c/d]} m]
1002+
(is (= [1 2] [b d])))
1003+
(let [{:keys [:a/b :c/d :e/f] :or {f 3}} m]
1004+
(is (= [1 2 3] [b d f])))))
1005+
1006+
(deftest namespaced-keys-in-destructuring
1007+
(let [m {:a/b 1 :c/d 2}]
1008+
(let [{:keys [a/b c/d]} m]
1009+
(is (= [1 2] [b d])))
1010+
(let [{:keys [a/b c/d e/f] :or {f 3}} m]
1011+
(is (= [1 2 3] [b d f])))))
1012+
1013+
(deftest namespaced-syms-in-destructuring
1014+
(let [{:syms [a/b c/d e/f] :or {f 3}} {'a/b 1 'c/d 2}]
1015+
(is (= [1 2 3] [b d f]))))
1016+
1017+
(deftest namespaced-keys-syntax
1018+
(let [{:a/keys [b c d] :or {d 3}} {:a/b 1 :a/c 2}]
1019+
(is (= [1 2 3] [b c d]))))
1020+
1021+
(deftest namespaced-syms-syntax
1022+
(let [{:a/syms [b c d] :or {d 3}} {'a/b 1 'a/c 2}]
1023+
(is (= [1 2 3] [b c d]))))
1024+
1025+
(deftest resolve-keyword-ns-alias-in-destructuring
1026+
(let [{:keys [::s/x ::s/y ::s/z] :or {z 3}} {:clojure.string/x 1 :clojure.string/y 2}]
1027+
(is (= [1 2 3] [x y z]))))
1028+
9921029
(deftest test-in-operations
9931030
(testing "Testing update-in"
9941031
(is (= {:foo {:bar {:baz 1}}}

src/test/clojure/cljs/compiler_tests.clj

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,21 @@
102102
(defmacro capture-warnings [& body]
103103
`(capture-warnings* (fn [] ~@body)))
104104

105+
(deftest or-doesnt-create-bindings
106+
(let [cenv (atom @cenv)]
107+
(binding [ana/*cljs-static-fns* true
108+
ana/*analyze-deps* false]
109+
(env/with-compiler-env cenv
110+
(ana/analyze-file (File. "src/main/cljs/cljs/core.cljs"))
111+
(let [warnings (-> (capture-warnings
112+
(with-out-str
113+
(comp/emit
114+
(ana/analyze aenv
115+
'(let [{:keys [a] :or {b 2}} {:a 1}] [a b]))))))]
116+
(is (= (ffirst warnings) :undeclared-var))
117+
(is (.startsWith (-> warnings first second)
118+
"WARNING: Use of undeclared Var cljs.user/b")))))))
119+
105120
(deftest no-warn-on-emit-invoke-protocol-method
106121
(let [define-foo #(assoc-in % [::ana/namespaces 'cljs.user :defs 'foo]
107122
{:ns 'cljs.user

0 commit comments

Comments
 (0)