Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

CLJS-647: Evaluate expressions for js-obj keys

JS objects are constructed in three phases. First, an object is
constructed using all key-value pairs with string literals as
their keys. Second, object keys are set for the key-value pairs
with symbols as their keys. Lastly, remaining key-value pairs
are let-bound, evaluated, and their keys are set via the
let-bound gensyms.
  • Loading branch information...
commit 7a912f32c7d26eb171862db03acd7184074c620b 1 parent 0e427a0
Travis Thieman thieman authored swannodette committed

Showing 2 changed files with 30 additions and 3 deletions. Show diff stats Hide diff stats

  1. +22 3 src/clj/cljs/core.clj
  2. +8 0 test/cljs/cljs/core_test.cljs
25 src/clj/cljs/core.clj
@@ -33,6 +33,7 @@
33 33
34 34 cond-> cond->> as-> some-> some->>])
35 35 (:require clojure.walk
  36 + clojure.set
36 37 cljs.compiler
37 38 [cljs.env :as env]))
38 39
@@ -1318,12 +1319,30 @@
1318 1319 ([& xs]
1319 1320 `(set (array ~@xs))))
1320 1321
1321   -(defmacro js-obj [& rest]
  1322 +(defn js-obj* [kvs]
1322 1323 (let [kvs-str (->> (repeat "~{}:~{}")
1323   - (take (quot (count rest) 2))
  1324 + (take (count kvs))
1324 1325 (interpose ",")
1325 1326 (apply core/str))]
1326   - (list* 'js* (core/str "{" kvs-str "}") rest)))
  1327 + (list* 'js* (core/str "{" kvs-str "}") (apply concat kvs))))
  1328 +
  1329 +(defmacro js-obj [& rest]
  1330 + (let [sym-or-str? (fn [x] (core/or (core/symbol? x) (core/string? x)))
  1331 + filter-on-keys (fn [f coll]
  1332 + (->> coll
  1333 + (filter (fn [[k _]] (f k)))
  1334 + (into {})))
  1335 + kvs (into {} (map vec (partition 2 rest)))
  1336 + sym-pairs (filter-on-keys core/symbol? kvs)
  1337 + expr->local (zipmap
  1338 + (filter (complement sym-or-str?) (keys kvs))
  1339 + (repeatedly gensym))
  1340 + obj (gensym "obj")]
  1341 + `(let [~@(apply concat (clojure.set/map-invert expr->local))
  1342 + ~obj ~(js-obj* (filter-on-keys core/string? kvs))]
  1343 + ~@(map (fn [[k v]] `(aset ~obj ~k ~v)) sym-pairs)
  1344 + ~@(map (fn [[k v]] `(aset ~obj ~v ~(core/get kvs k))) expr->local)
  1345 + ~obj)))
1327 1346
1328 1347 (defmacro alength [a]
1329 1348 (core/list 'js* "~{}.length" a))
8 test/cljs/cljs/core_test.cljs
@@ -1994,5 +1994,13 @@
1994 1994 (assert (= (keyword 123) nil))
1995 1995 (assert (= (keyword (js/Date.)) nil))
1996 1996
  1997 + ;; CLJS-647
  1998 + (let [keys #(vec (js-keys %))
  1999 + z "x"]
  2000 + (assert (= ["x"]
  2001 + (keys (js-obj "x" "y"))
  2002 + (keys (js-obj (identity "x") "y"))
  2003 + (keys (js-obj z "y")))))
  2004 +
1997 2005 :ok
1998 2006 )

0 comments on commit 7a912f3

Please sign in to comment.
Something went wrong with that request. Please try again.