|
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