From dbb0e36a5211cfbfac9a34c4eb5d973f55d2c61c Mon Sep 17 00:00:00 2001 From: sogaiu <983021772@users.noreply.github.com> Date: Sat, 7 Nov 2020 10:32:34 +0900 Subject: [PATCH] Add clj-kondo hooks --- .../clj-python/libpython-clj/config.edn | 13 +++ .../libpython_clj/jna/base/def_pylib_fn.clj | 83 +++++++++++++++++++ .../libpython_clj/require/import_python.clj | 75 +++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 resources/clj-kondo.exports/clj-python/libpython-clj/config.edn create mode 100644 resources/clj-kondo.exports/clj-python/libpython-clj/hooks/libpython_clj/jna/base/def_pylib_fn.clj create mode 100644 resources/clj-kondo.exports/clj-python/libpython-clj/hooks/libpython_clj/require/import_python.clj diff --git a/resources/clj-kondo.exports/clj-python/libpython-clj/config.edn b/resources/clj-kondo.exports/clj-python/libpython-clj/config.edn new file mode 100644 index 0000000..cab3e49 --- /dev/null +++ b/resources/clj-kondo.exports/clj-python/libpython-clj/config.edn @@ -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]}} +} diff --git a/resources/clj-kondo.exports/clj-python/libpython-clj/hooks/libpython_clj/jna/base/def_pylib_fn.clj b/resources/clj-kondo.exports/clj-python/libpython-clj/hooks/libpython_clj/jna/base/def_pylib_fn.clj new file mode 100644 index 0000000..bac1e09 --- /dev/null +++ b/resources/clj-kondo.exports/clj-python/libpython-clj/hooks/libpython_clj/jna/base/def_pylib_fn.clj @@ -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})) diff --git a/resources/clj-kondo.exports/clj-python/libpython-clj/hooks/libpython_clj/require/import_python.clj b/resources/clj-kondo.exports/clj-python/libpython-clj/hooks/libpython_clj/require/import_python.clj new file mode 100644 index 0000000..c6089d3 --- /dev/null +++ b/resources/clj-kondo.exports/clj-python/libpython-clj/hooks/libpython_clj/require/import_python.clj @@ -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}))