|
1365 | 1365 | (merge
|
1366 | 1366 | {:env env
|
1367 | 1367 | :op :the-var
|
| 1368 | + :children [:var :sym :meta] |
1368 | 1369 | :form form}
|
1369 | 1370 | (var-ast env sym)))
|
1370 | 1371 |
|
|
1380 | 1381 | {:env env :op :if :form form
|
1381 | 1382 | :test test-expr :then then-expr :else else-expr
|
1382 | 1383 | :unchecked *unchecked-if*
|
1383 |
| - :children [test-expr then-expr else-expr]})) |
| 1384 | + :children [:test :then :else]})) |
1384 | 1385 |
|
1385 | 1386 | (defmethod parse 'case*
|
1386 | 1387 | [op env [_ sym tests thens default :as form] name _]
|
|
1399 | 1400 | :form (:form test)
|
1400 | 1401 | :env expr-env
|
1401 | 1402 | :test test
|
1402 |
| - :children [test]}) |
| 1403 | + :children [:test]}) |
1403 | 1404 | tests)
|
1404 | 1405 | :then {:op :case-then
|
1405 | 1406 | :form (:form then)
|
1406 | 1407 | :env env
|
1407 | 1408 | :then then
|
1408 |
| - :children [then]} |
1409 |
| - :children (conj tests then)}) |
| 1409 | + :children [:then]} |
| 1410 | + :children [:tests :then]}) |
1410 | 1411 | tests
|
1411 | 1412 | thens)
|
1412 | 1413 | default (analyze env default)]
|
|
1419 | 1420 | "case* tests must be numbers, strings, or constants")
|
1420 | 1421 | {:env env :op :case :form form
|
1421 | 1422 | :test v :nodes nodes :default default
|
1422 |
| - :children (vec (concat [v] nodes [default]))})) |
| 1423 | + :children [:test :nodes :default]})) |
1423 | 1424 |
|
1424 | 1425 | (defmethod parse 'throw
|
1425 | 1426 | [op env [_ throw-form :as form] name _]
|
|
1433 | 1434 | (let [throw-expr (disallowing-recur (analyze (assoc env :context :expr) throw-form))]
|
1434 | 1435 | {:env env :op :throw :form form
|
1435 | 1436 | :exception throw-expr
|
1436 |
| - :children [throw-expr]})) |
| 1437 | + :children [:exception]})) |
1437 | 1438 |
|
1438 | 1439 | (defmethod parse 'try
|
1439 | 1440 | [op env [_ & body :as form] name _]
|
|
1494 | 1495 | :finally finally
|
1495 | 1496 | :name e
|
1496 | 1497 | :catch catch
|
1497 |
| - :children [try catch finally]})) |
| 1498 | + :children (vec |
| 1499 | + (concat [:body] |
| 1500 | + (when catch |
| 1501 | + [:catch]) |
| 1502 | + (when finally |
| 1503 | + [:finally])))})) |
1498 | 1504 |
|
1499 | 1505 | (defn valid-proto [x]
|
1500 | 1506 | (when (symbol? x) x))
|
|
1506 | 1512 | (fn [env ast opts]
|
1507 | 1513 | (assoc ast :env new-env)))
|
1508 | 1514 |
|
| 1515 | +(defn ast-children [ast] |
| 1516 | + (mapcat (fn [c] |
| 1517 | + (let [g (get ast c)] |
| 1518 | + (cond |
| 1519 | + (vector? g) g |
| 1520 | + g [g]))) |
| 1521 | + (:children ast))) |
| 1522 | + |
1509 | 1523 | (defn constant-value?
|
1510 | 1524 | [{:keys [op] :as ast}]
|
1511 | 1525 | (or (= :const op)
|
1512 | 1526 | (and (#{:map :set :vector :list} op)
|
1513 |
| - (every? constant-value? (:children ast))))) |
| 1527 | + (every? constant-value? (ast-children ast))))) |
1514 | 1528 |
|
1515 | 1529 | (defmethod parse 'def
|
1516 | 1530 | [op env form _ _]
|
|
1673 | 1687 | sym)
|
1674 | 1688 | :op :var)
|
1675 | 1689 | :doc doc
|
1676 |
| - :jsdoc (:jsdoc sym-meta) |
1677 |
| - :init init-expr} |
| 1690 | + :jsdoc (:jsdoc sym-meta)} |
1678 | 1691 | (when (true? (:def-emits-var env))
|
1679 | 1692 | {:var-ast (var-ast env sym)})
|
1680 | 1693 | (when-some [test (:test sym-meta)]
|
|
1685 | 1698 | {:tag tag}))
|
1686 | 1699 | (when (true? dynamic) {:dynamic true})
|
1687 | 1700 | (when (some? export-as) {:export export-as})
|
1688 |
| - (when (some? init-expr) {:children [init-expr]}))))) |
| 1701 | + (if (some? init-expr) |
| 1702 | + {:init init-expr |
| 1703 | + :children [:var :init]} |
| 1704 | + {:children [:var]}))))) |
1689 | 1705 |
|
1690 | 1706 | (defn analyze-fn-method-param [env]
|
1691 | 1707 | (fn [[locals params] name]
|
|
1738 | 1754 | expr (when analyze-body?
|
1739 | 1755 | (analyze-fn-method-body body-env body-form recur-frames))
|
1740 | 1756 | recurs @(:flag recur-frame)]
|
1741 |
| - {:env env |
1742 |
| - :op :fn-method |
1743 |
| - :variadic? variadic |
1744 |
| - :params params |
1745 |
| - :fixed-arity fixed-arity |
1746 |
| - :type type |
1747 |
| - :form form |
1748 |
| - :body expr |
1749 |
| - :recurs recurs})) |
| 1757 | + (merge |
| 1758 | + {:env env |
| 1759 | + :op :fn-method |
| 1760 | + :variadic? variadic |
| 1761 | + :params params |
| 1762 | + :fixed-arity fixed-arity |
| 1763 | + :type type |
| 1764 | + :form form |
| 1765 | + :recurs recurs} |
| 1766 | + (if (some? expr) |
| 1767 | + {:body expr |
| 1768 | + :children [:params :body]} |
| 1769 | + {:children [:params]})))) |
1750 | 1770 |
|
1751 | 1771 | (declare analyze-wrap-meta)
|
1752 | 1772 |
|
|
1768 | 1788 | (merge name-var ret-tag))))
|
1769 | 1789 |
|
1770 | 1790 | (defn analyze-fn-methods-pass2* [menv locals type meths]
|
1771 |
| - (doall (map #(analyze-fn-method menv locals % type true) meths))) |
| 1791 | + (mapv #(analyze-fn-method menv locals % type true) meths)) |
1772 | 1792 |
|
1773 | 1793 | (defn analyze-fn-methods-pass2 [menv locals type meths]
|
1774 | 1794 | (analyze-fn-methods-pass2* menv locals type meths))
|
|
1817 | 1837 | ;; a second pass with knowledge of our function-ness/arity
|
1818 | 1838 | ;; lets us optimize self calls
|
1819 | 1839 | (disallowing-ns* (analyze-fn-methods-pass2 menv locals type meths))
|
1820 |
| - methods) |
| 1840 | + (vec methods)) |
1821 | 1841 | form (vary-meta form dissoc ::protocol-impl ::protocol-inline ::type)
|
1822 | 1842 | js-doc (when (true? variadic)
|
1823 | 1843 | "@param {...*} var_args")
|
1824 |
| - children (mapv :body methods) |
1825 |
| - ast {:op :fn |
| 1844 | + children (if (some? name-var) |
| 1845 | + [:local :methods] |
| 1846 | + [:methods]) |
| 1847 | + ast (merge {:op :fn |
1826 | 1848 | :env env
|
1827 | 1849 | :form form
|
1828 | 1850 | :name name-var
|
|
1835 | 1857 | :max-fixed-arity mfa
|
1836 | 1858 | :protocol-impl proto-impl
|
1837 | 1859 | :protocol-inline proto-inline
|
1838 |
| - :children children}] |
| 1860 | + :children children} |
| 1861 | + (when (some? name-var) |
| 1862 | + {:local name-var}))] |
1839 | 1863 | (let [variadic-methods (filter :variadic? methods)
|
1840 | 1864 | variadic-params (count (:params (first variadic-methods)))
|
1841 | 1865 | param-counts (map (comp count :params) methods)]
|
|
1889 | 1913 | [meth-env []] bes)
|
1890 | 1914 | expr (analyze (assoc meth-env :context (if (= :expr context) :return context)) `(do ~@exprs))]
|
1891 | 1915 | {:env env :op :letfn :bindings bes :body expr :form form
|
1892 |
| - :children (conj (vec (map :init bes)) expr)})) |
| 1916 | + :children [:bindings :body]})) |
1893 | 1917 |
|
1894 | 1918 | (defn analyze-do-statements* [env exprs]
|
1895 |
| - (seq (doall (map #(analyze (assoc env :context :statement) %) (butlast exprs))))) |
| 1919 | + (mapv #(analyze (assoc env :context :statement) %) (butlast exprs))) |
1896 | 1920 |
|
1897 | 1921 | (defn analyze-do-statements [env exprs]
|
1898 | 1922 | (disallowing-recur (analyze-do-statements* env exprs)))
|
|
1902 | 1926 | (let [statements (analyze-do-statements env exprs)]
|
1903 | 1927 | (if (<= (count exprs) 1)
|
1904 | 1928 | (let [ret (analyze env (first exprs))
|
1905 |
| - children (conj (vec statements) ret)] |
| 1929 | + children [:statements :ret]] |
1906 | 1930 | {:op :do
|
1907 | 1931 | :env env
|
1908 | 1932 | :form form
|
|
1912 | 1936 | (assoc env :context :statement)
|
1913 | 1937 | (assoc env :context :return))
|
1914 | 1938 | ret (analyze ret-env (last exprs))
|
1915 |
| - children (conj (vec statements) ret)] |
| 1939 | + children [:statements :ret]] |
1916 | 1940 | {:op :do
|
1917 | 1941 | :env env
|
1918 | 1942 | :form form
|
|
1999 | 2023 | (some? *loop-lets*) (cons {:params bes} *loop-lets*))
|
2000 | 2024 | expr (analyze-let-body env context exprs recur-frames loop-lets)
|
2001 | 2025 | op (if (true? is-loop) :loop :let)
|
2002 |
| - children (conj (vec (map :init bes)) expr)] |
| 2026 | + children [:bindings :body]] |
2003 | 2027 | {:op op
|
2004 | 2028 | :env encl-env
|
2005 | 2029 | :bindings bes
|
|
2036 | 2060 | (assoc {:env env :op :recur :form form}
|
2037 | 2061 | :frame frame
|
2038 | 2062 | :exprs exprs
|
2039 |
| - :children exprs))) |
| 2063 | + :children [:exprs]))) |
2040 | 2064 |
|
2041 | 2065 | (defmethod parse 'quote
|
2042 | 2066 | [_ env [_ x] _ _]
|
|
2058 | 2082 | (when (and (not (-> ctor meta :internal-ctor))
|
2059 | 2083 | (some? known-num-fields) (not= known-num-fields argc))
|
2060 | 2084 | (warning :fn-arity env {:argc argc :ctor ctor}))
|
2061 |
| - {:env env :op :new :form form :ctor ctorexpr :args argexprs |
2062 |
| - :children (into [ctorexpr] argexprs) |
| 2085 | + {:env env :op :new :form form :class ctorexpr :args argexprs |
| 2086 | + :children [:class :args] |
2063 | 2087 | :tag (let [name (-> ctorexpr :info :name)]
|
2064 | 2088 | (or ('{js/Object object
|
2065 | 2089 | js/String string
|
|
2118 | 2142 |
|
2119 | 2143 | :else
|
2120 | 2144 | {:env env :op :set! :form form :target texpr :val vexpr
|
2121 |
| - :children [texpr vexpr]}))))) |
| 2145 | + :children [:target :val]}))))) |
2122 | 2146 |
|
2123 | 2147 | #?(:clj (declare analyze-file))
|
2124 | 2148 |
|
|
2862 | 2886 | {:op op :env env :form form :t t :fields fields :pmasks pmasks
|
2863 | 2887 | :tag 'function
|
2864 | 2888 | :protocols (disj protocols 'cljs.core/Object)
|
| 2889 | + :children [#_:fields :body] |
2865 | 2890 | :body (analyze (assoc env :locals locals) body)}))
|
2866 | 2891 |
|
2867 | 2892 | (defmethod parse 'deftype*
|
|
2977 | 3002 | (swap! env/*compiler* update-in
|
2978 | 3003 | (into [::namespaces (-> env :ns :name) :externs] pre) merge {}))))
|
2979 | 3004 | (case dot-action
|
2980 |
| - ::access (let [children [targetexpr]] |
| 3005 | + ::access (let [children [:target]] |
2981 | 3006 | {:op :host-field
|
2982 | 3007 | :env env
|
2983 | 3008 | :form form
|
|
2987 | 3012 | :tag (if (js-tag? tag)
|
2988 | 3013 | (or (js-tag (-> tag meta :prefix) :tag) tag)
|
2989 | 3014 | tag)})
|
2990 |
| - ::call (let [argexprs (map #(analyze enve %) args) |
2991 |
| - children (into [targetexpr] argexprs)] |
| 3015 | + ::call (let [argexprs (mapv #(analyze enve %) args) |
| 3016 | + children [:target :args]] |
2992 | 3017 | {:op :host-call
|
2993 | 3018 | :env env
|
2994 | 3019 | :form form
|
|
3103 | 3128 | :args argexprs
|
3104 | 3129 | :tag tag
|
3105 | 3130 | :form form
|
3106 |
| - :children argexprs |
| 3131 | + :children [:args] |
3107 | 3132 | :js-op js-op
|
3108 | 3133 | :numeric numeric}))
|
3109 | 3134 |
|
|
3206 | 3231 | (~(analyzed (if bind-f-expr? f-sym f))
|
3207 | 3232 | ~@(if bind-args? arg-syms args)))))
|
3208 | 3233 | (let [ana-expr #(analyze enve %)
|
3209 |
| - argexprs (map ana-expr args)] |
3210 |
| - {:env env :op :invoke :form form :fn fexpr :args (vec argexprs) |
3211 |
| - :children (into [fexpr] argexprs)})))) |
| 3234 | + argexprs (mapv ana-expr args)] |
| 3235 | + {:env env :op :invoke :form form :fn fexpr :args argexprs |
| 3236 | + :children [:fn :args]})))) |
3212 | 3237 |
|
3213 | 3238 | (defn parse-invoke
|
3214 | 3239 | [env form]
|
|
3434 | 3459 | (defn analyze-map
|
3435 | 3460 | [env form]
|
3436 | 3461 | (let [expr-env (assoc env :context :expr)
|
3437 |
| - ks (disallowing-recur (vec (map #(analyze expr-env %) (keys form)))) |
3438 |
| - vs (disallowing-recur (vec (map #(analyze expr-env %) (vals form))))] |
| 3462 | + ks (disallowing-recur (mapv #(analyze expr-env %) (keys form))) |
| 3463 | + vs (disallowing-recur (mapv #(analyze expr-env %) (vals form)))] |
3439 | 3464 | (analyze-wrap-meta {:op :map :env env :form form
|
3440 | 3465 | :keys ks :vals vs
|
3441 |
| - :children (vec (interleave ks vs)) |
| 3466 | + :children [:keys :vals] |
3442 | 3467 | :tag 'cljs.core/IMap})))
|
3443 | 3468 |
|
3444 | 3469 | (defn analyze-list
|
3445 | 3470 | [env form]
|
3446 | 3471 | (let [expr-env (assoc env :context :expr)
|
3447 |
| - items (disallowing-recur (doall (map #(analyze expr-env %) form)))] |
3448 |
| - (analyze-wrap-meta {:op :list :env env :form form :items items :children items :tag 'cljs.core/IList}))) |
| 3472 | + items (disallowing-recur (mapv #(analyze expr-env %) form))] |
| 3473 | + (analyze-wrap-meta {:op :list :env env :form form :items items :children [:items] :tag 'cljs.core/IList}))) |
3449 | 3474 |
|
3450 | 3475 | (defn analyze-vector
|
3451 | 3476 | [env form]
|
3452 | 3477 | (let [expr-env (assoc env :context :expr)
|
3453 |
| - items (disallowing-recur (vec (map #(analyze expr-env %) form)))] |
3454 |
| - (analyze-wrap-meta {:op :vector :env env :form form :items items :children items :tag 'cljs.core/IVector}))) |
| 3478 | + items (disallowing-recur (mapv #(analyze expr-env %) form))] |
| 3479 | + (analyze-wrap-meta {:op :vector :env env :form form :items items :children [:items] :tag 'cljs.core/IVector}))) |
3455 | 3480 |
|
3456 | 3481 | (defn analyze-set
|
3457 | 3482 | [env form ]
|
3458 | 3483 | (let [expr-env (assoc env :context :expr)
|
3459 |
| - items (disallowing-recur (vec (map #(analyze expr-env %) form)))] |
3460 |
| - (analyze-wrap-meta {:op :set :env env :form form :items items :children items :tag 'cljs.core/ISet}))) |
| 3484 | + items (disallowing-recur (mapv #(analyze expr-env %) form))] |
| 3485 | + (analyze-wrap-meta {:op :set :env env :form form :items items :children [:items] :tag 'cljs.core/ISet}))) |
3461 | 3486 |
|
3462 | 3487 | (defn analyze-js-value
|
3463 | 3488 | [env ^JSValue form]
|
|
3472 | 3497 | :form form
|
3473 | 3498 | :keys keys
|
3474 | 3499 | :vals vals
|
3475 |
| - :children vals |
| 3500 | + :children [:vals] |
3476 | 3501 | :tag 'object})
|
3477 | 3502 | (let [items (disallowing-recur
|
3478 | 3503 | (mapv #(analyze expr-env %) val))]
|
3479 | 3504 | {:op :js-array
|
3480 | 3505 | :env env
|
3481 | 3506 | :form form
|
3482 | 3507 | :items items
|
3483 |
| - :children items |
| 3508 | + :children [:items] |
3484 | 3509 | :tag 'array}))))
|
3485 | 3510 |
|
3486 | 3511 | (defn analyze-record
|
|
3499 | 3524 | :env env
|
3500 | 3525 | :form x
|
3501 | 3526 | :items items
|
3502 |
| - :children [items] |
| 3527 | + :children [:items] |
3503 | 3528 | :tag (symbol (str ns) (str name))}))
|
3504 | 3529 |
|
3505 | 3530 | (defn elide-reader-meta [m]
|
|
3516 | 3541 | expr (assoc-in expr [:env :context] :expr) ; change expr to :expr
|
3517 | 3542 | meta-expr (analyze-map (:env expr) m)]
|
3518 | 3543 | {:op :with-meta :env env :form form
|
3519 |
| - :meta meta-expr :expr expr :children [meta-expr expr]}) |
| 3544 | + :meta meta-expr :expr expr :children [:meta :expr]}) |
3520 | 3545 | expr)))
|
3521 | 3546 |
|
3522 | 3547 | (defn infer-type [env ast _]
|
|
3662 | 3687 | (one of :statement, :expr, :return), :ns (a symbol naming the
|
3663 | 3688 | compilation ns)}, and form, returns an expression object (a map
|
3664 | 3689 | containing at least :form, :op and :env keys). If expr has any (immediately)
|
3665 |
| - nested exprs, must have :children [exprs...] entry. This will |
| 3690 | + nested exprs, must have a :children entry. This must be a vector of keywords naming |
| 3691 | + the immediately nested fields mapped to an expr or vector of exprs. This will |
3666 | 3692 | facilitate code walking without knowing the details of the op set."
|
3667 | 3693 | ([env form] (analyze env form nil))
|
3668 | 3694 | ([env form name]
|
|
0 commit comments