|
24 | 24 | (str/replace "#'" "") |
25 | 25 | (str/replace "clojure.core/" ""))) |
26 | 26 | full-class (get alias-info class class)] |
27 | | - (str/join "/" (remove nil? [full-class (:field node)])))) |
| 27 | + (str/join "/" (remove nil? [(if (map? full-class) "" full-class) (:field node)])))) |
28 | 28 |
|
29 | 29 | (defn- contains-var? |
30 | | - "Checks if the var of `node` is present in the `var-set`." |
31 | | - [vars-set alias-info node] |
32 | | - (vars-set (node->var alias-info node))) |
| 30 | + "Checks if the var of `node` is same as given `var-name`" |
| 31 | + [var-name alias-info node] |
| 32 | + (= var-name (node->var alias-info node))) |
33 | 33 |
|
34 | 34 | (defn present-before-expansion? |
35 | 35 | "returns true if node is not result of macro expansion or if it is and it contains |
|
48 | 48 |
|
49 | 49 | (defn- find-nodes |
50 | 50 | "Filters `ast` with `pred` and returns a list of vectors with line-beg, line-end, |
51 | | - colum-beg, column-end and the result of applying pred to the node for each |
52 | | - node in the AST. |
| 51 | + colum-beg, column-end for each node in the AST. |
53 | 52 |
|
54 | 53 | if name present macro call sites are checked if they contained name before macro expansion" |
55 | 54 | ([asts pred] |
|
58 | 57 | (map (juxt (comp :line :env) |
59 | 58 | (comp :end-line :env) |
60 | 59 | (comp :column :env) |
61 | | - (comp :end-column :env) |
62 | | - pred)) |
| 60 | + (comp :end-column :env))) |
63 | 61 | (map #(zipmap [:line-beg :line-end :col-beg :col-end] %)))) |
64 | 62 | ([name asts pred] |
65 | 63 | (find-nodes (map #(postwalk % (partial dissoc-macro-nodes name)) asts) pred))) |
|
81 | 79 | var-name))) |
82 | 80 |
|
83 | 81 | (defn- contains-var-or-const? [var-name alias-info node] |
84 | | - (or (contains-var? #{var-name} alias-info node) |
| 82 | + (or (contains-var? var-name alias-info node) |
85 | 83 | (contains-const? var-name alias-info node))) |
86 | 84 |
|
87 | 85 | (defn- find-symbol-in-ast [name asts] |
|
103 | 101 | (str/join "\n") |
104 | 102 | str/trim))) |
105 | 103 |
|
106 | | -(defn- find-symbol-in-file [fully-qualified-name ignore-errors ^File file] |
| 104 | +(defn- find-symbol-in-file [fully-qualified-name ignore-errors referred-syms ^File file] |
107 | 105 | (let [file-content (slurp file) |
108 | 106 | locs (try (->> (ana/ns-ast file-content) |
109 | 107 | (find-symbol-in-ast fully-qualified-name) |
110 | 108 | (filter :line-beg)) |
111 | 109 | (catch Exception e |
112 | 110 | (when-not ignore-errors |
113 | 111 | (throw e)))) |
114 | | - locs (concat locs |
115 | | - (some-> |
116 | | - (libspecs/referred-syms-by-file&fullname) |
117 | | - (get-in [:clj (str file) fully-qualified-name]) |
118 | | - meta |
119 | | - ((fn [{:keys [line column end-line end-column]}] |
120 | | - (list {:line-beg line |
121 | | - :line-end end-line |
122 | | - :col-beg column |
123 | | - :col-end end-column}))))) |
| 112 | + locs (into |
| 113 | + locs (some-> |
| 114 | + referred-syms |
| 115 | + (get-in [:clj (str file) fully-qualified-name]) |
| 116 | + meta |
| 117 | + ((fn [{:keys [line column end-line end-column]}] |
| 118 | + (list {:line-beg line |
| 119 | + :line-end end-line |
| 120 | + :col-beg column |
| 121 | + :col-end end-column}))))) |
124 | 122 | gather (fn [info] |
125 | 123 | (merge info |
126 | 124 | {:file (.getCanonicalPath file) |
|
134 | 132 | (let [namespace (or ns (core/ns-from-string (slurp file))) |
135 | 133 | fully-qualified-name (if (= namespace "clojure.core") |
136 | 134 | var-name |
137 | | - (str/join "/" [namespace var-name]))] |
| 135 | + (str/join "/" [namespace var-name])) |
| 136 | + referred-syms (libspecs/referred-syms-by-file&fullname)] |
138 | 137 | (->> (core/dirs-on-classpath) |
139 | 138 | (mapcat (partial core/find-in-dir (some-fn core/clj-file? core/cljc-file?))) |
140 | | - (mapcat (partial find-symbol-in-file fully-qualified-name ignore-errors))))) |
| 139 | + (mapcat (partial find-symbol-in-file fully-qualified-name ignore-errors referred-syms))))) |
141 | 140 |
|
142 | 141 | (defn- get&read-enclosing-sexps |
143 | 142 | [file-content {:keys [^long line-beg ^long col-beg]}] |
|
165 | 164 | res))) |
166 | 165 |
|
167 | 166 | (defn- occurrence-for-optmap-default |
168 | | - [var-name [{:keys [line-beg col-beg] :as orig-occurrence} [_ _ ^String level2-string _]]] |
| 167 | + [var-name [orig-occurrence [_ _ ^String level2-string _]]] |
169 | 168 | (let [var-positions (re-pos (re-pattern (format "\\W%s\\W" var-name)) level2-string) |
170 | 169 | ^long var-default-pos (first (second var-positions)) |
171 | 170 | newline-cnt (reduce (fn [cnt char] (if (= char \newline) (inc (long cnt)) cnt)) 0 (.substring level2-string 0 var-default-pos)) |
|
228 | 227 | (map (partial occurrence-for-optmap-default var-name)))] |
229 | 228 | (sort-by :line-beg (concat local-occurrences optmap-def-occurrences)))))) |
230 | 229 |
|
231 | | -(defn- to-find-symbol-result |
232 | | - [{:keys [line-beg line-end col-beg col-end name file match]}] |
233 | | - [line-beg line-end col-beg col-end name file match]) |
234 | | - |
235 | 230 | (defn find-symbol [{:keys [file ns name line column ignore-errors]}] |
236 | 231 | (core/throw-unless-clj-file file) |
237 | 232 | (let [ignore-errors? (= ignore-errors "true") |
|
240 | 235 | distinct |
241 | 236 | (remove find-util/spurious?) |
242 | 237 | future)] |
| 238 | + |
243 | 239 | (or |
244 | 240 | ;; find-local-symbol is the fastest of the three |
245 | | - (not-empty (remove find-util/spurious? (distinct (find-local-symbol file name line column)))) |
| 241 | + ;; if result is not empty, there is no point in keeping `find-macro` and `find-global-symbol` futures still active |
| 242 | + (when-let [result (not-empty (remove find-util/spurious? (distinct (find-local-symbol file name line column))))] |
| 243 | + (future-cancel macros) |
| 244 | + (future-cancel globals) |
| 245 | + result) |
| 246 | + |
246 | 247 | ;; find-macros has to be checked first because find-global-symbol |
247 | 248 | ;; can return spurious hits for some macro definitions |
248 | 249 | @macros |
|
0 commit comments