Skip to content

Commit dbb0e36

Browse files
author
sogaiu
committed
Add clj-kondo hooks
1 parent 91f58f7 commit dbb0e36

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{:hooks
2+
{:analyze-call {libpython-clj.jna.base/def-pylib-fn
3+
hooks.libpython-clj.jna.base.def-pylib-fn/def-pylib-fn
4+
libpython-clj.require/import-python
5+
hooks.libpython-clj.require.import-python/import-python}}
6+
:linters {:unused-namespace {:exclude [builtins.list
7+
builtins.dict
8+
builtins.set
9+
builtins.tuple
10+
builtins.frozenset
11+
builtins.str
12+
builtins]}}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
;; XXX: work on export-symbols from tech.parallel.utils?
2+
(ns hooks.libpython-clj.jna.base.def-pylib-fn
3+
"The def-pylib-fn macro from libpython-clj/jna/base.clj"
4+
(:require [clj-kondo.hooks-api :as api]))
5+
6+
;; from: libpython-clj/jna/base.clj
7+
8+
;; (defmacro def-pylib-fn
9+
;; [fn-name docstring rettype & argpairs]
10+
;; `(defn ~fn-name
11+
;; ~docstring
12+
;; ~(mapv first argpairs)
13+
;; (when-not (== (current-thread-id) (.get ^AtomicLong gil-thread-id))
14+
;; (throw (Exception. "Failure to capture gil when calling into libpython")))
15+
;; (let [~'tvm-fn (jna/find-function ~(str fn-name) *python-library*)
16+
;; ~'fn-args (object-array
17+
;; ~(mapv (fn [[arg-symbol arg-coersion]]
18+
;; (when (= arg-symbol arg-coersion)
19+
;; (throw (ex-info (format "Argument symbol (%s) cannot match coersion (%s)"
20+
;; arg-symbol arg-coersion)
21+
;; {})))
22+
;; `(~arg-coersion ~arg-symbol))
23+
;; argpairs))]
24+
;; ~(if rettype
25+
;; `(.invoke (jna-base/to-typed-fn ~'tvm-fn) ~rettype ~'fn-args)
26+
;; `(.invoke (jna-base/to-typed-fn ~'tvm-fn) ~'fn-args)))))
27+
28+
;; called like:
29+
30+
;; (def-pylib-fn PyImport_AddModule
31+
;; "Return value: Borrowed reference.
32+
;;
33+
;; Similar to PyImport_AddModuleObject(), but the name is a UTF-8 encoded string instead
34+
;; of a Unicode object."
35+
;; Pointer
36+
;; [name str])
37+
38+
(defn def-pylib-fn
39+
"Macro in libpython-clj/jna/base.clj.
40+
41+
Example call:
42+
43+
(def-pylib-fn PyImport_AddModule
44+
\"Return value: Borrowed reference.
45+
46+
Similar to PyImport_AddModuleObject(), but the name is a UTF-8 ...
47+
of a Unicode object.\"
48+
Pointer
49+
[name str])
50+
51+
This has the form:
52+
53+
(def-pylib-fn fn-name docstring rettype & argpairs)
54+
55+
May be treating it as:
56+
57+
(defn fn-name
58+
[arg1 arg2 ,,, argn]
59+
[arg1 arg2 ,,, argn]) ; fake usage of args?
60+
61+
where arg1, ..., argn are extracted from argpairs is acceptable.
62+
63+
XXX: using the second elements of argpairs might be worth doing
64+
to avoid unused warnings.
65+
66+
"
67+
[{:keys [:node]}]
68+
(let [[_ fn-name _ _ & argpairs] (:children node)
69+
pairs (map (fn [vec-node]
70+
(let [[an-arg a-type] (:children vec-node)]
71+
[an-arg a-type]))
72+
argpairs)
73+
new-node (with-meta (api/list-node
74+
(apply concat
75+
[(api/token-node 'defn)
76+
fn-name
77+
(api/vector-node (map first pairs))]
78+
pairs))
79+
(meta node))]
80+
;; XXX: uncomment following and run clj-kondo on cl_format.clj to debug
81+
;;(prn (api/sexpr node))
82+
;;(prn (api/sexpr new-node))
83+
{:node new-node}))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
(ns hooks.libpython-clj.require.import-python
2+
"The import-python macro from libpython-clj/require.clj"
3+
(:require [clj-kondo.hooks-api :as api]))
4+
5+
;; from: libpython-clj/require.clj
6+
7+
;; (defn import-python
8+
;; "Loads python, python.list, python.dict, python.set, python.tuple,
9+
;; and python.frozenset."
10+
;; []
11+
;; (require-python
12+
;; '(builtins
13+
;; [list :as python.list]
14+
;; [dict :as python.dict]
15+
;; [set :as python.set]
16+
;; [tuple :as python.tuple]
17+
;; [frozenset :as python.frozenset]
18+
;; [str :as python.str])
19+
;; '[builtins :as python])
20+
;; :ok)
21+
22+
;; alternative:
23+
;;
24+
;; (require
25+
;; (quote [builtins.list :as python.list])
26+
;; (quote [builtins.dict :as python.dict])
27+
;; (quote [builtins.set :as python.set])
28+
;; (quote [builtins.tuple :as python.tuple])
29+
;; (quote [builtins.frozenset :as python.frozenset])
30+
;; (quote [builtins.str :as python.str])
31+
;; (quote [builtins :as python]))
32+
33+
(defn make-require
34+
[ns-sym alias-sym]
35+
(api/list-node
36+
[(api/token-node 'require)
37+
(api/list-node
38+
[(api/token-node 'quote)
39+
(api/vector-node
40+
[(api/token-node ns-sym)
41+
(api/keyword-node :as)
42+
(api/token-node alias-sym)])])]))
43+
44+
(defn import-python
45+
"Macro in libpython-clj/require.clj.
46+
47+
Example call:
48+
49+
(import-python)
50+
51+
May be treating it as:
52+
53+
(do
54+
(require (quote [builtins.list :as python.list]))
55+
(require (quote [builtins.dict :as python.dict]))
56+
,,,
57+
)
58+
59+
"
60+
[{:keys [:node]}]
61+
(let [new-node
62+
(with-meta (api/list-node
63+
[(api/token-node 'do)
64+
(make-require 'builtins.list 'python.list)
65+
(make-require 'builtins.dict 'python.dict)
66+
(make-require 'builtins.set 'python.set)
67+
(make-require 'builtins.tuple 'python.tuple)
68+
(make-require 'builtins.frozenset 'python.frozenset)
69+
(make-require 'builtins.str 'python.str)
70+
(make-require 'builtins 'python)])
71+
(meta node))]
72+
;; XXX: uncomment following and run clj-kondo on cl_format.clj to debug
73+
;;(prn (api/sexpr node))
74+
;;(prn (api/sexpr new-node))
75+
{:node new-node}))

0 commit comments

Comments
 (0)