Skip to content

Commit 6c8e69c

Browse files
frenchy64swannodette
authored andcommitted
CLJS-2797: Prepare :method, :dot, :js-value, and :case* for tools.analyzer AST conversion
rename :method op to :fn-method rename :expr entry to :body in :fn-method op rename :max-fixed-arity to :fixed-arity in :fn-method op rename :variadic to :variadic? in :fn-method op split :dot op into :host-field/:host-call split :js-value op into :js-object/:js-array rename :case* op to :case rename :v to :test in :case op add :case-node grouping with :case-{test,then} in :case op
1 parent e43c6f7 commit 6c8e69c

File tree

3 files changed

+103
-64
lines changed

3 files changed

+103
-64
lines changed

src/main/clojure/cljs/analyzer.cljc

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,8 +1224,8 @@
12241224
c (count params)]
12251225
(some
12261226
(fn [m]
1227-
(and (or (== (:max-fixed-arity m) c)
1228-
(:variadic m))
1227+
(and (or (== (:fixed-arity m) c)
1228+
(:variadic? m))
12291229
m))
12301230
methods)))
12311231

@@ -1289,7 +1289,7 @@
12891289
(when (= 'js (:ns info)) 'js))]
12901290
ret-tag
12911291
(let [args (:args e)
1292-
me (assoc (find-matching-method f args) :op :method)]
1292+
me (assoc (find-matching-method f args) :op :fn-method)]
12931293
(if-some [ret-tag (infer-tag env me)]
12941294
ret-tag
12951295
ANY_SYM)))))
@@ -1306,7 +1306,7 @@
13061306
:let (infer-tag env (:body e))
13071307
:loop (infer-tag env (:body e))
13081308
:do (infer-tag env (:ret e))
1309-
:method (infer-tag env (:expr e))
1309+
:fn-method (infer-tag env (:body e))
13101310
:def (infer-tag env (:init e))
13111311
:invoke (infer-invoke env e)
13121312
:if (infer-if env e)
@@ -1317,7 +1317,7 @@
13171317
:var (if-some [init (:init e)]
13181318
(infer-tag env init)
13191319
(infer-tag env (:info e)))
1320-
:dot ANY_SYM
1320+
(:host-field :host-call) ANY_SYM
13211321
:js ANY_SYM
13221322
nil)))
13231323

@@ -1390,6 +1390,25 @@
13901390
v (disallowing-recur (analyze expr-env sym))
13911391
tests (mapv #(mapv (fn [t] (analyze expr-env t)) %) tests)
13921392
thens (mapv #(analyze env %) thens)
1393+
nodes (mapv (fn [tests then]
1394+
{:op :case-node
1395+
;synthetic node, no :form
1396+
:env env
1397+
:tests (mapv (fn [test]
1398+
{:op :case-test
1399+
:form (:form test)
1400+
:env expr-env
1401+
:test test
1402+
:children [test]})
1403+
tests)
1404+
:then {:op :case-then
1405+
:form (:form then)
1406+
:env env
1407+
:then then
1408+
:children [then]}
1409+
:children (conj tests then)})
1410+
tests
1411+
thens)
13931412
default (analyze env default)]
13941413
(assert (every? (fn [t]
13951414
(or
@@ -1398,9 +1417,9 @@
13981417
((some-fn number? string? char?) (:form t)))))
13991418
(apply concat tests))
14001419
"case* tests must be numbers, strings, or constants")
1401-
{:env env :op :case* :form form
1402-
:v v :tests tests :thens thens :default default
1403-
:children (vec (concat [v] tests thens (if default [default])))}))
1420+
{:env env :op :case :form form
1421+
:test v :nodes nodes :default default
1422+
:children (vec (concat [v] nodes [default]))}))
14041423

14051424
(defmethod parse 'throw
14061425
[op env [_ throw-form :as form] name _]
@@ -1627,7 +1646,7 @@
16271646
:protocol-inline (:protocol-inline init-expr)}
16281647
(if-some [top-fn-meta (:top-fn sym-meta)]
16291648
top-fn-meta
1630-
{:variadic (:variadic init-expr)
1649+
{:variadic? (:variadic? init-expr)
16311650
:max-fixed-arity (:max-fixed-arity init-expr)
16321651
:method-params params
16331652
:arglists (:arglists sym-meta)
@@ -1720,12 +1739,13 @@
17201739
(analyze-fn-method-body body-env body-form recur-frames))
17211740
recurs @(:flag recur-frame)]
17221741
{:env env
1723-
:variadic variadic
1742+
:op :fn-method
1743+
:variadic? variadic
17241744
:params params
1725-
:max-fixed-arity fixed-arity
1745+
:fixed-arity fixed-arity
17261746
:type type
17271747
:form form
1728-
:expr expr
1748+
:body expr
17291749
:recurs recurs}))
17301750

17311751
(declare analyze-wrap-meta)
@@ -1783,13 +1803,13 @@
17831803
{:protocol-impl proto-impl
17841804
:protocol-inline proto-inline})
17851805
methods (map #(disallowing-ns* (analyze-fn-method menv locals % type (nil? name))) meths)
1786-
mfa (apply max (map :max-fixed-arity methods))
1787-
variadic (boolean (some :variadic methods))
1806+
mfa (apply max (map :fixed-arity methods))
1807+
variadic (boolean (some :variadic? methods))
17881808
locals (if named-fn?
17891809
(update-in locals [name] assoc
17901810
;; TODO: can we simplify? - David
17911811
:fn-var true
1792-
:variadic variadic
1812+
:variadic? variadic
17931813
:max-fixed-arity mfa
17941814
:method-params (map :params methods))
17951815
locals)
@@ -1801,13 +1821,13 @@
18011821
form (vary-meta form dissoc ::protocol-impl ::protocol-inline ::type)
18021822
js-doc (when (true? variadic)
18031823
"@param {...*} var_args")
1804-
children (mapv :expr methods)
1824+
children (mapv :body methods)
18051825
ast {:op :fn
18061826
:env env
18071827
:form form
18081828
:name name-var
18091829
:methods methods
1810-
:variadic variadic
1830+
:variadic? variadic
18111831
:tag 'function
18121832
:recur-frames *recur-frames*
18131833
:loop-lets *loop-lets*
@@ -1816,7 +1836,7 @@
18161836
:protocol-impl proto-impl
18171837
:protocol-inline proto-inline
18181838
:children children}]
1819-
(let [variadic-methods (filter :variadic methods)
1839+
(let [variadic-methods (filter :variadic? methods)
18201840
variadic-params (count (:params (first variadic-methods)))
18211841
param-counts (map (comp count :params) methods)]
18221842
(when (< 1 (count variadic-methods))
@@ -1846,7 +1866,7 @@
18461866
:column (get-col n env)
18471867
:local true
18481868
:shadow (locals n)
1849-
:variadic (:variadic fexpr)
1869+
:variadic? (:variadic? fexpr)
18501870
:max-fixed-arity (:max-fixed-arity fexpr)
18511871
:method-params (map :params (:methods fexpr))}
18521872
ret-tag (assoc :ret-tag ret-tag))]
@@ -1861,7 +1881,7 @@
18611881
fexpr (analyze env (n->fexpr name))
18621882
be' (assoc be
18631883
:init fexpr
1864-
:variadic (:variadic fexpr)
1884+
:variadic? (:variadic? fexpr)
18651885
:max-fixed-arity (:max-fixed-arity fexpr)
18661886
:method-params (map :params (:methods fexpr)))]
18671887
[(assoc-in env [:locals name] be')
@@ -1943,7 +1963,7 @@
19431963
;; TODO: can we simplify - David
19441964
(merge be
19451965
{:fn-var true
1946-
:variadic (:variadic init-expr)
1966+
:variadic? (:variadic? init-expr)
19471967
:max-fixed-arity (:max-fixed-arity init-expr)
19481968
:method-params (map :params (:methods init-expr))})
19491969
be)]
@@ -2958,7 +2978,7 @@
29582978
(into [::namespaces (-> env :ns :name) :externs] pre) merge {}))))
29592979
(case dot-action
29602980
::access (let [children [targetexpr]]
2961-
{:op :dot
2981+
{:op :host-field
29622982
:env env
29632983
:form form
29642984
:target targetexpr
@@ -2969,7 +2989,7 @@
29692989
tag)})
29702990
::call (let [argexprs (map #(analyze enve %) args)
29712991
children (into [targetexpr] argexprs)]
2972-
{:op :dot
2992+
{:op :host-call
29732993
:env env
29742994
:form form
29752995
:target targetexpr
@@ -3155,7 +3175,7 @@
31553175
bind-args? (and HO-invoke?
31563176
(not (all-values? args)))]
31573177
(when ^boolean fn-var?
3158-
(let [{:keys [^boolean variadic max-fixed-arity method-params name ns macro]} (:info fexpr)]
3178+
(let [{^boolean variadic :variadic? :keys [max-fixed-arity method-params name ns macro]} (:info fexpr)]
31593179
;; don't warn about invalid arity when when compiling a macros namespace
31603180
;; that requires itself, as that code is not meant to be executed in the
31613181
;; `$macros` ns - António Monteiro
@@ -3442,18 +3462,26 @@
34423462
(defn analyze-js-value
34433463
[env ^JSValue form]
34443464
(let [val (.-val form)
3445-
expr-env (assoc env :context :expr)
3446-
items (if (map? val)
3447-
(zipmap (keys val)
3448-
(disallowing-recur (doall (map #(analyze expr-env %) (vals val)))))
3449-
(disallowing-recur (doall (map #(analyze expr-env %) val))))]
3450-
{:op :js-value
3451-
:js-type (if (map? val) :object :array)
3452-
:env env
3453-
:form form
3454-
:items items
3455-
:children items
3456-
:tag (if (map? val) 'object 'array)}))
3465+
expr-env (assoc env :context :expr)]
3466+
(if (map? val)
3467+
(let [keys (vec (keys val))
3468+
vals (disallowing-recur
3469+
(mapv #(analyze expr-env %) (vals val)))]
3470+
{:op :js-object
3471+
:env env
3472+
:form form
3473+
:keys keys
3474+
:vals vals
3475+
:children vals
3476+
:tag 'object})
3477+
(let [items (disallowing-recur
3478+
(mapv #(analyze expr-env %) val))]
3479+
{:op :js-array
3480+
:env env
3481+
:form form
3482+
:items items
3483+
:children items
3484+
:tag 'array}))))
34573485

34583486
(defn analyze-record
34593487
[env x]

src/main/clojure/cljs/compiler.cljc

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -475,19 +475,27 @@
475475

476476
:else (emits "cljs.core.PersistentHashSet.createAsIfByAssoc([" (comma-sep items) "])"))))
477477

478-
(defmethod emit* :js-value
479-
[{:keys [items js-type env]}]
478+
(defn emit-js-object [items]
479+
(emits "({")
480+
(when-let [items (seq items)]
481+
(let [[[k v] & r] items]
482+
(emits "\"" (name k) "\": " v)
483+
(doseq [[k v] r]
484+
(emits ", \"" (name k) "\": " v))))
485+
(emits "})"))
486+
487+
(defn emit-js-array [items]
488+
(emits "[" (comma-sep items) "]"))
489+
490+
(defmethod emit* :js-object
491+
[{:keys [keys vals env]}]
480492
(emit-wrap env
481-
(if (= js-type :object)
482-
(do
483-
(emits "({")
484-
(when-let [items (seq items)]
485-
(let [[[k v] & r] items]
486-
(emits "\"" (name k) "\": " v)
487-
(doseq [[k v] r]
488-
(emits ", \"" (name k) "\": " v))))
489-
(emits "})"))
490-
(emits "[" (comma-sep items) "]"))))
493+
(emit-js-object (map vector keys vals))))
494+
495+
(defmethod emit* :js-array
496+
[{:keys [items env]}]
497+
(emit-wrap env
498+
(emit-js-array items)))
491499

492500
(defmethod emit* :record-value
493501
[{:keys [items ns name items env]}]
@@ -534,16 +542,16 @@
534542
(emitln then "} else {")
535543
(emitln else "}"))))))
536544

537-
(defmethod emit* :case*
538-
[{:keys [v tests thens default env]}]
545+
(defmethod emit* :case
546+
[{v :test :keys [nodes default env]}]
539547
(when (= (:context env) :expr)
540548
(emitln "(function(){"))
541549
(let [gs (gensym "caseval__")]
542550
(when (= :expr (:context env))
543551
(emitln "var " gs ";"))
544552
(emitln "switch (" v ") {")
545-
(doseq [[ts then] (partition 2 (interleave tests thens))]
546-
(doseq [test ts]
553+
(doseq [{ts :tests {:keys [then]} :then} nodes]
554+
(doseq [test (map :test ts)]
547555
(emitln "case " test ":"))
548556
(if (= :expr (:context env))
549557
(emitln gs "=" then)
@@ -765,7 +773,7 @@
765773
(emits ","))))
766774

767775
(defn emit-fn-method
768-
[{:keys [type name variadic params expr env recurs max-fixed-arity]}]
776+
[{expr :body :keys [type name params env recurs]}]
769777
(emit-wrap env
770778
(emits "(function " (munge name) "(")
771779
(emit-fn-params params)
@@ -794,7 +802,7 @@
794802
a))
795803

796804
(defn emit-variadic-fn-method
797-
[{:keys [type name variadic params expr env recurs max-fixed-arity] :as f}]
805+
[{expr :body max-fixed-arity :fixed-arity variadic :variadic? :keys [type name params env recurs] :as f}]
798806
(emit-wrap env
799807
(let [name (or name (gensym))
800808
mname (munge name)
@@ -844,7 +852,7 @@
844852
(emitln "})()"))))
845853

846854
(defmethod emit* :fn
847-
[{:keys [name env methods max-fixed-arity variadic recur-frames loop-lets]}]
855+
[{variadic :variadic? :keys [name env methods max-fixed-arity recur-frames loop-lets]}]
848856
;;fn statements get erased, serve no purpose and can pollute scope if named
849857
(when-not (= :statement (:context env))
850858
(let [loop-locals (->> (concat (mapcat :params (filter #(and % @(:flag %)) recur-frames))
@@ -876,7 +884,7 @@
876884
(emitln "var " mname " = null;")
877885
(doseq [[n meth] ms]
878886
(emits "var " n " = ")
879-
(if (:variadic meth)
887+
(if (:variadic? meth)
880888
(emit-variadic-fn-method meth)
881889
(emit-fn-method meth))
882890
(emitln ";"))
@@ -889,7 +897,7 @@
889897
(emitln " = var_args;"))
890898
(emitln "switch(arguments.length){")
891899
(doseq [[n meth] ms]
892-
(if (:variadic meth)
900+
(if (:variadic? meth)
893901
(do (emitln "default:")
894902
(let [restarg (munge (gensym))]
895903
(emitln "var " restarg " = null;")
@@ -913,10 +921,10 @@
913921
(emitln "};")
914922
(when variadic
915923
(emitln mname ".cljs$lang$maxFixedArity = " max-fixed-arity ";")
916-
(emitln mname ".cljs$lang$applyTo = " (some #(let [[n m] %] (when (:variadic m) n)) ms) ".cljs$lang$applyTo;"))
924+
(emitln mname ".cljs$lang$applyTo = " (some #(let [[n m] %] (when (:variadic? m) n)) ms) ".cljs$lang$applyTo;"))
917925
(doseq [[n meth] ms]
918926
(let [c (count (:params meth))]
919-
(if (:variadic meth)
927+
(if (:variadic? meth)
920928
(emitln mname ".cljs$core$IFn$_invoke$arity$variadic = " n ".cljs$core$IFn$_invoke$arity$variadic;")
921929
(emitln mname ".cljs$core$IFn$_invoke$arity$" c " = " n ";"))))
922930
(emitln "return " mname ";")
@@ -1039,7 +1047,7 @@
10391047
[f variadic-invoke]
10401048
(if fn?
10411049
(let [arity (count args)
1042-
variadic? (:variadic info)
1050+
variadic? (:variadic? info)
10431051
mps (:method-params info)
10441052
mfa (:max-fixed-arity info)]
10451053
(cond
@@ -1234,7 +1242,7 @@
12341242
(emitln "});")
12351243
(emit body)))
12361244

1237-
(defmethod emit* :dot
1245+
(defn emit-dot
12381246
[{:keys [target field method args env]}]
12391247
(emit-wrap env
12401248
(if field
@@ -1243,6 +1251,9 @@
12431251
(comma-sep args)
12441252
")"))))
12451253

1254+
(defmethod emit* :host-field [ast] (emit-dot ast))
1255+
(defmethod emit* :host-call [ast] (emit-dot ast))
1256+
12461257
(defmethod emit* :js
12471258
[{:keys [op env code segs args]}]
12481259
(if (and code #?(:clj (.startsWith ^String (string/trim code) "/*")

0 commit comments

Comments
 (0)