|
781 | 781 | {:name (symbol (str full-ns) (str sym))
|
782 | 782 | :ns full-ns}))
|
783 | 783 |
|
| 784 | + (not (nil? (gets @env/*compiler* ::namespaces (-> env :ns :name) :renames sym))) |
| 785 | + (let [qualified-symbol (gets @env/*compiler* ::namespaces (-> env :ns :name) :renames sym) |
| 786 | + full-ns (symbol (namespace qualified-symbol)) |
| 787 | + sym (symbol (name qualified-symbol))] |
| 788 | + (merge |
| 789 | + (gets @env/*compiler* ::namespaces full-ns :defs sym) |
| 790 | + {:name qualified-symbol |
| 791 | + :ns full-ns})) |
| 792 | + |
784 | 793 | (not (nil? (gets @env/*compiler* ::namespaces (-> env :ns :name) :imports sym)))
|
785 | 794 | (recur env (gets @env/*compiler* ::namespaces (-> env :ns :name) :imports sym) confirm)
|
786 | 795 |
|
|
830 | 839 | (let [full-ns (get-in namespaces [ns :use-macros sym])]
|
831 | 840 | (get-in namespaces [full-ns :macros sym]))
|
832 | 841 |
|
| 842 | + (get-in namespaces [ns :rename-macros sym]) |
| 843 | + (let [qualified-symbol (get-in namespaces [ns :rename-macros sym]) |
| 844 | + full-ns (symbol (namespace qualified-symbol)) |
| 845 | + sym (symbol (name qualified-symbol))] |
| 846 | + (get-in namespaces [full-ns :macros sym])) |
| 847 | + |
833 | 848 | :else
|
834 | 849 | (let [ns (cond
|
835 | 850 | (get-in namespaces [ns :macros sym]) ns
|
|
1727 | 1742 | (not (= (get js-lib :group) :goog))
|
1728 | 1743 | (not (get js-lib :closure-lib)))))
|
1729 | 1744 |
|
| 1745 | +(defn missing-rename? [sym cenv] |
| 1746 | + (let [lib (symbol (namespace sym)) |
| 1747 | + sym (symbol (name sym))] |
| 1748 | + (missing-use? lib sym cenv))) |
| 1749 | + |
1730 | 1750 | (defn missing-use-macro? [lib sym]
|
1731 | 1751 | (let [the-ns #?(:clj (find-ns lib) :cljs (find-macros-ns lib))]
|
1732 | 1752 | (or (nil? the-ns) (nil? (.findInternedVar ^clojure.lang.Namespace the-ns sym)))))
|
1733 | 1753 |
|
| 1754 | +(defn missing-rename-macro? [sym] |
| 1755 | + (let [lib (symbol (namespace sym)) |
| 1756 | + sym (symbol (name sym)) |
| 1757 | + the-ns #?(:clj (find-ns lib) :cljs (find-macros-ns lib))] |
| 1758 | + (or (nil? the-ns) (nil? (.findInternedVar ^clojure.lang.Namespace the-ns sym))))) |
| 1759 | + |
1734 | 1760 | (defn missing-uses [uses env]
|
1735 | 1761 | (let [cenv @env/*compiler*]
|
1736 | 1762 | (into {} (filter (fn [[sym lib]] (missing-use? lib sym cenv)) uses))))
|
1737 | 1763 |
|
| 1764 | +(defn missing-renames [renames] |
| 1765 | + (let [cenv @env/*compiler*] |
| 1766 | + (into {} (filter (fn [[_ qualified-sym]] (missing-rename? qualified-sym cenv)) renames)))) |
| 1767 | + |
1738 | 1768 | (defn missing-use-macros [use-macros env]
|
1739 | 1769 | (let [cenv @env/*compiler*]
|
1740 | 1770 | (into {} (filter (fn [[sym lib]] (missing-use-macro? lib sym)) use-macros))))
|
|
1743 | 1773 | (let [cenv @env/*compiler*]
|
1744 | 1774 | (into {} (filter (fn [[sym lib]] (not (missing-use-macro? lib sym))) use-macros))))
|
1745 | 1775 |
|
| 1776 | +(defn inferred-rename-macros [rename-macros env] |
| 1777 | + (into {} (filter (fn [[_ qualified-sym]] (not (missing-rename-macro? qualified-sym))) rename-macros))) |
| 1778 | + |
1746 | 1779 | (defn check-uses [uses env]
|
1747 | 1780 | (let [cenv @env/*compiler*]
|
1748 | 1781 | (doseq [[sym lib] uses]
|
|
1766 | 1799 |
|
1767 | 1800 | (defn check-use-macros-inferring-missing
|
1768 | 1801 | [ast name use-macros missing-uses env]
|
1769 |
| - (let [remove-missing-uses #(apply dissoc % (keys missing-uses)) |
| 1802 | + (let [remove-missing-uses #(apply dissoc % (keys missing-uses)) |
| 1803 | + missing-renames (missing-renames (:renames ast)) |
| 1804 | + missing-rename-macros (inferred-rename-macros missing-renames env) |
| 1805 | + remove-missing-renames #(apply dissoc % (keys missing-renames)) |
1770 | 1806 | ast' (-> ast
|
1771 | 1807 | (update-in [:use-macros] merge
|
1772 | 1808 | (check-use-macros use-macros missing-uses env))
|
1773 |
| - (update-in [:uses] remove-missing-uses))] |
| 1809 | + (update-in [:uses] remove-missing-uses) |
| 1810 | + (update-in [:rename-macros] merge missing-rename-macros) |
| 1811 | + (update-in [:renames] remove-missing-renames))] |
1774 | 1812 | (swap! env/*compiler* #(-> %
|
1775 | 1813 | (update-in [::namespaces name :use-macros] merge (:use-macros ast'))
|
1776 |
| - (update-in [::namespaces name :uses] remove-missing-uses))) |
| 1814 | + (update-in [::namespaces name :uses] remove-missing-uses) |
| 1815 | + (update-in [::namespaces name :rename-macros] merge (:rename-macros ast')) |
| 1816 | + (update-in [::namespaces name :renames] remove-missing-renames))) |
1777 | 1817 | ast'))
|
1778 | 1818 |
|
1779 | 1819 | (defn parse-ns-error-msg [spec msg]
|
|
1795 | 1835 | (throw
|
1796 | 1836 | (error env
|
1797 | 1837 | (parse-ns-error-msg spec
|
1798 |
| - "Only :as alias and :refer (names) options supported in :require")))) |
1799 |
| - (when-not (every? #{:as :refer} (map first (partition 2 (next spec)))) |
| 1838 | + "Only :as alias, :refer (names) and :rename {from to} options supported in :require")))) |
| 1839 | + (when-not (every? #{:as :refer :rename} (map first (partition 2 (next spec)))) |
1800 | 1840 | (throw
|
1801 | 1841 | (error env
|
1802 | 1842 | (parse-ns-error-msg spec
|
1803 |
| - "Only :as and :refer options supported in :require / :require-macros")))) |
| 1843 | + "Only :as, :refer and :rename options supported in :require / :require-macros")))) |
1804 | 1844 | (when-not (let [fs (frequencies (next spec))]
|
1805 | 1845 | (and (<= (fs :as 0) 1)
|
1806 | 1846 | (<= (fs :refer 0) 1)))
|
|
1811 | 1851 |
|
1812 | 1852 | (defn parse-ns-excludes [env args]
|
1813 | 1853 | (reduce
|
1814 |
| - (fn [s [k exclude xs]] |
| 1854 | + (fn [s [k & filters]] |
1815 | 1855 | (if (= k :refer-clojure)
|
1816 | 1856 | (do
|
1817 |
| - (when-not (= exclude :exclude) |
1818 |
| - (throw (error env "Only [:refer-clojure :exclude (names)] form supported"))) |
1819 | 1857 | (when (seq s)
|
1820 | 1858 | (throw (error env "Only one :refer-clojure form is allowed per namespace definition")))
|
1821 |
| - (into s xs)) |
| 1859 | + (let [valid-kws #{:exclude :rename} |
| 1860 | + xs |
| 1861 | + (loop [fs (seq filters) |
| 1862 | + ret {:excludes #{} |
| 1863 | + :renames {}} |
| 1864 | + err (not (even? (count filters)))] |
| 1865 | + (cond |
| 1866 | + (true? err) |
| 1867 | + (throw |
| 1868 | + (error env "Only [:refer-clojure :exclude (names)] and optionally `:rename {from to}` specs supported")) |
| 1869 | + |
| 1870 | + (not (nil? fs)) |
| 1871 | + (let [kw (first fs)] |
| 1872 | + (if (valid-kws kw) |
| 1873 | + (let [refs (second fs)] |
| 1874 | + (cond |
| 1875 | + (not (or (and (= kw :exclude) (sequential? refs) (every? symbol? refs)) |
| 1876 | + (and (= kw :rename) (map? refs) (every? #(every? symbol? %) refs)))) |
| 1877 | + (recur fs ret true) |
| 1878 | + |
| 1879 | + (= kw :exclude) |
| 1880 | + (recur (nnext fs) (update-in ret [:excludes] into refs) false) |
| 1881 | + |
| 1882 | + (= kw :rename) |
| 1883 | + (recur (nnext fs) (update-in ret [:renames] merge refs) false))) |
| 1884 | + (recur fs ret true ))) |
| 1885 | + |
| 1886 | + :else ret))] |
| 1887 | + (merge-with into s xs))) |
1822 | 1888 | s))
|
1823 |
| - #{} args)) |
| 1889 | + {} args)) |
1824 | 1890 |
|
1825 |
| -(defn use->require [env [lib kw referred :as spec]] |
1826 |
| - (when-not (and (symbol? lib) (= :only kw) (sequential? referred) (every? symbol? referred)) |
| 1891 | +(defn use->require [env [lib & filters :as spec]] |
| 1892 | + (when-not (and (symbol? lib) (odd? (count spec))) |
1827 | 1893 | (throw
|
1828 | 1894 | (error env
|
1829 | 1895 | (parse-ns-error-msg spec
|
1830 |
| - "Only [lib.ns :only (names)] specs supported in :use / :use-macros")))) |
1831 |
| - [lib :refer referred]) |
| 1896 | + "Only [lib.ns :only (names)] and optionally `:rename {from to}` specs supported in :use / :use-macros")))) |
| 1897 | + (loop [fs (seq filters) ret [lib] err false] |
| 1898 | + (cond |
| 1899 | + (true? err) |
| 1900 | + (throw |
| 1901 | + (error env |
| 1902 | + (parse-ns-error-msg spec |
| 1903 | + "Only [lib.ns :only (names)] and optionally `:rename {from to}` specs supported in :use / :use-macros"))) |
| 1904 | + |
| 1905 | + (not (nil? fs)) |
| 1906 | + (let [kw (first fs) |
| 1907 | + only? (= kw :only)] |
| 1908 | + (if (or only? (= kw :rename)) |
| 1909 | + (if (some #{(if only? :refer kw)} ret) |
| 1910 | + (throw |
| 1911 | + (error env |
| 1912 | + (parse-ns-error-msg spec |
| 1913 | + "Each of :only and :rename options may only be specified once in :use / :use-macros"))) |
| 1914 | + (let [refs (second fs)] |
| 1915 | + (if-not (or (and only? (sequential? refs) (every? symbol? refs)) |
| 1916 | + (and (= kw :rename) (map? refs) (every? #(every? symbol? %) refs))) |
| 1917 | + (recur fs ret true) |
| 1918 | + (recur (nnext fs) (into ret [(if only? :refer kw) refs]) false)))) |
| 1919 | + (recur fs ret true ))) |
| 1920 | + |
| 1921 | + :else (if (some #{:refer} ret) |
| 1922 | + ret |
| 1923 | + (recur fs ret true))))) |
1832 | 1924 |
|
1833 | 1925 | (defn parse-require-spec [env macros? deps aliases spec]
|
1834 | 1926 | (if (symbol? spec)
|
|
1839 | 1931 | lib (if-let [js-module-name (get-in @env/*compiler* [:js-module-index (name lib)])]
|
1840 | 1932 | (symbol js-module-name)
|
1841 | 1933 | lib)
|
1842 |
| - {alias :as referred :refer :or {alias lib}} (apply hash-map opts) |
1843 |
| - [rk uk] (if macros? [:require-macros :use-macros] [:require :use])] |
| 1934 | + {alias :as referred :refer renamed :rename :or {alias lib}} (apply hash-map opts) |
| 1935 | + referred-without-renamed (seq (remove (set (keys renamed)) referred)) |
| 1936 | + [rk uk renk] (if macros? [:require-macros :use-macros :rename-macros] [:require :use :rename])] |
1844 | 1937 | (when-not (or (symbol? alias) (nil? alias))
|
1845 | 1938 | (throw
|
1846 | 1939 | (error env
|
|
1866 | 1959 | (merge
|
1867 | 1960 | (when alias
|
1868 | 1961 | {rk (merge {alias lib} {lib lib})})
|
1869 |
| - (when referred {uk (apply hash-map (interleave referred (repeat lib)))})))))) |
| 1962 | + (when referred-without-renamed {uk (apply hash-map (interleave referred-without-renamed (repeat lib)))}) |
| 1963 | + (when renamed |
| 1964 | + {renk (reduce (fn [m [original renamed]] |
| 1965 | + (when-not (some #{original} referred) |
| 1966 | + (throw (error env |
| 1967 | + (str "Renamed symbol " original " not referred")))) |
| 1968 | + (assoc m renamed (symbol (str lib) (str original)))) |
| 1969 | + {} renamed)})))))) |
1870 | 1970 |
|
1871 | 1971 | (defn parse-import-spec [env deps spec]
|
1872 | 1972 | (when-not (or (and (sequential? spec)
|
|
1977 | 2077 | (if-not (reload-spec? x)
|
1978 | 2078 | (->> x (remove-from-spec #{:include-macros})
|
1979 | 2079 | (remove-from-spec #{:refer})
|
| 2080 | + (remove-from-spec #{:rename}) |
1980 | 2081 | (replace-refer-macros))
|
1981 | 2082 | x)))))
|
1982 | 2083 | remove-sugar (partial remove-from-spec sugar-keys)]
|
|
2034 | 2135 | (if metadata (next args) args))
|
2035 | 2136 | :cljs (if metadata (next args) args)))
|
2036 | 2137 | name (vary-meta name merge metadata)
|
2037 |
| - excludes (parse-ns-excludes env args) |
| 2138 | + {excludes :excludes core-renames :renames} (parse-ns-excludes env args) |
| 2139 | + core-renames (reduce (fn [m [original renamed]] |
| 2140 | + (assoc m renamed (symbol "cljs.core" (str original)))) |
| 2141 | + {} core-renames) |
2038 | 2142 | deps (atom #{})
|
2039 | 2143 | aliases (atom {:fns {} :macros {}})
|
2040 | 2144 | spec-parsers {:require (partial parse-require-spec env false deps aliases)
|
|
2047 | 2151 | valid-forms (atom #{:use :use-macros :require :require-macros :import})
|
2048 | 2152 | reload (atom {:use nil :require nil :use-macros nil :require-macros nil})
|
2049 | 2153 | reloads (atom {})
|
2050 |
| - {uses :use requires :require use-macros :use-macros require-macros :require-macros imports :import :as params} |
| 2154 | + {uses :use requires :require renames :rename |
| 2155 | + use-macros :use-macros require-macros :require-macros |
| 2156 | + rename-macros :rename-macros imports :import :as params} |
2051 | 2157 | (reduce
|
2052 | 2158 | (fn [m [k & libs]]
|
2053 | 2159 | (when-not (#{:use :use-macros :require :require-macros :import} k)
|
|
2076 | 2182 | :excludes excludes
|
2077 | 2183 | :use-macros use-macros
|
2078 | 2184 | :require-macros require-macros
|
| 2185 | + :rename-macros rename-macros |
2079 | 2186 | :uses uses
|
2080 | 2187 | :requires requires
|
| 2188 | + :renames (merge renames core-renames) |
2081 | 2189 | :imports imports}
|
2082 | 2190 | ns-info
|
2083 | 2191 | (if (:merge form-meta)
|
2084 | 2192 | ;; for merging information in via require usage in REPLs
|
2085 | 2193 | (let [ns-info' (get-in @env/*compiler* [::namespaces name])]
|
2086 | 2194 | (if (pos? (count ns-info'))
|
2087 | 2195 | (let [merge-keys
|
2088 |
| - [:use-macros :require-macros :uses :requires :imports]] |
| 2196 | + [:use-macros :require-macros :rename-macros |
| 2197 | + :uses :requires :renames :imports]] |
2089 | 2198 | (merge
|
2090 | 2199 | ns-info'
|
2091 | 2200 | (merge-with merge
|
|
2458 | 2567 | (when-not (or (not (nil? (gets env :locals sym))) ; locals hide macros
|
2459 | 2568 | (and (excluded? env sym) (not (used? env sym))))
|
2460 | 2569 | (let [nstr (namespace sym)]
|
2461 |
| - (if-not (nil? nstr) |
| 2570 | + (cond |
| 2571 | + (not (nil? nstr)) |
2462 | 2572 | (let [ns (get-expander-ns env nstr)]
|
2463 | 2573 | (when-not (nil? ns)
|
2464 | 2574 | (.findInternedVar ^clojure.lang.Namespace ns (symbol (name sym)))))
|
| 2575 | + |
| 2576 | + (not (nil? (gets env :ns :rename-macros sym))) |
| 2577 | + (let [qualified-symbol (gets env :ns :rename-macros sym) |
| 2578 | + nsym (symbol (namespace qualified-symbol)) |
| 2579 | + sym (symbol (name qualified-symbol))] |
| 2580 | + (.findInternedVar ^clojure.lang.Namespace |
| 2581 | + #?(:clj (find-ns nsym) :cljs (find-macros-ns nsym)) sym)) |
| 2582 | + |
| 2583 | + :else |
2465 | 2584 | (let [nsym (gets env :ns :use-macros sym)]
|
2466 | 2585 | (if-not (nil? nsym)
|
2467 | 2586 | (.findInternedVar ^clojure.lang.Namespace
|
|
0 commit comments