-
-
Notifications
You must be signed in to change notification settings - Fork 290
/
hooks_api.clj
157 lines (129 loc) · 4.64 KB
/
hooks_api.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
(ns clj-kondo.hooks-api
(:require
[clj-kondo.impl.cache :as cache]
[clj-kondo.impl.findings :as findings]
[clj-kondo.impl.metadata :as meta]
[clj-kondo.impl.rewrite-clj.node :as node]
[clj-kondo.impl.rewrite-clj.parser :as parser]
[clj-kondo.impl.utils :as utils]
[clojure.pprint]
[sci.core :as sci])
(:refer-clojure :exclude [macroexpand]))
(defn- mark-generate [node]
(assoc node :clj-kondo.impl/generated true))
(defn parse-string [s]
(parser/parse-string s))
(defn keyword-node? [n]
(utils/keyword-node? n))
(def keyword-node
(comp mark-generate utils/keyword-node))
(defn string-node? [n]
(instance? clj_kondo.impl.rewrite_clj.node.string.StringNode n))
(def string-node
(comp mark-generate utils/string-node))
(defn token-node? [n]
(instance? clj_kondo.impl.rewrite_clj.node.token.TokenNode n))
(def token-node
(comp mark-generate utils/token-node))
(defn vector-node? [n]
(and (instance? clj_kondo.impl.rewrite_clj.node.seq.SeqNode n)
(identical? :vector (utils/tag n))))
(def vector-node (comp mark-generate utils/vector-node))
(def list-node? utils/list-node?)
(def list-node (comp mark-generate utils/list-node))
(defn map-node? [n]
(and (instance? clj_kondo.impl.rewrite_clj.node.seq.SeqNode n)
(identical? :map (utils/tag n))))
(def map-node (comp mark-generate utils/map-node))
(defn sexpr [expr]
(node/sexpr expr))
(defn tag [n]
(node/tag n))
(defn reg-finding! [m]
(let [ctx utils/*ctx*
filename (:filename ctx)]
(findings/reg-finding! ctx (assoc m :filename filename))))
(defn reg-keyword!
[k reg-by]
(utils/assoc-some k :reg reg-by))
(defn coerce [s-expr]
(node/coerce s-expr))
(defn- var-definitions
"Project cached analysis as a subset of public var-definitions."
[analysis]
(let [selected-keys [:ns :name
:fixed-arities :varargs-min-arity
:private :macro]]
(->> (dissoc analysis :filename :source)
(utils/map-vals #(select-keys % selected-keys)))))
(defn- ns-analysis*
"Adapt from-cache-1 to provide a uniform return format.
Unifies the format of cached information provided for each source
language."
[lang ns-sym]
(if (= lang :cljc)
(->> (dissoc
(cache/from-cache-1 (:cache-dir utils/*ctx*) :cljc ns-sym)
:filename
:source)
(utils/map-vals var-definitions))
(some->> (cache/from-cache-1 (:cache-dir utils/*ctx*) lang ns-sym)
var-definitions
(hash-map lang))))
(defn ns-analysis
"Return any cached analysis for the namespace identified by ns-sym.
Returns a map keyed by language keyword with values being maps of var
definitions keyed by defined symbol. The value for each symbol is a
subset of the values provide by the top level :analysis option."
([ns-sym] (ns-analysis ns-sym {}))
([ns-sym {:keys [lang]}]
(if lang
(ns-analysis* lang ns-sym)
(reduce
merge
{}
(map #(ns-analysis* % ns-sym) [:cljc :clj :cljs])))))
(def ^:dynamic *reload*)
(defn walk
[inner outer form]
(cond
(instance? clj_kondo.impl.rewrite_clj.node.protocols.Node form)
(outer (update form :children #(mapv inner %)))
:else (outer form)))
(defn prewalk
[f form]
(walk (partial prewalk f) identity (f form)))
(defn- annotate [node original-meta]
(let [!!last-meta (volatile! original-meta)]
(prewalk (fn [node]
(cond
(and (instance? clj_kondo.impl.rewrite_clj.node.seq.SeqNode node)
(identical? :list (utils/tag node)))
(if-let [m (meta node)]
(if-let [m (not-empty (select-keys m [:row :end-row :col :end-col]))]
(do (vreset! !!last-meta m)
(mark-generate node))
(-> (with-meta node
(merge @!!last-meta (meta node)))
mark-generate))
(-> (with-meta node
(merge @!!last-meta (meta node)))
mark-generate))
(instance? clj_kondo.impl.rewrite_clj.node.protocols.Node node)
(-> (with-meta node
(merge @!!last-meta (meta node)))
mark-generate)
:else node))
node)))
(defn macroexpand [macro node bindings]
(let [call (sexpr node)
args (rest call)
res (apply macro call bindings args)
coerced (coerce res)
annotated (annotate coerced (meta node))
lifted (meta/lift-meta-content2 utils/*ctx* annotated)]
;;
lifted))
(defn pprint [& args]
(binding [*out* @sci/out]
(apply clojure.pprint/pprint args)))