Skip to content

Commit

Permalink
CLJS-717: #js tagged literal
Browse files Browse the repository at this point in the history
  • Loading branch information
swannodette committed Dec 6, 2013
1 parent a459707 commit 91f6a32
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 2 deletions.
20 changes: 19 additions & 1 deletion src/clj/cljs/tagged_literals.clj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -24,7 +24,25 @@
(catch Throwable e (catch Throwable e
(throw (RuntimeException. (.getMessage e)))))) (throw (RuntimeException. (.getMessage e))))))


(defn valid-js-literal-key? [k]
(or (string? k)
(and (keyword? k)
(nil? (namespace k)))))

(defn read-js
[form]
(assert (or (vector? form) (map? form))
"JavaScript literal must use map or vector notation")
(assert (or (not (map? form))
(every? valid-js-literal-key? (keys form)))
"JavaScript literal keys must be strings or unqualified keywords")
(if (map? form)
`(cljs.core/js-obj
~@(apply concat (map (fn [[k v]] [(name k) v]) form)))
`(cljs.core/array ~@form)))

(def ^:dynamic *cljs-data-readers* (def ^:dynamic *cljs-data-readers*
{'queue read-queue {'queue read-queue
'uuid read-uuid 'uuid read-uuid
'inst read-inst}) 'inst read-inst
'js read-js})
24 changes: 23 additions & 1 deletion src/cljs/cljs/reader.cljs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -525,6 +525,27 @@ nil if the end of stream has been reached")
(reader-error nil "Queue literal expects a vector for its elements."))) (reader-error nil "Queue literal expects a vector for its elements.")))




(defn ^:private read-js
[form]
(cond
(vector? form)
(let [arr (array)]
(doseq [x form]
(.push arr x))
arr)

(map? form)
(let [obj (js-obj)]
(doseq [[k v] form]
(aset obj (name k) v))
obj)

:else
(reader-error nil
(str "JS literal expects a vector or map containing "
"only string or unqualified keyword keys"))))


(defn ^:private read-uuid (defn ^:private read-uuid
[uuid] [uuid]
(if (string? uuid) (if (string? uuid)
Expand All @@ -533,7 +554,8 @@ nil if the end of stream has been reached")


(def *tag-table* (atom {"inst" read-date (def *tag-table* (atom {"inst" read-date
"uuid" read-uuid "uuid" read-uuid
"queue" read-queue})) "queue" read-queue
"js" read-js}))


(def *default-data-reader-fn* (def *default-data-reader-fn*
(atom nil)) (atom nil))
Expand Down
11 changes: 11 additions & 0 deletions test/cljs/cljs/core_test.cljs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2016,5 +2016,16 @@


(assert (= (count {some-x :foo some-y :bar}) 1)) (assert (= (count {some-x :foo some-y :bar}) 1))


;; CLJS-717

(assert (array? #js [1 2 3]))
(assert (= (alength #js [1 2 3]) 3))
(assert (= (seq #js [1 2 3]) (seq [1 2 3])))
(assert (= (set (js-keys #js {:foo "bar" :baz "woz"})) #{"foo" "baz"}))
(assert (= (aget #js {:foo "bar"} "foo") "bar"))
(assert (= (aget #js {"foo" "bar"} "foo") "bar"))
(assert (array? (aget #js {"foo" #js [1 2 3]} "foo")))
(assert (= (seq (aget #js {"foo" #js [1 2 3]} "foo")) '(1 2 3)))

:ok :ok
) )
11 changes: 11 additions & 0 deletions test/cljs/cljs/reader_test.cljs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -155,4 +155,15 @@
(catch js/Error e :ok))] (catch js/Error e :ok))]
(assert (= r :ok) (str "Failed to throw reader error for: " unicode-error)))) (assert (= r :ok) (str "Failed to throw reader error for: " unicode-error))))


;; CLJS-717

(assert (array? (reader/read-string "#js [1 2 3]")))
(assert (= (alength (reader/read-string "#js [1 2 3]")) 3))
(assert (= (seq (reader/read-string "#js [1 2 3]")) (seq [1 2 3])))
(assert (= (set (js-keys (reader/read-string "#js {:foo \"bar\" :baz \"woz\"}"))) #{"foo" "baz"}))
(assert (= (aget (reader/read-string "#js {:foo \"bar\"}") "foo") "bar"))
(assert (= (aget (reader/read-string "#js {\"foo\" \"bar\"}") "foo") "bar"))
(assert (array? (aget (reader/read-string "#js {\"foo\" #js [1 2 3]}") "foo")))
(assert (= (seq (aget (reader/read-string "#js {\"foo\" #js [1 2 3]}") "foo")) '(1 2 3)))

:ok) :ok)

0 comments on commit 91f6a32

Please sign in to comment.