Skip to content

Commit bb06691

Browse files
CyrikLukas Domagala
andauthored
xref: fix AOT function lookup (#147)
Co-authored-by: Lukas Domagala <[email protected]>
1 parent 01c755e commit bb06691

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

src/orchard/xref.clj

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,18 @@
5757
{:added "0.5"}
5858
[v]
5959
(when-let [^clojure.lang.AFn v (to-fn v)]
60-
(let [f-class-name (-> v .getClass .getName)]
61-
;; this uses the implementation detail that the clojure compiler always
62-
;; prefixes names of lambdas with the name of its surrounding function class
63-
(into #{} (comp (filter (fn [[k _v]] (clojure.string/includes? k f-class-name)))
64-
(map (fn [[_k value]] (.get ^java.lang.ref.Reference value)))
65-
(mapcat fn-deps-class))
66-
class-cache))))
60+
(let [f-class-name (-> v .getClass .getName)
61+
;; this uses the implementation detail that the clojure compiler always
62+
;; prefixes names of lambdas with the name of its surrounding function class
63+
deps (into #{} (comp (filter (fn [[k _v]] (clojure.string/includes? k f-class-name)))
64+
(map (fn [[_k value]] (.get ^java.lang.ref.Reference value)))
65+
(mapcat fn-deps-class))
66+
class-cache)]
67+
;; if there's no deps the class is most likely AoT compiled,
68+
;; try to access it directly
69+
(if (empty? deps)
70+
(-> v .getClass fn-deps-class)
71+
deps))))
6772

6873
(defn fn-transitive-deps
6974
"Returns a set with all the functions invoked inside `v` or inside those functions.

test/orchard/xref_test.clj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
(testing "with a symbol"
2525
(is (= (xref/fn-deps 'orchard.xref-test/dummy-fn)
2626
#{#'clojure.core/map #'clojure.core/filter
27-
#'clojure.core/even? #'clojure.core/range #'orchard.xref-test/fn-dep}))))
27+
#'clojure.core/even? #'clojure.core/range #'orchard.xref-test/fn-dep})))
28+
(testing "AoT compiled functions return deps"
29+
(is (= #{#'clojure.core/conj}
30+
(xref/fn-deps reverse)))))
2831

2932
;; The mere presence of this var can reproduce a certain issue. See:
3033
;; https://github.com/clojure-emacs/orchard/issues/135#issuecomment-939731698
@@ -52,8 +55,12 @@
5255
(testing "basics"
5356
(let [expected #{#'orchard.xref-test/fn-deps-test #'orchard.xref-test/fn-dep #'clojure.core/even?
5457
#'clojure.core/filter #'orchard.xref-test/fn-transitive-dep #'clojure.core/map
55-
#'clojure.test/test-var #'clojure.core/range}]
58+
#'clojure.test/test-var #'clojure.core/range #'clojure.core/inc'}]
5659
(is (contains? expected #'orchard.xref-test/fn-transitive-dep)
5760
"Specifically includes `#'fn-transitive-dep`, which is a transitive dep of `#'dummy-fn` (via `#'fn-dep`)")
61+
(is (contains? expected #'clojure.core/inc')
62+
"Specifically includes `#'clojure.core/inc'`, which is a transitive dep of `#'dummy-fn`
63+
(via `#'clojure.core/range'`). Unlike other AoT compiled core transitive dependancies
64+
it gets found because its a non `:static` dependancy.")
5865
(is (= expected
5966
(xref/fn-transitive-deps dummy-fn))))))

0 commit comments

Comments
 (0)