- public static Collection<ClassOutput> compile(Path file) throws IOException {
- List<String> opt = Arrays.asList();
- JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
- if(javac == null)
- throw(new RuntimeException("no javac present"));
- Collection<FilePart> files;
- files = FilePart.split(file);
- DiagnosticCollector<JavaFileObject> out = new DiagnosticCollector<>();
- FileContext fs = new FileContext(javac);
- JavaCompiler.CompilationTask job = javac.getTask(null, fs, out, opt, null, files);
- if(!job.call())
- throw(new CompilationException(file, out.getDiagnostics()));
- return(fs.output);
+ public static class Compilation implements AutoCloseable {
+ public final Path dir, srcdir, outdir;
+ private final List<Path> infiles = new ArrayList<>();
+ private final List<Path> classpath = new ArrayList<>();
+ private List<String> output = null;
+
+ public Compilation() throws IOException {
+ dir = Files.createTempDirectory("javac");
+ srcdir = dir.resolve("src");
+ outdir = dir.resolve("out");
+ Files.createDirectory(srcdir);
+ Files.createDirectory(outdir);
+ }
+
+ public void add(Path p) {
+ infiles.add(p);
+ }
+
+ public void classpath(Path p) {
+ classpath.add(p);
+ }
+
+ public boolean compile() throws IOException {
+ List<String> args = new ArrayList<>();
+ args.add("javac");
+ args.add("-d");
+ args.add(outdir.toString());
+ if(!classpath.isEmpty()) {
+ StringBuilder buf = new StringBuilder();
+ for(Path cp : classpath) {
+ if(buf.length() > 0)
+ buf.append(":");
+ buf.append(cp.toString());
+ }
+ args.add("-cp");
+ args.add(buf.toString());
+ }
+ for(Path p : infiles)
+ args.add(p.toString());
+ ProcessBuilder cmd = new ProcessBuilder(args);
+ cmd.redirectErrorStream(true);
+ cmd.redirectOutput(ProcessBuilder.Redirect.PIPE);
+ Process proc = cmd.start();
+ List<String> output = new ArrayList<>();
+ BufferedReader fp = new BufferedReader(new InputStreamReader(proc.getInputStream(), Utils.UTF8));
+ while(true) {
+ String ln = fp.readLine();
+ if(ln == null)
+ break;
+ output.add(ln);
+ }
+ int status;
+ try {
+ status = proc.waitFor();
+ } catch(InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw(new IOException("compilation interrupted"));
+ }
+ this.output = output;
+ return(status == 0);
+ }
+
+ public List<String> output() {
+ if(output == null)
+ throw(new IllegalStateException());
+ return(output);
+ }
+
+ public Collection<ClassOutput> classes() throws IOException {
+ Collection<ClassOutput> ret = new ArrayList<>();
+ for(Path p : (Iterable<Path>)Files.walk(outdir)::iterator) {
+ Path rel = outdir.relativize(p);
+ String fn = rel.getName(rel.getNameCount() - 1).toString();
+ if(!Files.isRegularFile(p) || !fn.endsWith(".class"))
+ continue;
+ StringBuilder clnm = new StringBuilder();
+ for(int i = 0; i < rel.getNameCount() - 1; i++) {
+ clnm.append(rel.getName(i));
+ clnm.append('.');
+ }
+ clnm.append(fn.substring(0, fn.length() - 6));
+ ClassOutput cls = new ClassOutput(clnm.toString());
+ Files.copy(p, cls.buf);
+ ret.add(cls);
+ }
+ return(ret);
+ }
+
+ private static void remove(Path p) throws IOException {
+ if(Files.isDirectory(p)) {
+ for(Path ent : (Iterable<Path>)Files.list(p)::iterator)
+ remove(ent);
+ }
+ Files.delete(p);
+ }
+
+ public void close() throws IOException {
+ remove(dir);
+ }