|
21 | 21 | (:require [clojure.repl :as repl]
|
22 | 22 | [clojure.pprint]
|
23 | 23 | [clojure.java.io :as io]
|
24 |
| - [clojure.string :as str]) |
| 24 | + [clojure.string :as str] |
| 25 | + [clojure.tools.namespace.file :as nfile] |
| 26 | + [clojure.tools.namespace.find :as nf] |
| 27 | + [clojure.java.classpath :as cp]) |
25 | 28 | (:import
|
26 | 29 | (java.io File LineNumberReader InputStreamReader
|
27 | 30 | PushbackReader FileInputStream)
|
| 31 | + (java.util.jar JarFile) |
28 | 32 | (clojure.lang RT)))
|
29 | 33 |
|
30 | 34 | (defmacro xcond
|
@@ -407,9 +411,11 @@ malleable to refactoring."
|
407 | 411 | (xcond
|
408 | 412 | ((nil? idx)
|
409 | 413 | expr)
|
| 414 | + |
410 | 415 | ;; [x |(+ 1 2) y (+ 3 4)] => {:x 3}
|
411 |
| - ;; TODO: would be better to have 1 level higher context, so that we just check |
412 |
| - ;; (= (first context) 'let) |
| 416 | + ((and (= (first context) 'let) (= idx 1)) |
| 417 | + (shadow-dest expr)) |
| 418 | + |
413 | 419 | ((and (vector? context)
|
414 | 420 | (= 0 (rem (count context) 2))
|
415 | 421 | (= 0 (rem (inc idx) 2))
|
@@ -508,10 +514,47 @@ malleable to refactoring."
|
508 | 514 | f
|
509 | 515 | (. (io/resource f) getPath)))
|
510 | 516 |
|
| 517 | +(defonce ns-to-jar (atom {})) |
| 518 | + |
| 519 | +(defn ns-location [sym] |
| 520 | + (when (empty? @ns-to-jar) |
| 521 | + (reset! ns-to-jar |
| 522 | + (apply hash-map |
| 523 | + (->> |
| 524 | + (cp/classpath) |
| 525 | + (mapcat #(interleave |
| 526 | + (if (. % isFile) |
| 527 | + (nf/find-namespaces-in-jarfile (JarFile. %)) |
| 528 | + (nf/find-namespaces-in-dir % nil)) |
| 529 | + (repeat %))))))) |
| 530 | + (let [dir (get @ns-to-jar sym)] |
| 531 | + (if (. dir isFile) |
| 532 | + (let [jf (JarFile. dir) |
| 533 | + file-in-jar (first |
| 534 | + (filter |
| 535 | + (fn [f] |
| 536 | + (let [entry (nf/read-ns-decl-from-jarfile-entry jf f nil)] |
| 537 | + (when (and entry (= (first entry) sym)) |
| 538 | + f))) |
| 539 | + (nf/clojure-sources-in-jar jf)))] |
| 540 | + (list |
| 541 | + (str "file:" dir "!/" file-in-jar) |
| 542 | + 0)) |
| 543 | + (let [file-in-dir (first |
| 544 | + (filter |
| 545 | + (fn [f] |
| 546 | + (let [decl (nfile/read-file-ns-decl f nil)] |
| 547 | + (and decl (= (first decl) sym) |
| 548 | + f))) |
| 549 | + (nf/find-clojure-sources-in-dir dir)))] |
| 550 | + (list (.getCanonicalPath file-in-dir) 0))))) |
| 551 | + |
511 | 552 | (defn location [sym]
|
512 | 553 | (let [rs (resolve sym)
|
513 | 554 | m (meta rs)]
|
514 |
| - (xcond ((:l-file m) |
| 555 | + (xcond |
| 556 | + ((and (nil? rs) (ns-location sym))) |
| 557 | + ((:l-file m) |
515 | 558 | (list (:l-file m) (:l-line m)))
|
516 | 559 | ((and (:file m) (not (re-matches #"^/tmp/" (:file m))))
|
517 | 560 | (list (file->elisp (:file m)) (:line m))))))
|
|
0 commit comments