PageRenderTime 49ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/src/swank/commands/xref.clj

http://github.com/technomancy/swank-clojure
Clojure | 52 lines | 45 code | 5 blank | 2 comment | 2 complexity | d45da13eea1a3ad4f621212340e84229 MD5 | raw file
Possible License(s): EPL-1.0
  1. (ns swank.commands.xref
  2. (:use clojure.walk swank.util)
  3. (:import (clojure.lang RT)
  4. (java.io LineNumberReader InputStreamReader Reader PushbackReader)))
  5. ;; Yoinked and modified from clojure.contrib.repl-utils.
  6. ;; Now takes a var instead of a sym in the current ns
  7. (defn- get-source-from-var
  8. "Returns a string of the source code for the given symbol, if it can
  9. find it. This requires that the symbol resolve to a Var defined in
  10. a namespace for which the .clj is in the classpath. Returns nil if
  11. it can't find the source.
  12. Example: (get-source-from-var 'filter)"
  13. [v] (when-let [filepath (:file (meta v))]
  14. (when-let [strm (.getResourceAsStream (RT/baseLoader) filepath)]
  15. (with-open [rdr (LineNumberReader. (InputStreamReader. strm))]
  16. (dotimes [_ (dec (:line (meta v)))] (.readLine rdr))
  17. (let [text (StringBuilder.)
  18. pbr (proxy [PushbackReader] [rdr]
  19. (read [] (let [#^Reader this this
  20. i (proxy-super read)]
  21. (.append text (char i))
  22. i)))]
  23. (read (PushbackReader. pbr))
  24. (str text))))))
  25. (defn- recursive-contains? [coll obj]
  26. "True if coll contains obj. Obj can't be a seq"
  27. (not (empty? (filter #(= obj %) (flatten coll)))))
  28. (defn- does-var-call-fn [var fn]
  29. "Checks if a var calls a function named 'fn"
  30. (if-let [source (get-source-from-var var)]
  31. (let [node (read-string source)]
  32. (if (recursive-contains? node fn)
  33. var
  34. false))))
  35. (defn- does-ns-refer-to-var? [ns var]
  36. (ns-resolve ns var))
  37. (defn all-vars-who-call [sym]
  38. (filter
  39. ifn?
  40. (filter
  41. #(identity %)
  42. (map #(does-var-call-fn % sym)
  43. (flatten
  44. (map vals
  45. (map ns-interns
  46. (filter #(does-ns-refer-to-var? % sym)
  47. (all-ns)))))))))