-
Notifications
You must be signed in to change notification settings - Fork 0
/
java.clj
152 lines (127 loc) · 5.53 KB
/
java.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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
(ns ^{:author "Jeremy Schoffen"
:doc "
Minimal api wrapping some of the `java.tools` apis providing java compilation utilities.
"}
fr.jeremyschoffen.mbt.alpha.core.compilation.java
(:require
[clojure.spec.alpha :as s]
[fr.jeremyschoffen.java.nio.alpha.file :as fs]
[fr.jeremyschoffen.mbt.alpha.core.jar.fs :as jar-fs]
[fr.jeremyschoffen.mbt.alpha.core.specs :as specs]
[fr.jeremyschoffen.mbt.alpha.utils :as u])
(:import
(javax.tools StandardJavaFileManager JavaCompiler ToolProvider)))
(u/pseudo-nss
classpath
compilation.java
compilation.java.file-manager)
;;----------------------------------------------------------------------------------------------------------------------
;; Finding java files
;;----------------------------------------------------------------------------------------------------------------------
(defn- find-java-files* [src]
(-> src
fs/walk
fs/realize
(->> (filter #(= "java" (fs/file-extention %))))))
(u/simple-fdef find-java-files*
specs/dir-path?
(s/coll-of fs/path?))
(defn project-files
"Use an indexed classpath to find all .java files src directories from inside the working directory.
See:
- [[fr.jeremyschoffen.mbt.alpha.core.classpath/indexed-classpath]]"
[{ i ::classpath/index}]
(-> i
::classpath/dir
(->> (into []
(comp
(map u/safer-path)
(mapcat find-java-files*))))))
(u/spec-op project-files
:param {:req [::classpath/index]}
:ret ::compilation.java/sources)
(defn external-files
"Use an indexed classpath to find all .java files from src directories located outside the working directory.\n These would be namespaces from local deps or directly from a git repo.
See:
- [[fr.jeremyschoffen.mbt.alpha.core.classpath/indexed-classpath]]."
[{ i ::classpath/index}]
(-> i
::classpath/ext-dep
(->> (into []
(mapcat find-java-files*)))))
(u/spec-op external-files
:param {:req [::classpath/index]}
:ret ::compilation.java/sources)
(defn jar-files [{i ::classpath/index}]
"Use an indexed classpath to find all .java files from jars.
See:
- [[fr.jeremyschoffen.mbt.alpha.core.classpath/indexed-classpath]]
"
(-> i
::classpath/jar
(->> (into []
(mapcat (fn [src-jar]
(with-open [src (jar-fs/read-only-jar-fs src-jar)]
(find-java-files* src))))))))
(u/spec-op jar-files
:param {:req [::classpath/index]}
:ret ::compilation.java/sources)
;;----------------------------------------------------------------------------------------------------------------------
;; Building java object used to compile.
;;----------------------------------------------------------------------------------------------------------------------
(defn make-java-compiler
"Return the platform's default java compiler."
{:tag JavaCompiler}
[& _]
(ToolProvider/getSystemJavaCompiler))
(u/spec-op make-java-compiler
:ret ::compilation.java/compiler)
(defn make-standard-file-manager
"Make a standard file manager from a java compiler."
{:tag StandardJavaFileManager}
[{compiler ::compilation.java/compiler
opts ::compilation.java.file-manager/options}]
(let [{::compilation.java.file-manager/keys [listener locale charset]} opts]
(.getStandardFileManager ^JavaCompiler compiler listener locale charset)))
(u/spec-op make-standard-file-manager
:param {:req [::compilation.java/compiler]
:opt [::compilation.java.file-manager/options]})
(defn make-compilation-unit
"Make a compilation unit to give a compilation task using a file manager."
[{file-manager ::compilation.java/file-manager
sources ::compilation.java/sources}]
(->> sources
(mapv fs/file)
(.getJavaFileObjectsFromFiles ^StandardJavaFileManager file-manager)))
(u/spec-op make-compilation-unit
:param {:req [::compilation.java/file-manager
::compilation.java/sources]})
;;----------------------------------------------------------------------------------------------------------------------
;; Compilation proper
;;----------------------------------------------------------------------------------------------------------------------
(defn compile!
"Compile java files. This function makes a compilation task with `compiler.getTask` and immediatly calls `.call on
it`.
See: `javax.tool.JavaCompiler`."
[{compiler ::compilation.java/compiler
file-manager ::compilation.java/file-manager
out ::compilation.java/compiler-out
diagnostic-listener ::compilation.java/diagnostic-listener
options ::compilation.java/options
classes ::compilation.java/compiler-classes
compilation-unit ::compilation.java/compilation-unit}]
(.call (.getTask ^JavaCompiler compiler
out
file-manager
diagnostic-listener
options
classes
compilation-unit)))
(u/spec-op compile!
:param {:req [::compilation.java/compiler
::compilation.java/file-manager
::compilation.java/compilation-unit]
:opt [::compilation.java/compiler-out
::compilation.java/diagnostic-listener
::compilation.java/options
::compilation.java/compiler-classes]})