Skip to content

Commit 9f4db3b

Browse files
committed
wip
1 parent 319bcdc commit 9f4db3b

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

test/compojure/api/dev/gen.clj

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
(ns compojure.api.dev.gen
2+
(:require [clojure.string :as str]
3+
[clojure.set :as set]
4+
[clojure.walk :as walk]))
5+
6+
(def impl-local-sym '+impl+)
7+
8+
(defn normalize-argv [argv]
9+
{:post [(or (empty? %)
10+
(apply distinct? %))
11+
(not-any? #{impl-local-sym} %)]}
12+
(into [] (map-indexed (fn [i arg]
13+
(if (symbol? arg)
14+
(do (assert (not (namespace arg)))
15+
(if (some #(Character/isDigit (char %)) (name arg))
16+
(symbol (apply str (concat
17+
(remove #(Character/isDigit (char %)) (name arg))
18+
[i])))
19+
arg))
20+
(symbol (str "arg" i)))))
21+
argv))
22+
23+
(defn normalize-arities [arities]
24+
(cond-> arities
25+
(= 1 (count arities)) first))
26+
27+
(defn import-fn [sym]
28+
{:pre [(namespace sym)]}
29+
(let [vr (find-var sym)
30+
m (meta vr)
31+
n (:name m)
32+
arglists (:arglists m)
33+
protocol (:protocol m)
34+
when-class (-> sym meta :when-class)
35+
_ (assert (not when-class))
36+
forward-meta (into (sorted-map) (select-keys m [:tag :arglists :doc :deprecated]))
37+
_ (assert (not= n impl-local-sym))
38+
_ (when (:macro m)
39+
(throw (IllegalArgumentException.
40+
(str "Calling import-fn on a macro: " sym))))
41+
form (if protocol
42+
(list* 'defn (with-meta n (dissoc forward-meta :arglists))
43+
(map (fn [argv]
44+
{:pre [(not-any? #{'&} argv)]}
45+
(list argv (list* sym argv)))
46+
arglists))
47+
(list 'def (with-meta n forward-meta) sym))]
48+
(cond->> form
49+
#_#_when-class (list 'java-time.util/when-class when-class))))
50+
51+
(defn import-macro [sym]
52+
(let [vr (find-var sym)
53+
m (meta vr)
54+
_ (when-not (:macro m)
55+
(throw (IllegalArgumentException.
56+
(str "Calling import-macro on a non-macro: " sym))))
57+
n (:name m)
58+
arglists (:arglists m)]
59+
(list* 'defmacro n
60+
(concat
61+
(some-> (not-empty (into (sorted-map) (select-keys m [:doc :deprecated])))
62+
list)
63+
(normalize-arities
64+
(map (fn [argv]
65+
(let [argv (normalize-argv argv)]
66+
(list argv
67+
(if (some #{'&} argv)
68+
(list* 'list* (list 'quote sym) (remove #{'&} argv))
69+
(list* 'list (list 'quote sym) argv)))))
70+
arglists))))))
71+
72+
(defn import-vars
73+
"Imports a list of vars from other namespaces."
74+
[& syms]
75+
(let [unravel (fn unravel [x]
76+
(if (sequential? x)
77+
(->> x
78+
rest
79+
(mapcat unravel)
80+
(map
81+
#(with-meta
82+
(symbol
83+
(str (first x)
84+
(when-let [n (namespace %)]
85+
(str "." n)))
86+
(name %))
87+
(meta %))))
88+
[x]))
89+
syms (mapcat unravel syms)]
90+
(map (fn [sym]
91+
(let [vr (if-some [rr (resolve 'clojure.core/requiring-resolve)]
92+
(rr sym)
93+
(do (require (-> sym namespace symbol))
94+
(resolve sym)))
95+
_ (assert vr (str sym " is unresolvable"))
96+
m (meta vr)]
97+
(if (:macro m)
98+
(import-macro sym)
99+
(import-fn sym))))
100+
syms)))
101+
102+
(def impl-info
103+
{:vars '([compojure.api.core routes defroutes let-routes undocumented middleware
104+
context GET ANY HEAD PATCH DELETE OPTIONS POST PUT]
105+
[compojure.api.api api defapi]
106+
[compojure.api.resource resource]
107+
[compojure.api.routes path-for]
108+
[compojure.api.swagger swagger-routes]
109+
[ring.swagger.json-schema describe])})
110+
111+
(defn gen-compojure-api-sweet-ns-forms [nsym]
112+
(let [require-macros (into #{} (map first) (:macros impl-info))]
113+
(concat
114+
[";; NOTE: This namespace is generated by compojure.api.dev.gen"
115+
`(~'ns ~nsym
116+
(:require compojure.api.core
117+
compojure.api.api
118+
compojure.api.routes
119+
compojure.api.resource
120+
compojure.api.swagger
121+
ring.swagger.json-schema))]
122+
(apply import-vars (:vars impl-info)))))
123+
124+
(defn print-form [form]
125+
(with-bindings
126+
(cond-> {#'*print-meta* true
127+
#'*print-length* nil
128+
#'*print-level* nil}
129+
(resolve '*print-namespace-maps*)
130+
(assoc (resolve '*print-namespace-maps*) false))
131+
(cond
132+
(string? form) (println form)
133+
:else (println (pr-str (walk/postwalk
134+
(fn [v]
135+
(if (meta v)
136+
(if (symbol? v)
137+
(vary-meta v #(not-empty
138+
(cond-> (sorted-map)
139+
(some? (:tag %)) (assoc :tag (:tag %))
140+
(some? (:doc %)) (assoc :doc (:doc %))
141+
((some-fn true? string?) (:deprecated %)) (assoc :deprecated (:deprecated %))
142+
(string? (:superseded-by %)) (assoc :superseded-by (:superseded-by %))
143+
(string? (:supercedes %)) (assoc :supercedes (:supercedes %))
144+
(some? (:arglists %)) (assoc :arglists (list 'quote (doall (map normalize-argv (:arglists %))))))))
145+
(with-meta v nil))
146+
v))
147+
form)))))
148+
nil)
149+
150+
(defn print-compojure-api-ns [nsym]
151+
(run! print-form (gen-compojure-api-sweet-ns-forms nsym)))
152+
153+
(def compojure-api-sweet-nsym
154+
(with-meta
155+
'compojure.api.sweet
156+
;;TODO ns meta
157+
nil))
158+
159+
(def gen-source->nsym
160+
{"src/compojure/api/sweet.clj" compojure-api-sweet-nsym})
161+
162+
(defn spit-compojure-api-ns []
163+
(doseq [[source nsym] gen-source->nsym]
164+
(spit source (with-out-str (print-compojure-api-ns nsym)))))
165+
166+
(comment
167+
(print-compojure-api-ns compojure-api-sweet-nsym)
168+
(spit-compojure-api-ns)
169+
)

0 commit comments

Comments
 (0)