-
Notifications
You must be signed in to change notification settings - Fork 0
/
delegate.clj
34 lines (31 loc) · 1.37 KB
/
delegate.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
(ns unixsocket-http.impl.delegate
(:import [java.lang.reflect Method Modifier]))
(defn is-public-instance-method?
[^Method method]
(let [modifiers (.getModifiers method)]
(and (Modifier/isPublic modifiers)
(not (Modifier/isStatic modifiers)))))
(defmacro delegate
"Used inside a `:gen-class` namespace this macro will generate all
method definitions of `class`, delegating calls to the value
returned by `via`.
You can set up exclusions using `except`."
[{:keys [class via except additional]}]
(let [include? (complement (set except))
class (Class/forName (str class))]
`(do
~@(for [^Method method (.getDeclaredMethods class)
:when (is-public-instance-method? method)
:let [method-name (.getName method)
method-sym (symbol method-name)
method-fn-sym (symbol (str "-" method-name))
args (->> (.getParameterTypes method)
(map
(fn [^Class c]
(with-meta
(gensym (.getSimpleName c))
{:type (symbol (.getName c))}))))]
:when (include? method-sym)]
`(defn ~method-fn-sym
[~'this ~@args]
(. (~via ~'this) ~method-sym ~@args))))))