Skip to content

Commit dbb9fad

Browse files
[info] Recognize Clojure vars printed as munged classes and methods
1 parent bf41648 commit dbb9fad

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

src/orchard/info.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
(m/special-sym-meta sym)
6464
;; it's a var
6565
(some-> ns (m/resolve-var sym) (m/var-meta var-meta-allowlist))
66+
;; it's a munged printed var or .invoke method of a Clojure function
67+
(some-> (m/resolve-munged-printed-var sym) (m/var-meta var-meta-allowlist))
6668
;; it's a Java class/constructor/member symbol
6769
(some-> ns (java/resolve-symbol sym))
6870
;; it's an alias for another ns

src/orchard/meta.clj

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
[orchard.namespace :as ns]
1212
[orchard.spec :as spec])
1313
(:import
14-
(clojure.lang LineNumberingPushbackReader Namespace Var)))
14+
(clojure.lang Compiler LineNumberingPushbackReader Namespace Var)))
1515

1616
;;; ## Extractors
1717

@@ -119,6 +119,26 @@
119119
(when-let [ns (find-ns ns)]
120120
(ns-aliases ns)))
121121

122+
(defn resolve-munged-printed-var
123+
"Given a printed munged representation of Clojure function, try to resolve it as
124+
a var. Supports the following representations:
125+
- clojure.core$str
126+
- clojure.core$str.invoke
127+
- clojure.main$repl$fn__9119.invoke (resolves to named var, not internal lambda)
128+
- some.ns$eval1234$closing_over_fn__12345.invoke"
129+
[sym]
130+
(let [demunged (-> (Compiler/demunge (str sym))
131+
(string/replace #"--\d+" ""))
132+
[_ wo-method] (re-matches #"(.+?)(?:\.(?:invoke|invokeStatic|doInvoke))?"
133+
demunged)
134+
[ns-str name-str] (->> (string/split wo-method #"/")
135+
(remove #(re-matches #"eval\d+" %)))
136+
ns (some-> ns-str symbol find-ns)
137+
resolved (when (and ns name-str)
138+
(ns-resolve ns (symbol name-str)))]
139+
(when (var? resolved)
140+
resolved)))
141+
122142
;; Even if things like catch or finally aren't clojure special
123143
;; symbols we want to be able to talk about them.
124144
;; They just map to a special symbol.

test/orchard/info_test.clj

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,23 @@
191191
(select-keys [:ns :name :arglists :doc])
192192
(update :ns ns-name))))))))
193193

194+
(let [a 1]
195+
(defn- closed-over [] a))
196+
197+
(deftest info-munged-printed-var-test
198+
(is (= 'str
199+
(:name (info/info 'orchard.test-ns 'clojure.core$str))))
200+
(is (= 'str
201+
(:name (info/info 'orchard.test-ns 'clojure.core$str.invoke))))
202+
(is (= 'str
203+
(:name (info/info 'orchard.test-ns 'clojure.core$str$fn__12.doInvoke))))
204+
(is (= 'str
205+
(:name (info/info 'orchard.test-ns (symbol "clojure.core/str/fn--12")))))
206+
(is (= 'closed-over
207+
(:name (info/info 'orchard.test-ns 'orchard.info_test$eval17939$closed_over__17940.invokeStatic))))
208+
(is (= 'closed-over
209+
(:name (info/info 'orchard.test-ns (symbol "orchard.info-test/eval17939/closed_over--17940"))))))
210+
194211
(deftest info-unqualified-sym-and-namespace-test
195212
(testing "Resolution from current namespace"
196213
(when cljs-available?
@@ -410,13 +427,13 @@
410427

411428
(when cljs-available?
412429
(testing "- :cljs"
413-
(is (= (take 3 (repeat expected))
430+
(is (= (repeat 3 expected)
414431
(->> params
415432
(map #(info/info* (merge @*cljs-params* %)))
416433
(map #(select-keys % [:ns :name :arglists :macro :file])))))))
417434

418435
(testing "- :clj"
419-
(is (= [{}, expected, {}]
436+
(is (= (repeat 3 expected)
420437
(->> params
421438
(map #(info/info* %))
422439
(map #(select-keys % [:ns :name :arglists :macro :file])))))))))

0 commit comments

Comments
 (0)