Skip to content

Commit 4dd8c87

Browse files
committed
Merge branch 'master' of github.com:clojure/clojurescript
2 parents 53e59c5 + 3b5d88a commit 4dd8c87

File tree

13 files changed

+132
-46
lines changed

13 files changed

+132
-46
lines changed

pom.template.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<dependency>
3131
<groupId>com.google.javascript</groupId>
3232
<artifactId>closure-compiler-unshaded</artifactId>
33-
<version>v20170521</version>
33+
<version>v20170626</version>
3434
</dependency>
3535
<dependency>
3636
<groupId>org.clojure</groupId>

project.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
[org.clojure/test.check "0.9.0" :scope "test"]
1515
[com.cognitect/transit-clj "0.8.300"]
1616
[org.clojure/google-closure-library "0.0-20170519-fa0499ef"]
17-
[com.google.javascript/closure-compiler-unshaded "v20170521"]
17+
[com.google.javascript/closure-compiler-unshaded "v20170626"]
1818
[org.mozilla/rhino "1.7R5"]]
1919
:profiles {:1.6 {:dependencies [[org.clojure/clojure "1.6.0"]]}
2020
:uberjar {:aot :all :main clojure.main}}

script/bootstrap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set -e
55
CLOJURE_RELEASE="1.9.0-alpha16"
66
SPEC_ALPHA_RELEASE="0.1.108"
77
CORE_SPECS_ALPHA_RELEASE="0.1.10"
8-
CLOSURE_RELEASE="20170521"
8+
CLOSURE_RELEASE="20170626"
99
DJSON_RELEASE="0.2.6"
1010
TRANSIT_RELEASE="0.8.285"
1111
GCLOSURE_LIB_RELEASE="0.0-20160609-f42b4a24"

src/main/cljs/cljs/core.cljs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@
255255
[p x]
256256
(let [x (if (nil? x) nil x)]
257257
(cond
258-
(aget p (goog/typeOf x)) true
259-
(aget p "_") true
258+
(unsafe-get p (goog/typeOf x)) true
259+
(unsafe-get p "_") true
260260
:else false)))
261261
(set! *unchecked-if* false)
262262

@@ -887,7 +887,7 @@
887887

888888
(defn add-to-string-hash-cache [k]
889889
(let [h (hash-string* k)]
890-
(aset string-hash-cache k h)
890+
(gobject/set string-hash-cache k h)
891891
(set! string-hash-cache-count (inc string-hash-cache-count))
892892
h))
893893

@@ -897,7 +897,7 @@
897897
(set! string-hash-cache-count 0))
898898
(if (nil? k)
899899
0
900-
(let [h (aget string-hash-cache k)]
900+
(let [h (unsafe-get string-hash-cache k)]
901901
(if (number? h)
902902
h
903903
(add-to-string-hash-cache k)))))
@@ -2927,7 +2927,7 @@ reduces them without incurring seq initialization"
29272927
[obj fn-map]
29282928
(doseq [[key-name f] fn-map]
29292929
(let [str-name (name key-name)]
2930-
(aset obj str-name f)))
2930+
(gobject/set obj str-name f)))
29312931
obj)
29322932

29332933
;;;;;;;;;;;;;;;; cons ;;;;;;;;;;;;;;;;
@@ -5998,7 +5998,7 @@ reduces them without incurring seq initialization"
59985998
(loop [i 0]
59995999
(when (< i l)
60006000
(let [k (aget ks i)]
6001-
(aset new-obj k (aget obj k))
6001+
(gobject/set new-obj k (gobject/get obj k))
60026002
(recur (inc i)))))
60036003
new-obj))
60046004

@@ -8458,7 +8458,7 @@ reduces them without incurring seq initialization"
84588458
(loop [kvs (seq keyvals)]
84598459
(if kvs
84608460
(do (.push ks (first kvs))
8461-
(aset obj (first kvs) (second kvs))
8461+
(gobject/set obj (first kvs) (second kvs))
84628462
(recur (nnext kvs)))
84638463
(.fromObject ObjMap ks obj)))))
84648464

@@ -9532,7 +9532,7 @@ reduces them without incurring seq initialization"
95329532
[s]
95339533
(str \"
95349534
(.replace s (js/RegExp "[\\\\\"\b\f\n\r\t]" "g")
9535-
(fn [match] (aget char-escapes match)))
9535+
(fn [match] (unsafe-get char-escapes match)))
95369536
\"))
95379537

95389538
(declare print-map)
@@ -10151,7 +10151,7 @@ reduces them without incurring seq initialization"
1015110151
(symbol? x) (str x)
1015210152
(map? x) (let [m (js-obj)]
1015310153
(doseq [[k v] x]
10154-
(aset m (key->js k) (clj->js v)))
10154+
(gobject/set m (key->js k) (clj->js v)))
1015510155
m)
1015610156
(coll? x) (let [arr (array)]
1015710157
(doseq [x (map clj->js x)]

src/main/cljs/cljs/reader.cljs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
(ns cljs.reader
1010
(:require-macros [cljs.reader :refer [add-data-readers]])
11-
(:require [goog.string :as gstring])
11+
(:require [goog.object :as gobject]
12+
[goog.string :as gstring])
1213
(:import goog.string.StringBuffer))
1314

1415
(defprotocol PushbackReader
@@ -580,7 +581,7 @@ nil if the end of stream has been reached")
580581
(map? form)
581582
(let [obj (js-obj)]
582583
(doseq [[k v] form]
583-
(aset obj (name k) v))
584+
(gobject/set obj (name k) v))
584585
obj)
585586

586587
:else

src/main/clojure/cljs/analyzer.cljc

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@
134134
:extending-base-js-type true
135135
:invoke-ctor true
136136
:invalid-arithmetic true
137+
:invalid-aget false
138+
:invalid-aset false
137139
:protocol-invalid-method true
138140
:protocol-duped-method true
139141
:protocol-multiple-impls true
@@ -391,6 +393,24 @@
391393
[warning-type info]
392394
(str (:js-op info) ", all arguments must be numbers, got " (:types info) " instead."))
393395

396+
(defmethod error-message :invalid-aget
397+
[warning-type info]
398+
(str (:js-op info) ", arguments must be an array followed by numeric indices, got " (:types info) " instead"
399+
(when (or (= 'object (first (:types info)))
400+
(every? #{'string} (rest (:types info))))
401+
(str " (consider "
402+
(if (== 2 (count (:types info)))
403+
"goog.object/get"
404+
"goog.object/getValueByKeys")
405+
" for object access)"))))
406+
407+
(defmethod error-message :invalid-aset
408+
[warning-type info]
409+
(str (:js-op info) ", arguments must be an array, followed by numeric indices, followed by a value, got " (:types info) " instead"
410+
(when (or (= 'object (first (:types info)))
411+
(every? #{'string} (butlast (rest (:types info)))))
412+
" (consider goog.object/set for object access)")))
413+
394414
(defmethod error-message :invoke-ctor
395415
[warning-type info]
396416
(str "Cannot invoke type constructor " (-> info :fexpr :info :name) " as function "))
@@ -2822,20 +2842,48 @@
28222842
(contains? t 'any)
28232843
(contains? t 'js))))))
28242844

2845+
(defn array-type?
2846+
#?(:cljs {:tag boolean})
2847+
[t]
2848+
;; TODO same inference caveats as the numeric-type? fn above
2849+
(cond
2850+
(nil? t) true
2851+
(= 'clj-nil t) true
2852+
(js-tag? t) true ;; TODO: revisit
2853+
:else
2854+
(if (and (symbol? t) (some? (get '#{any array} t)))
2855+
true
2856+
(when #?(:clj (set? t)
2857+
:cljs (cljs-set? t))
2858+
(or (contains? t 'array)
2859+
(contains? t 'any)
2860+
(contains? t 'js))))))
2861+
28252862
(defn analyze-js-star* [env jsform args form]
28262863
(let [enve (assoc env :context :expr)
28272864
argexprs (vec (map #(analyze enve %) args))
28282865
form-meta (meta form)
28292866
segs (js-star-seg jsform)
28302867
tag (get-js-tag form)
28312868
js-op (:js-op form-meta)
2832-
numeric (:numeric form-meta)]
2869+
numeric (:numeric form-meta)
2870+
validate (fn [warning-type valid-types?]
2871+
(let [types (map #(infer-tag env %) argexprs)]
2872+
(when-not (valid-types? types)
2873+
(warning warning-type env
2874+
{:js-op js-op
2875+
:types (into [] types)}))))
2876+
op-match? (fn [sym]
2877+
#?(:clj (= sym (:js-op form-meta))
2878+
:cljs (symbol-identical? sym (:js-op form-meta))))]
28332879
(when (true? numeric)
2834-
(let [types (map #(infer-tag env %) argexprs)]
2835-
(when-not (every? numeric-type? types)
2836-
(warning :invalid-arithmetic env
2837-
{:js-op js-op
2838-
:types (into [] types)}))))
2880+
(validate :invalid-arithmetic #(every? numeric-type? %)))
2881+
(when (op-match? 'cljs.core/aget)
2882+
(validate :invalid-aget #(and (array-type? (first %))
2883+
(every? numeric-type? (rest %)))))
2884+
(when (op-match? 'cljs.core/aset)
2885+
(validate :invalid-aset #(and (array-type? (first %))
2886+
(every? numeric-type? (butlast (rest %))))))
28392887
{:op :js
28402888
:env env
28412889
:segs segs

src/main/clojure/cljs/closure.clj

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,7 @@
6161
SourceMap$DetailLevel ClosureCodingConvention SourceFile
6262
Result JSError CheckLevel DiagnosticGroups
6363
CommandLineRunner AnonymousFunctionNamingPolicy
64-
JSModule SourceMap ProcessCommonJSModules
65-
AbstractCompiler TransformAMDToCJSModule
66-
ProcessEs6Modules CompilerInput]
64+
JSModule SourceMap]
6765
[com.google.javascript.jscomp.deps ModuleLoader$ResolutionMode]
6866
[com.google.javascript.rhino Node]
6967
[java.nio.file Path Paths Files StandardWatchEventKinds WatchKey
@@ -1473,7 +1471,8 @@
14731471
(str "document.write('<script>goog.require(\"" (comp/munge entry)"\");</script>');\n"))
14741472
(if-let [entries (:entries opts)]
14751473
entries
1476-
[(:main opts)]))))))))
1474+
(when-let [main (:main opts)]
1475+
[main])))))))))
14771476

14781477
(defn output-modules
14791478
"Given compiler options, original IJavaScript sources and a sequence of

src/main/clojure/cljs/core.cljc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,12 @@
993993
astr (apply core/str (repeat n "[~{}]"))]
994994
`(~'js* ~(core/str "(~{}[~{}][~{}]" astr " = ~{})") ~a ~idx ~idx2 ~@idxv))))
995995

996+
(core/defmacro unsafe-get
997+
"Efficient alternative to goog.object/get which lacks opt_val and emits
998+
unchecked property access."
999+
[obj key]
1000+
(core/list 'js* "(~{}[~{}])" obj key))
1001+
9961002
(core/defmacro ^::ana/numeric +
9971003
([] 0)
9981004
([x] x)
@@ -1376,9 +1382,9 @@
13761382
(core/let [psym (resolve p)
13771383
pfn-prefix (subs (core/str psym) 0
13781384
(clojure.core/inc (.indexOf (core/str psym) "/")))]
1379-
(cons `(aset ~psym ~type true)
1385+
(cons `(goog.object/set ~psym ~type true)
13801386
(map (core/fn [[f & meths :as form]]
1381-
`(aset ~(symbol (core/str pfn-prefix f))
1387+
`(goog.object/set ~(symbol (core/str pfn-prefix f))
13821388
~type ~(with-meta `(fn ~@meths) (meta form))))
13831389
sigs))))
13841390

@@ -1977,10 +1983,10 @@
19771983
(not (nil? (. ~(first sig) ~(symbol (core/str "-" slot)))))) ;; Property access needed here.
19781984
(. ~(first sig) ~slot ~@sig)
19791985
(let [x# (if (nil? ~(first sig)) nil ~(first sig))
1980-
m# (aget ~(fqn fname) (goog/typeOf x#))]
1986+
m# (unsafe-get ~(fqn fname) (goog/typeOf x#))]
19811987
(if-not (nil? m#)
19821988
(m# ~@sig)
1983-
(let [m# (aget ~(fqn fname) "_")]
1989+
(let [m# (unsafe-get ~(fqn fname) "_")]
19841990
(if-not (nil? m#)
19851991
(m# ~@sig)
19861992
(throw
@@ -2740,7 +2746,7 @@
27402746
(core/list 'js* "''+~{}" s))
27412747

27422748
(core/defmacro es6-iterable [ty]
2743-
`(aset (.-prototype ~ty) cljs.core/ITER_SYMBOL
2749+
`(goog.object/set (.-prototype ~ty) cljs.core/ITER_SYMBOL
27442750
(fn []
27452751
(this-as this#
27462752
(cljs.core/es6-iterator this#)))))

src/test/cljs/cljs/core_test.cljs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
(:refer-clojure :exclude [iter])
1111
(:require [cljs.test :refer-macros [deftest testing is]]
1212
[clojure.string :as s]
13-
[clojure.set :as set]))
13+
[clojure.set :as set]
14+
[goog.object :as gobject]))
1415

1516
(deftest test-metadata
1617
(testing "Testing metadata"
@@ -143,11 +144,11 @@
143144
(is (goog/isArray (clj->js #{})))
144145
(is (goog/isArray (clj->js '())))
145146
(is (goog/isObject (clj->js {})))
146-
(is (= (aget (clj->js {:a 1}) "a") 1))
147+
(is (= (gobject/get (clj->js {:a 1}) "a") 1))
147148
(is (= (-> (clj->js {:a {:b {{:k :ey} :d}}})
148-
(aget "a")
149-
(aget "b")
150-
(aget "{:k :ey}"))
149+
(gobject/get "a")
150+
(gobject/get "b")
151+
(gobject/get "{:k :ey}"))
151152
"d")))))
152153

153154
(deftest test-delay
@@ -544,6 +545,11 @@
544545
(is (= 0 (loop [x 0] (cond-> x false recur))))
545546
(is (= 0 (loop [x 0] (cond->> x false recur)))))
546547

548+
(deftest unsafe-get-test
549+
(is (= 1 (unsafe-get #js {:a 1} "a")))
550+
(is (nil? (unsafe-get #js {:a 1} "b")))
551+
(is (nil? (unsafe-get #js {:a 1} nil))))
552+
547553
;; =============================================================================
548554
;; Tickets
549555

src/test/cljs/cljs/hashing_test.cljs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
(:refer-clojure :exclude [iter])
1111
(:require [cljs.test :refer-macros [deftest testing is]]
1212
[clojure.string :as s]
13-
[clojure.set :as set]))
13+
[clojure.set :as set]
14+
[goog.object :as gobject]))
1415

1516
(deftest test-hash-null
16-
(is (zero? (hash (aget (js-obj) "foo")))))
17+
(is (zero? (hash (gobject/get (js-obj) "foo")))))
1718

1819
;; hashing bug in many JS runtimes CLJ-118
1920
(deftest test-clj-118

0 commit comments

Comments
 (0)