|
4 | 4 | (ns refactor-nrepl.ns.imports-and-refers-analysis
|
5 | 5 | "Formerly known as `refactor-nrepl.ns.slam.hound.regrow`."
|
6 | 6 | (:require
|
7 |
| - [nrepl.middleware.interruptible-eval :refer [*msg*]] |
8 | 7 | [refactor-nrepl.ns.class-search :as class-search]))
|
9 | 8 |
|
10 |
| -(def ^:dynamic *cache* (atom {})) |
11 |
| -(def ^:dynamic *dirty-ns* (atom #{})) |
12 |
| - |
13 |
| -(defn wrap-clojure-repl [f] |
14 |
| - (fn [& args] |
15 |
| - (when-let [ns (some-> *msg* :ns symbol find-ns)] |
16 |
| - (swap! *dirty-ns* conj ns)) |
17 |
| - (apply f args))) |
18 |
| - |
19 |
| -;; XXX remove this if possible, we shouldn't be this sort of stuff. |
20 |
| -(alter-var-root #'clojure.main/repl wrap-clojure-repl) |
21 |
| - |
22 |
| -(defn cache-with-dirty-tracking |
23 |
| - "The function to be cached, f, should have two signatures. A zero-operand |
24 |
| - signature which computes the result for all namespaces, and a two-operand |
25 |
| - version which takes the previously computed result and a list of dirty |
26 |
| - namespaces, and returns an updated result." |
27 |
| - [k f] |
28 |
| - (if *cache* |
29 |
| - (if-let [cached (get @*cache* k)] |
30 |
| - (if-let [dirty (seq @*dirty-ns*)] |
31 |
| - (k (swap! *cache* assoc k (f cached dirty))) |
32 |
| - cached) |
33 |
| - (k (swap! *cache* assoc k (f)))) |
34 |
| - (f))) |
35 |
| - |
36 |
| -(defn clear-cache! [] |
37 |
| - (when *cache* |
38 |
| - (reset! *cache* {}) |
39 |
| - (reset! *dirty-ns* #{}))) |
40 |
| - |
41 |
| -(defn- all-ns-imports* |
| 9 | +;; Benefits from `pmap` because ns-imports is somewhat expensive. |
| 10 | +(defn- all-ns-imports |
42 | 11 | ([]
|
43 |
| - (all-ns-imports* {} (all-ns))) |
| 12 | + (all-ns-imports {} (all-ns))) |
44 | 13 | ([init namespaces]
|
45 |
| - (reduce (fn [imports ns] |
46 |
| - (assoc imports ns (ns-imports ns))) |
47 |
| - init namespaces))) |
48 |
| - |
49 |
| -(defn- all-ns-imports [] |
50 |
| - (cache-with-dirty-tracking :all-ns-imports all-ns-imports*)) |
51 |
| - |
52 |
| -(defn- symbols->ns-syms* |
| 14 | + (->> namespaces |
| 15 | + (pmap (fn [ns] |
| 16 | + [ns, (ns-imports ns)])) |
| 17 | + (into init)))) |
| 18 | + |
| 19 | +;; Doesn't need parallelization (unlike `all-ns-imports`), |
| 20 | +;; as this defn is instantaneous. |
| 21 | +(defn- symbols->ns-syms |
53 | 22 | ([]
|
54 |
| - (symbols->ns-syms* {} (all-ns))) |
| 23 | + (symbols->ns-syms {} (all-ns))) |
55 | 24 | ([init namespaces]
|
56 | 25 | (reduce
|
57 | 26 | (fn [m ns] (let [ns-sym (ns-name ns)]
|
|
61 | 30 | m (keys (ns-publics ns)))))
|
62 | 31 | init namespaces)))
|
63 | 32 |
|
64 |
| -(defn- symbols->ns-syms [] |
65 |
| - (cache-with-dirty-tracking :symbols->ns-syms symbols->ns-syms*)) |
66 |
| - |
67 | 33 | (defn- ns-import-candidates
|
68 | 34 | "Search (all-ns) for imports that match missing-sym, returning a set of
|
69 | 35 | class symbols. This is slower than scanning through the list of static
|
|
0 commit comments