Skip to content

Instantly share code, notes, and snippets.

@mickronome
Last active July 7, 2020 20:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mickronome/27d3df3898924608facaf0584b55ec5c to your computer and use it in GitHub Desktop.
Save mickronome/27d3df3898924608facaf0584b55ec5c to your computer and use it in GitHub Desktop.
Compile Java using a cached file-manager in Clojure
(ns cached-filemanager
(:import (javax.tools ToolProvider)))
(defn create-compiler[]
(let [compiler (ToolProvider/getSystemJavaCompiler)
file-manager (.getStandardFileManager compiler nil nil nil)]
{:java-compiler compiler
:file-manager file-manager}))
(defn path-of[file-path]
(let [fs (java.nio.file.FileSystems/getDefault)]
(.getPath fs file-path (make-array String 0))))
(defn mk-unit[{:keys [file-manager]} file-path]
(let [path-array (into-array java.nio.file.Path [(path-of file-path)])
compilation-unit (.getJavaFileObjects file-manager path-array)]
{:compilation-unit compilation-unit}))
(defn do-compile[{:keys [file-manager java-compiler
task compilation-unit diagnostic]}]
(let [result (.call task)
diagnostic-list (.getDiagnostics diagnostic)] ;;javax/tools/Diagnostic
{:success result
:errors (map bean diagnostic-list)}))
(defn mk-task [{:keys [file-manager java-compiler
compilation-unit diagnostic]}]
(let [diagnostic (javax.tools.DiagnosticCollector.)
task (.getTask java-compiler *out* file-manager diagnostic nil nil compilation-unit)]
{:diagnostic diagnostic
:task task}))
;; see https://www.logicbig.com/tutorials/core-java-tutorial/java-se-compiler-api/java-compiler-api-intro.html
(comment
;; except the first run, this usually takes ~300 ms
(require '[clj-async-profiler.core :as prof])
(def compiler (create-compiler))
(def file-path ".../java-experiments/src/main/java/net/curiosprogrammer/javaexperiments/compiler/JavaCompiler.java")
(def cu (mk-unit compiler file-path))
(prof/start)
;; YOUR CODE HERE
(for [x (range 1 2)]
(time (do-compile (merge compiler cu (mk-task (merge cu compiler))))))
(prof/stop {:width 2400}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment