|
11 | 11 | [cljs.analyzer :as ana]
|
12 | 12 | [cljs.analyzer.api :as ana-api]
|
13 | 13 | [cljs.compiler :as comp]
|
14 |
| - [cljs.closure :as closure] |
15 | 14 | [cljs.env :as env]
|
16 |
| - [cljs.externs :as externs] |
17 | 15 | [cljs.test-util :refer [unsplit-lines]]
|
18 | 16 | [cljs.util :as util]
|
19 | 17 | [clojure.java.io :as io]
|
|
1493 | 1491 | (.getMessage (.getCause e))))
|
1494 | 1492 | "Argument to var must be symbol")))
|
1495 | 1493 |
|
1496 |
| -(deftest test-has-extern?-basic |
1497 |
| - (let [externs (externs/externs-map |
1498 |
| - (closure/load-externs |
1499 |
| - {:externs ["src/test/externs/test.js"] |
1500 |
| - :use-only-custom-externs true}))] |
1501 |
| - (is (true? (ana/has-extern? '[Foo] externs))) |
1502 |
| - (is (true? (ana/has-extern? '[Foo wozMethod] externs))) |
1503 |
| - (is (false? (ana/has-extern? '[foo] externs))) |
1504 |
| - (is (false? (ana/has-extern? '[Foo gozMethod] externs))) |
1505 |
| - (is (true? (ana/has-extern? '[baz] externs))) |
1506 |
| - (is (false? (ana/has-extern? '[Baz] externs))))) |
1507 |
| - |
1508 |
| -(deftest test-has-extern?-defaults |
1509 |
| - (let [externs (externs/externs-map)] |
1510 |
| - (is (true? (ana/has-extern? '[console] externs))) |
1511 |
| - (is (true? (ana/has-extern? '[console log] externs))) |
1512 |
| - (is (true? (ana/has-extern? '[Number isNaN] externs))))) |
1513 |
| - |
1514 |
| -(def externs-cenv |
1515 |
| - (atom |
1516 |
| - {::ana/externs |
1517 |
| - (externs/externs-map |
1518 |
| - (closure/load-externs |
1519 |
| - {:externs ["src/test/externs/test.js"]}))})) |
1520 |
| - |
1521 |
| -(deftest test-js-tag |
1522 |
| - (let [externs (externs/externs-map |
1523 |
| - (closure/load-externs |
1524 |
| - {:externs ["src/test/externs/test.js"]}))] |
1525 |
| - (is (= 'js/Console (ana/js-tag '[console] :tag externs))) |
1526 |
| - (is (= 'js/Function (ana/js-tag '[console log] :tag externs))) |
1527 |
| - (is (= 'js/Boolean (ana/js-tag '[Number isNaN] :ret-tag externs))) |
1528 |
| - (is (= 'js/Foo (ana/js-tag '[baz] :ret-tag externs))))) |
1529 |
| - |
1530 |
| -(deftest test-externs-infer |
1531 |
| - (is (= 'js/Foo |
1532 |
| - (-> (binding [ana/*cljs-ns* ana/*cljs-ns*] |
1533 |
| - (env/with-compiler-env externs-cenv |
1534 |
| - (analyze (ana/empty-env) 'js/baz))) |
1535 |
| - :info :ret-tag))) |
1536 |
| - (is (= 'js/Foo |
1537 |
| - (-> (binding [ana/*cljs-ns* ana/*cljs-ns*] |
1538 |
| - (env/with-compiler-env externs-cenv |
1539 |
| - (analyze (ana/empty-env) '(js/baz)))) |
1540 |
| - :tag))) |
1541 |
| - (is (= 'js |
1542 |
| - (-> (binding [ana/*cljs-ns* ana/*cljs-ns*] |
1543 |
| - (env/with-compiler-env externs-cenv |
1544 |
| - (analyze (ana/empty-env) '(js/woz)))) |
1545 |
| - :tag))) |
1546 |
| - (is (= 'js |
1547 |
| - (-> (binding [ana/*cljs-ns* ana/*cljs-ns*] |
1548 |
| - (env/with-compiler-env externs-cenv |
1549 |
| - (analyze (ana/empty-env) '(def foo (js/woz))))) |
1550 |
| - :tag))) |
1551 |
| - (is (= 'js |
1552 |
| - (-> (binding [ana/*cljs-ns* ana/*cljs-ns*] |
1553 |
| - (env/with-compiler-env externs-cenv |
1554 |
| - (analyze (ana/empty-env) '(def foo js/boz)))) |
1555 |
| - :tag))) |
1556 |
| - (is (nil? (-> (binding [ana/*cljs-ns* ana/*cljs-ns*] |
1557 |
| - (ana/no-warn |
1558 |
| - (env/with-compiler-env externs-cenv |
1559 |
| - (analyze (ana/empty-env) |
1560 |
| - '(let [z (.baz ^js/Foo.Bar x)] |
1561 |
| - z))))) |
1562 |
| - :tag meta :prefix)))) |
1563 |
| - |
1564 | 1494 | (deftest test-cljs-1871
|
1565 | 1495 | (let [ws (atom [])]
|
1566 | 1496 | (try
|
|
1695 | 1625 | #"Can't recur here"
|
1696 | 1626 | (analyze test-env invalid-try-recur-form)))))
|
1697 | 1627 |
|
1698 |
| -(comment |
1699 |
| - (binding [ana/*cljs-ns* ana/*cljs-ns*] |
1700 |
| - (ana/no-warn |
1701 |
| - (env/with-compiler-env externs-cenv |
1702 |
| - (analyze (ana/empty-env) |
1703 |
| - '(let [React (js/require "react")] |
1704 |
| - React))))) |
1705 |
| - |
1706 |
| - ;; FIXME: we don't preserve tag information |
1707 |
| - (binding [ana/*cljs-ns* ana/*cljs-ns*] |
1708 |
| - (ana/no-warn |
1709 |
| - (env/with-compiler-env externs-cenv |
1710 |
| - (let [aenv (ana/empty-env) |
1711 |
| - _ (analyze aenv '(ns foo.core)) |
1712 |
| - aenv' (assoc-in aenv [:ns :name] 'foo.core) |
1713 |
| - _ (ana/analyze aenv' '(def x 1))] |
1714 |
| - (dissoc (ana/analyze-symbol (assoc-in aenv [:ns :name] 'foo.core) 'x) :env) |
1715 |
| - ;(get-in @externs-cenv [::ana/namespaces 'foo.core]) |
1716 |
| - )))) |
1717 |
| - ) |
1718 |
| - |
1719 |
| -(def core-inferred |
1720 |
| - ["var setTimeout;" "var process;" "process.hrtime;" |
1721 |
| - "goog.isArrayLike;" "Java.type;" "Object.out;" "Object.out.println;" |
1722 |
| - "Object.error;" "Object.error.println;"]) |
1723 |
| - |
1724 |
| -(defn infer-test-helper |
1725 |
| - [{:keys [forms externs warnings warn js-dependency-index with-core? opts]}] |
1726 |
| - (let [test-cenv (atom |
1727 |
| - (cond-> |
1728 |
| - (if with-core? |
1729 |
| - (env/default-compiler-env* |
1730 |
| - (closure/add-externs-sources (merge {:infer-externs true} opts))) |
1731 |
| - {::ana/externs |
1732 |
| - (externs/externs-map |
1733 |
| - (closure/load-externs {:externs (or externs [])}))}) |
1734 |
| - js-dependency-index (assoc :js-dependency-index js-dependency-index))) |
1735 |
| - wrap (if with-core? |
1736 |
| - #(comp/with-core-cljs nil %) |
1737 |
| - #(do (%)))] |
1738 |
| - (ana/with-warning-handlers [(collecting-warning-handler (or warnings (atom [])))] |
1739 |
| - (binding [ana/*analyze-deps* false |
1740 |
| - ana/*cljs-ns* ana/*cljs-ns*] |
1741 |
| - (env/with-compiler-env test-cenv |
1742 |
| - (wrap |
1743 |
| - (fn [] |
1744 |
| - (binding [ana/*analyze-deps* true |
1745 |
| - ana/*cljs-warnings* |
1746 |
| - (assoc ana/*cljs-warnings* |
1747 |
| - :infer-warning (if (nil? warn) true warn))] |
1748 |
| - (ana/analyze-form-seq forms)) |
1749 |
| - (with-out-str |
1750 |
| - (comp/emit-externs |
1751 |
| - (reduce util/map-merge {} |
1752 |
| - (map (comp :externs second) |
1753 |
| - (get @test-cenv ::ana/namespaces)))))))))))) |
1754 |
| - |
1755 |
| -(deftest test-basic-infer |
1756 |
| - (let [res (infer-test-helper |
1757 |
| - {:forms '[(ns foo.core) |
1758 |
| - (defn bar [a] (js/parseInt a)) |
1759 |
| - (def c js/React.Component) |
1760 |
| - (js/console.log "Hello world!") |
1761 |
| - (fn [& args] |
1762 |
| - (.apply (.-log js/console) js/console (into-array args))) |
1763 |
| - (js/console.log js/Number.MAX_VALUE) |
1764 |
| - (js/console.log js/Symbol.iterator)]})] |
1765 |
| - (is (= (unsplit-lines ["var React;" "React.Component;"]) res)))) |
1766 |
| - |
1767 |
| -(deftest test-method-infer |
1768 |
| - (let [res (infer-test-helper |
1769 |
| - {:forms '[(defn foo [^js/React.Component c] |
1770 |
| - (.render c))]})] |
1771 |
| - (is (= (unsplit-lines ["var React;" "React.Component;" "React.Component.prototype.render;"]) |
1772 |
| - res)))) |
1773 |
| - |
1774 |
| -(deftest test-minimal-infer |
1775 |
| - (let [res (infer-test-helper |
1776 |
| - {:forms '[(js/console.log (.wozMethod (js/baz)))] |
1777 |
| - :externs ["src/test/externs/test.js"]})] |
1778 |
| - (is (string/blank? res)))) |
1779 |
| - |
1780 |
| -(deftest test-type-hint-minimal-infer |
1781 |
| - (let [res (infer-test-helper |
1782 |
| - {:forms ''[(defn afun [^js/Foo x] |
1783 |
| - (.wozMethod x))] |
1784 |
| - :externs ["src/test/externs/test.js"]})] |
1785 |
| - (is (string/blank? res)))) |
1786 |
| - |
1787 |
| -(deftest test-type-hint-infer-unknown-method-in-chain |
1788 |
| - (let [ws (atom []) |
1789 |
| - res (infer-test-helper |
1790 |
| - {:forms '[(defn afun [^js/Foo.Bar x] |
1791 |
| - (let [z (.baz x)] |
1792 |
| - (.wozz z)))] |
1793 |
| - :externs ["src/test/externs/test.js"] |
1794 |
| - :warnings ws})] |
1795 |
| - (is (= (unsplit-lines ["Foo.Boo.prototype.wozz;"]) res)) |
1796 |
| - (is (= 1 (count @ws))) |
1797 |
| - (is (string/starts-with? |
1798 |
| - (first @ws) |
1799 |
| - "Cannot resolve property wozz for inferred type js/Foo.Boo")))) |
1800 |
| - |
1801 |
| -(deftest test-type-hint-infer-unknown-property-in-chain |
1802 |
| - (let [ws (atom []) |
1803 |
| - res (infer-test-helper |
1804 |
| - {:forms '[(defn afun [^js/Foo.Bar x] |
1805 |
| - (let [z (.baz x)] |
1806 |
| - (.-wozz z)))] |
1807 |
| - :externs ["src/test/externs/test.js"] |
1808 |
| - :warnings ws})] |
1809 |
| - (is (= (unsplit-lines ["Foo.Boo.prototype.wozz;"]) res)) |
1810 |
| - (is (= 1 (count @ws))) |
1811 |
| - (is (string/starts-with? |
1812 |
| - (first @ws) |
1813 |
| - "Cannot resolve property wozz for inferred type js/Foo.Boo")))) |
1814 |
| - |
1815 |
| -(deftest test-type-hint-infer-unknown-method |
1816 |
| - (let [ws (atom []) |
1817 |
| - res (infer-test-helper |
1818 |
| - {:forms '[(defn baz [^js/Foo a] |
1819 |
| - (.gozMethod a))] |
1820 |
| - :externs ["src/test/externs/test.js"] |
1821 |
| - :warnings ws})] |
1822 |
| - (is (= (unsplit-lines ["Foo.prototype.gozMethod;"]) res)) |
1823 |
| - (is (= 1 (count @ws))) |
1824 |
| - (is (string/starts-with? |
1825 |
| - (first @ws) |
1826 |
| - "Cannot resolve property gozMethod for inferred type js/Foo")))) |
1827 |
| - |
1828 |
| -(deftest test-infer-unknown-method-from-externs |
1829 |
| - (let [ws (atom []) |
1830 |
| - res (infer-test-helper |
1831 |
| - {:forms '[(.gozMethod (js/baz))] |
1832 |
| - :externs ["src/test/externs/test.js"] |
1833 |
| - :warnings ws})] |
1834 |
| - (is (= (unsplit-lines ["Foo.prototype.gozMethod;"]) res)) |
1835 |
| - (is (= 1 (count @ws))) |
1836 |
| - (is (string/starts-with? |
1837 |
| - (first @ws) |
1838 |
| - "Cannot resolve property gozMethod for inferred type js/Foo")))) |
1839 |
| - |
1840 |
| -(deftest test-infer-js-require |
1841 |
| - (let [ws (atom []) |
1842 |
| - res (infer-test-helper |
1843 |
| - {:forms '[(ns foo.core) |
1844 |
| - (def React (js/require "react")) |
1845 |
| - (.log js/console (.-Component React))] |
1846 |
| - :externs ["src/test/externs/test.js"] |
1847 |
| - :warnings ws})] |
1848 |
| - (is (= (unsplit-lines ["var require;" "Object.Component;"]) res)) |
1849 |
| - (is (= 1 (count @ws))) |
1850 |
| - (is (string/starts-with? |
1851 |
| - (first @ws) |
1852 |
| - "Adding extern to Object for property Component")))) |
1853 |
| - |
1854 |
| -(deftest test-set-warn-on-infer |
1855 |
| - (let [ws (atom []) |
1856 |
| - res (infer-test-helper |
1857 |
| - {:forms '[(ns warn-on-infer-test.app) |
1858 |
| - (set! *warn-on-infer* true) |
1859 |
| - (defn wrap-baz [x] |
1860 |
| - (.baz x))] |
1861 |
| - :externs ["src/test/externs/test.js"] |
1862 |
| - :warnings ws |
1863 |
| - :warn false |
1864 |
| - :with-core? true})] |
1865 |
| - (is (= 1 (count @ws))) |
1866 |
| - (is (string/starts-with? (first @ws) "Cannot infer target type")))) |
1867 |
| - |
1868 |
| -(deftest test-cljs-1970-infer-with-cljs-literals |
1869 |
| - (let [ws (atom []) |
1870 |
| - res (infer-test-helper |
1871 |
| - {:forms '[(ns cjls-1970.core) |
1872 |
| - (set! *warn-on-infer* true) |
1873 |
| - (defn foo [] (list)) |
1874 |
| - (defn bar [] (vector))] |
1875 |
| - :externs ["src/test/externs/test.js"] |
1876 |
| - :warnings ws |
1877 |
| - :with-core? true})] |
1878 |
| - (is (zero? (count @ws))))) |
1879 |
| - |
1880 |
| -(deftest test-cljs-1918-infer-with-case-keywords |
1881 |
| - (let [ws (atom []) |
1882 |
| - res (infer-test-helper |
1883 |
| - {:forms '[(ns cjls-1918.core) |
1884 |
| - (defn foo [x] |
1885 |
| - (cljs.core/case x |
1886 |
| - :foo 1 |
1887 |
| - nil))] |
1888 |
| - :externs ["src/test/externs/test.js"] |
1889 |
| - :warnings ws |
1890 |
| - :with-core? true})] |
1891 |
| - (is (zero? (count @ws))))) |
1892 |
| - |
1893 |
| -(deftest test-cljs-2247 |
1894 |
| - (let [ws (atom [])] |
1895 |
| - (try |
1896 |
| - (ana/with-warning-handlers [(collecting-warning-handler ws)] |
1897 |
| - (env/with-compiler-env (assoc @test-cenv :repl-env {}) |
1898 |
| - (ana/analyze (ana/empty-env) |
1899 |
| - '(defn -foo [])) |
1900 |
| - (ana/analyze (ana/empty-env) |
1901 |
| - '(defprotocol IAlpha (-foo [this]))))) |
1902 |
| - (catch Exception _)) |
1903 |
| - (is (= ["Protocol IAlpha is overwriting function -foo"] @ws)))) |
1904 |
| - |
1905 |
| -(deftest test-cljs-2385-infer-priority |
1906 |
| - (let [ws (atom []) |
1907 |
| - res (infer-test-helper |
1908 |
| - {:forms '[(ns cjls-1918.core) |
1909 |
| - (defn thing [{:as this}] |
1910 |
| - (.componentDidUpdate ^js/Thing this))] |
1911 |
| - :externs ["src/test/externs/test.js"] |
1912 |
| - :warnings ws |
1913 |
| - :with-core? true})] |
1914 |
| - (is (string/includes? res "Thing.prototype.componentDidUpdate;")) |
1915 |
| - (is (zero? (count @ws))))) |
1916 |
| - |
1917 |
| -(deftest test-cljs-2392-broken-inferred-externs |
1918 |
| - (let [ws (atom []) |
1919 |
| - res (infer-test-helper |
1920 |
| - {:forms '[(ns cjls-1918.core |
1921 |
| - (:require [cljs.nodejs] |
1922 |
| - [cljs.nodejscli]))] |
1923 |
| - :warnings ws |
1924 |
| - :with-core? true |
1925 |
| - :opts {:target :nodejs}})] |
1926 |
| - (not (string/includes? res "COMPILED")) |
1927 |
| - (not (string/includes? res "goog")) |
1928 |
| - (is (zero? (count @ws))))) |
1929 |
| - |
1930 |
| -(deftest test-cljs-2678-global-exports-infer |
1931 |
| - (let [ws (atom []) |
1932 |
| - res (infer-test-helper |
1933 |
| - {:js-dependency-index {"react" {:global-exports '{react React}}} |
1934 |
| - :forms '[(ns foo.core |
1935 |
| - (:require [react :as react])) |
1936 |
| - (.log js/console react/Component)] |
1937 |
| - :warnings ws |
1938 |
| - :warn false})] |
1939 |
| - (is (= (unsplit-lines ["Object.Component;"]) res)))) |
1940 |
| - |
1941 |
| -(deftest test-cljs-2767-deftype-defrecord |
1942 |
| - (let [ws (atom []) |
1943 |
| - res (infer-test-helper |
1944 |
| - {:forms '[(ns cjls-2767.core) |
1945 |
| - (defrecord Foo [])] |
1946 |
| - :externs ["src/test/externs/test.js"] |
1947 |
| - :warnings ws |
1948 |
| - :with-core? true})] |
1949 |
| - (is (empty? @ws)) |
1950 |
| - (is (not (string/includes? res "cljs.core")))) |
1951 |
| - (let [ws (atom []) |
1952 |
| - res (infer-test-helper |
1953 |
| - {:forms '[(ns cjls-2767.core) |
1954 |
| - (deftype Foo [])] |
1955 |
| - :externs ["src/test/externs/test.js"] |
1956 |
| - :warnings ws |
1957 |
| - :with-core? true})] |
1958 |
| - (is (empty? @ws)) |
1959 |
| - (is (not (string/includes? res "cljs.core"))))) |
1960 |
| - |
1961 |
| -(deftest test-cljs-2790-defrecord-fields |
1962 |
| - (let [ws (atom []) |
1963 |
| - res (infer-test-helper |
1964 |
| - {:forms '[(ns cjls-2790.core) |
1965 |
| - (defrecord Foo [a b])] |
1966 |
| - :externs ["src/test/externs/test.js"] |
1967 |
| - :warnings ws |
1968 |
| - :with-core? true})] |
1969 |
| - (is (empty? @ws)) |
1970 |
| - (is (not (string/includes? res "cljs.core"))))) |
1971 |
| - |
1972 | 1628 | (deftest test-locals-mapped-to-sym
|
1973 | 1629 | (testing "analyze should be robust to :locals mapping to symbols"
|
1974 | 1630 | (is (= [:local 'a] (-> (analyze (assoc-in test-env [:locals 'a] 'foo) 'a)
|
|
2137 | 1793 | (is (= w2 "cljs.core/-, all arguments must be numbers, got [string] instead"))
|
2138 | 1794 | (is (= w3 "cljs.core//, all arguments must be numbers, got [number string] instead"))
|
2139 | 1795 | (is (= w4 "cljs.core/*, all arguments must be numbers, got [string] instead")))))
|
2140 |
| - |
2141 |
| -(deftest test-cljs-3181 |
2142 |
| - (let [ws (atom []) |
2143 |
| - res (binding [ana/*cljs-static-fns* true] |
2144 |
| - (infer-test-helper |
2145 |
| - {:forms '[(ns warn-on-infer-test.app) |
2146 |
| - (set! *warn-on-infer* true) |
2147 |
| - (defn f [gfn] |
2148 |
| - (.then ^js/Promise (gfn (inc 1)) identity))] |
2149 |
| - :externs ["src/test/externs/test.js"] |
2150 |
| - :warnings ws |
2151 |
| - :warn false |
2152 |
| - :with-core? true}))] |
2153 |
| - (is (empty? @ws)))) |
0 commit comments