|
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