Skip to content

Commit

Permalink
Add clj-kondo hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
sogaiu committed Nov 7, 2020
1 parent 91f58f7 commit dbb0e36
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 0 deletions.
13 changes: 13 additions & 0 deletions resources/clj-kondo.exports/clj-python/libpython-clj/config.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{:hooks
{:analyze-call {libpython-clj.jna.base/def-pylib-fn
hooks.libpython-clj.jna.base.def-pylib-fn/def-pylib-fn
libpython-clj.require/import-python
hooks.libpython-clj.require.import-python/import-python}}
:linters {:unused-namespace {:exclude [builtins.list
builtins.dict
builtins.set
builtins.tuple
builtins.frozenset
builtins.str
builtins]}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
;; XXX: work on export-symbols from tech.parallel.utils?
(ns hooks.libpython-clj.jna.base.def-pylib-fn
"The def-pylib-fn macro from libpython-clj/jna/base.clj"
(:require [clj-kondo.hooks-api :as api]))

;; from: libpython-clj/jna/base.clj

;; (defmacro def-pylib-fn
;; [fn-name docstring rettype & argpairs]
;; `(defn ~fn-name
;; ~docstring
;; ~(mapv first argpairs)
;; (when-not (== (current-thread-id) (.get ^AtomicLong gil-thread-id))
;; (throw (Exception. "Failure to capture gil when calling into libpython")))
;; (let [~'tvm-fn (jna/find-function ~(str fn-name) *python-library*)
;; ~'fn-args (object-array
;; ~(mapv (fn [[arg-symbol arg-coersion]]
;; (when (= arg-symbol arg-coersion)
;; (throw (ex-info (format "Argument symbol (%s) cannot match coersion (%s)"
;; arg-symbol arg-coersion)
;; {})))
;; `(~arg-coersion ~arg-symbol))
;; argpairs))]
;; ~(if rettype
;; `(.invoke (jna-base/to-typed-fn ~'tvm-fn) ~rettype ~'fn-args)
;; `(.invoke (jna-base/to-typed-fn ~'tvm-fn) ~'fn-args)))))

;; called like:

;; (def-pylib-fn PyImport_AddModule
;; "Return value: Borrowed reference.
;;
;; Similar to PyImport_AddModuleObject(), but the name is a UTF-8 encoded string instead
;; of a Unicode object."
;; Pointer
;; [name str])

(defn def-pylib-fn
"Macro in libpython-clj/jna/base.clj.
Example call:
(def-pylib-fn PyImport_AddModule
\"Return value: Borrowed reference.
Similar to PyImport_AddModuleObject(), but the name is a UTF-8 ...
of a Unicode object.\"
Pointer
[name str])
This has the form:
(def-pylib-fn fn-name docstring rettype & argpairs)
May be treating it as:
(defn fn-name
[arg1 arg2 ,,, argn]
[arg1 arg2 ,,, argn]) ; fake usage of args?
where arg1, ..., argn are extracted from argpairs is acceptable.
XXX: using the second elements of argpairs might be worth doing
to avoid unused warnings.
"
[{:keys [:node]}]
(let [[_ fn-name _ _ & argpairs] (:children node)
pairs (map (fn [vec-node]
(let [[an-arg a-type] (:children vec-node)]
[an-arg a-type]))
argpairs)
new-node (with-meta (api/list-node
(apply concat
[(api/token-node 'defn)
fn-name
(api/vector-node (map first pairs))]
pairs))
(meta node))]
;; XXX: uncomment following and run clj-kondo on cl_format.clj to debug
;;(prn (api/sexpr node))
;;(prn (api/sexpr new-node))
{:node new-node}))
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
(ns hooks.libpython-clj.require.import-python
"The import-python macro from libpython-clj/require.clj"
(:require [clj-kondo.hooks-api :as api]))

;; from: libpython-clj/require.clj

;; (defn import-python
;; "Loads python, python.list, python.dict, python.set, python.tuple,
;; and python.frozenset."
;; []
;; (require-python
;; '(builtins
;; [list :as python.list]
;; [dict :as python.dict]
;; [set :as python.set]
;; [tuple :as python.tuple]
;; [frozenset :as python.frozenset]
;; [str :as python.str])
;; '[builtins :as python])
;; :ok)

;; alternative:
;;
;; (require
;; (quote [builtins.list :as python.list])
;; (quote [builtins.dict :as python.dict])
;; (quote [builtins.set :as python.set])
;; (quote [builtins.tuple :as python.tuple])
;; (quote [builtins.frozenset :as python.frozenset])
;; (quote [builtins.str :as python.str])
;; (quote [builtins :as python]))

(defn make-require
[ns-sym alias-sym]
(api/list-node
[(api/token-node 'require)
(api/list-node
[(api/token-node 'quote)
(api/vector-node
[(api/token-node ns-sym)
(api/keyword-node :as)
(api/token-node alias-sym)])])]))

(defn import-python
"Macro in libpython-clj/require.clj.
Example call:
(import-python)
May be treating it as:
(do
(require (quote [builtins.list :as python.list]))
(require (quote [builtins.dict :as python.dict]))
,,,
)
"
[{:keys [:node]}]
(let [new-node
(with-meta (api/list-node
[(api/token-node 'do)
(make-require 'builtins.list 'python.list)
(make-require 'builtins.dict 'python.dict)
(make-require 'builtins.set 'python.set)
(make-require 'builtins.tuple 'python.tuple)
(make-require 'builtins.frozenset 'python.frozenset)
(make-require 'builtins.str 'python.str)
(make-require 'builtins 'python)])
(meta node))]
;; XXX: uncomment following and run clj-kondo on cl_format.clj to debug
;;(prn (api/sexpr node))
;;(prn (api/sexpr new-node))
{:node new-node}))

0 comments on commit dbb0e36

Please sign in to comment.