|
3 | 3 | ;;;; Distributed under the Eclipse Public License, the same as Clojure.
|
4 | 4 | (ns refactor-nrepl.ns.slam.hound.regrow
|
5 | 5 | (:require
|
6 |
| - [clojure.set :as set] |
7 | 6 | [nrepl.middleware.interruptible-eval :refer [*msg*]]
|
8 |
| - [refactor-nrepl.ns.slam.hound.search :as search]) |
9 |
| - (:import |
10 |
| - (clojure.lang IMapEntry IRecord))) |
| 7 | + [refactor-nrepl.ns.slam.hound.search :as search])) |
11 | 8 |
|
12 | 9 | (def ^:dynamic *cache* (atom {}))
|
13 | 10 | (def ^:dynamic *dirty-ns* (atom #{}))
|
|
20 | 17 |
|
21 | 18 | (alter-var-root #'clojure.main/repl wrap-clojure-repl)
|
22 | 19 |
|
23 |
| -(defmacro ^:private caching [key & body] |
24 |
| - `(if *cache* |
25 |
| - (if-let [v# (get @*cache* ~key)] |
26 |
| - v# |
27 |
| - (let [v# (do ~@body)] |
28 |
| - (swap! *cache* assoc ~key v#) |
29 |
| - v#)) |
30 |
| - (do ~@body))) |
31 |
| - |
32 | 20 | (defn cache-with-dirty-tracking
|
33 | 21 | "The function to be cached, f, should have two signatures. A zero-operand
|
34 | 22 | signature which computes the result for all namespaces, and a two-operand
|
|
59 | 47 | (defn- all-ns-imports []
|
60 | 48 | (cache-with-dirty-tracking :all-ns-imports all-ns-imports*))
|
61 | 49 |
|
62 |
| -(defn- ns->symbols [] |
63 |
| - (caching :ns->symbols |
64 |
| - (let [xs (all-ns)] |
65 |
| - (zipmap xs (mapv (comp set keys ns-publics) xs))))) |
66 |
| - |
67 | 50 | (defn- symbols->ns-syms*
|
68 | 51 | ([]
|
69 | 52 | (symbols->ns-syms* {} (all-ns)))
|
|
79 | 62 | (defn- symbols->ns-syms []
|
80 | 63 | (cache-with-dirty-tracking :symbols->ns-syms symbols->ns-syms*))
|
81 | 64 |
|
82 |
| -(defn- walk |
83 |
| - "Adapted from clojure.walk/walk and clojure.walk/prewalk; this version |
84 |
| - preserves metadata on compound forms." |
85 |
| - [f form] |
86 |
| - (-> (cond |
87 |
| - (list? form) (apply list (map f form)) |
88 |
| - (instance? IMapEntry form) (vec (map f form)) |
89 |
| - (seq? form) (doall (map f form)) |
90 |
| - (instance? IRecord form) (reduce (fn [r x] (conj r (f x))) form form) |
91 |
| - (coll? form) (into (empty form) (map f form)) |
92 |
| - :else form) |
93 |
| - (as-> form (if-let [m (meta form)] |
94 |
| - (with-meta form m) |
95 |
| - form)))) |
96 |
| - |
97 |
| -(defn- prewalk [f form] |
98 |
| - (walk (partial prewalk f) (f form))) |
99 |
| - |
100 |
| -(defn- symbols-in-body [body] |
101 |
| - (filter symbol? (remove coll? (rest (tree-seq coll? seq body))))) |
102 |
| - |
103 |
| -(defn- remove-var-form |
104 |
| - "Remove (var symbol) forms from body" |
105 |
| - [expr] |
106 |
| - (if (and (coll? expr) (= (first expr) 'var)) |
107 |
| - nil |
108 |
| - expr)) |
109 |
| - |
110 |
| -(def ^:private ns-qualifed-syms |
111 |
| - (memoize |
112 |
| - (fn [body] |
113 |
| - (apply merge-with set/union {} |
114 |
| - (for [ss (symbols-in-body body) |
115 |
| - :let [[_ alias var-name] (re-matches #"(.+)/(.+)" (str ss))] |
116 |
| - :when alias] |
117 |
| - {(symbol alias) #{(symbol var-name)}}))))) |
118 |
| - |
119 | 65 | (defn- ns-import-candidates
|
120 | 66 | "Search (all-ns) for imports that match missing-sym, returning a set of
|
121 | 67 | class symbols. This is slower than scanning through the list of static
|
|
128 | 74 | s))
|
129 | 75 | #{} (vals (all-ns-imports))))
|
130 | 76 |
|
131 |
| -(defn- alias-candidates [_type missing body] |
132 |
| - (set |
133 |
| - (let [syms-with-alias (get (ns-qualifed-syms body) missing)] |
134 |
| - (when (seq syms-with-alias) |
135 |
| - (let [ns->syms (ns->symbols)] |
136 |
| - (for [ns (all-ns) |
137 |
| - :when (set/subset? syms-with-alias (ns->syms ns))] |
138 |
| - (ns-name ns))))))) |
139 |
| - |
140 | 77 | (defn candidates
|
141 | 78 | "Return a set of class or ns symbols that match the given constraints."
|
142 |
| - [type missing body old-ns-map] |
| 79 | + [type missing _body _old-ns-map] |
143 | 80 | (case type
|
144 | 81 | :import (into (ns-import-candidates missing)
|
145 | 82 | (get @search/available-classes-by-last-segment missing))
|
146 |
| - :alias (let [cs (alias-candidates type missing body)] |
147 |
| - (if (seq cs) |
148 |
| - cs |
149 |
| - ;; Try the alias search again without dynamically resolved vars |
150 |
| - ;; in case #' was used to resolve private vars in an aliased ns |
151 |
| - (let [body' (prewalk remove-var-form body)] |
152 |
| - (if (= body' body) |
153 |
| - cs |
154 |
| - (alias-candidates type missing body'))))) |
155 |
| - :refer (get (symbols->ns-syms) missing) |
156 |
| - :rename (reduce-kv |
157 |
| - (fn [s ns orig->rename] |
158 |
| - (cond-> s |
159 |
| - (some #{missing} (vals orig->rename)) (conj ns))) |
160 |
| - #{} (:rename old-ns-map)))) |
| 83 | + :refer (get (symbols->ns-syms) missing))) |
0 commit comments