From: Fredrik Tolf Date: Thu, 9 Nov 2023 16:08:14 +0000 (+0100) Subject: Reorganize compiler for more flexibility. X-Git-Url: http://git.dolda2000.com/gitweb/?a=commitdiff_plain;h=e8892ea03fb37d1f1d362ad82b16a14986c5cd25;p=jagi.git Reorganize compiler for more flexibility. --- diff --git a/src/jagi/fs/Compiler.java b/src/jagi/fs/Compiler.java index 02c3a7f..14b3786 100644 --- a/src/jagi/fs/Compiler.java +++ b/src/jagi/fs/Compiler.java @@ -8,7 +8,7 @@ import java.nio.file.attribute.*; import java.io.*; public class Compiler { - private final Map modules = new HashMap<>(); + private final Map files = new HashMap<>(); public static class ClassOutput { public final String name; @@ -62,34 +62,6 @@ public class Compiler { infiles.add(p); } - private static final Pattern classpat = Pattern.compile("^((public|abstract)\\s+)*(class|interface)\\s+(\\S+)"); - public void split(Path infile) throws IOException { - StringBuilder head = new StringBuilder(); - BufferedWriter cur = null; - try(BufferedReader fp = Files.newBufferedReader(infile)) { - for(String ln = fp.readLine(); ln != null; ln = fp.readLine()) { - Matcher m = classpat.matcher(ln); - if(m.find()) { - String clnm = m.group(4); - Path sp = srcdir.resolve(clnm + ".java"); - add(sp); - if(cur != null) - cur.close(); - cur = Files.newBufferedWriter(sp); - cur.append(head); - } - if(cur != null) { - cur.append(ln); cur.append('\n'); - } else { - head.append(ln); head.append('\n'); - } - } - } finally { - if(cur != null) - cur.close(); - } - } - public boolean compile() throws IOException { List args = new ArrayList<>(); args.add("javac"); @@ -159,15 +131,6 @@ public class Compiler { } } - public static Collection compile(Path file) throws IOException { - try(Compilation c = new Compilation()) { - c.split(file); - if(!c.compile()) - throw(new CompilationException(file, c.output())); - return(c.classes()); - } - } - public static class BufferedClassLoader extends ClassLoader { public final Map contents; @@ -187,35 +150,78 @@ public class Compiler { public static class Module { public final Path file; - private FileTime mtime = null; - private ClassLoader code = null; + public final ClassLoader code; - private Module(Path file) { + public Module(Path file) throws IOException { this.file = file; + try(Compilation c = new Compilation()) { + split(c); + if(!c.compile()) + throw(new CompilationException(file, c.output())); + code = new BufferedClassLoader(c.classes()); + } + } + + private static final Pattern classpat = Pattern.compile("^((public|abstract)\\s+)*(class|interface)\\s+(\\S+)"); + public void split(Compilation c) throws IOException { + StringBuilder head = new StringBuilder(); + BufferedWriter cur = null; + try(BufferedReader fp = Files.newBufferedReader(file)) { + for(String ln = fp.readLine(); ln != null; ln = fp.readLine()) { + Matcher m = classpat.matcher(ln); + if(m.find()) { + String clnm = m.group(4); + Path sp = c.srcdir.resolve(clnm + ".java"); + c.add(sp); + if(cur != null) + cur.close(); + cur = Files.newBufferedWriter(sp); + cur.append(head); + } + if(cur != null) { + cur.append(ln); cur.append('\n'); + } else { + head.append(ln); head.append('\n'); + } + } + } finally { + if(cur != null) + cur.close(); + } + } + } + + public static class File { + public final Path name; + private FileTime mtime = null; + private Module mod = null; + + private File(Path name) { + this.name = name; } public void update() throws IOException { synchronized(this) { - FileTime mtime = Files.getLastModifiedTime(file); + FileTime mtime = Files.getLastModifiedTime(name); if((this.mtime == null) || (this.mtime.compareTo(mtime) < 0)) { - code = new BufferedClassLoader(compile(file)); + mod = new Module(name); this.mtime = mtime; } } } - public ClassLoader code() { - if(code == null) - throw(new RuntimeException("module has not yet been updated")); - return(code); + public Module mod() { + if(mod == null) + throw(new RuntimeException("file has not yet been updated")); + return(mod); } } - public Module module(Path file) { - synchronized(modules) { - Module ret = modules.get(file); + public File file(Path name) { + synchronized(files) { + File ret = files.get(name); if(ret == null) - modules.put(file, ret = new Module(file)); + files.put(name, ret = new File(name)); return(ret); } } diff --git a/src/jagi/fs/JavaHandler.java b/src/jagi/fs/JavaHandler.java index 111264f..6579097 100644 --- a/src/jagi/fs/JavaHandler.java +++ b/src/jagi/fs/JavaHandler.java @@ -9,7 +9,7 @@ import java.nio.file.*; public class JavaHandler implements Function, Map> { private static final Logger log = Logger.getLogger("jagi-fs"); - private final Map, Map>> handlers = new WeakHashMap<>(); + private final Map, Map>> handlers = new WeakHashMap<>(); public static class HandlerException extends RuntimeException { public final Path file; @@ -31,7 +31,7 @@ public class JavaHandler implements Function, Map, Map> makehandler(Compiler.Module mod) { Class main; try { - main = mod.code().loadClass("Main"); + main = mod.code.loadClass("Main"); } catch(ClassNotFoundException e) { throw(new HandlerException(mod.file, "no Main class")); } @@ -65,30 +65,30 @@ public class JavaHandler implements Function, Map, Map> gethandler(Compiler.Module mod) { - ClassLoader code = mod.code(); + private Function, Map> gethandler(Compiler.File file) { + Compiler.Module mod = file.mod(); synchronized(handlers) { - Function, Map> ret = handlers.get(code); + Function, Map> ret = handlers.get(mod); if(ret == null) - handlers.put(code, ret = makehandler(mod)); + handlers.put(mod, ret = makehandler(mod)); return(ret); } } public Map apply(Map req) { - Compiler.Module mod = Compiler.get().module(Paths.get((String)req.get("SCRIPT_FILENAME"))); + Compiler.File file = Compiler.get().file(Paths.get((String)req.get("SCRIPT_FILENAME"))); try { - mod.update(); + file.update(); } catch(Compiler.CompilationException e) { - log.warning(String.format("Could not compile %s:\n%s", mod.file, e.messages())); + log.warning(String.format("Could not compile %s:\n%s", file.name, e.messages())); return(Utils.simpleerror(500, "Internal Error", "Could not load JAGI handler")); } catch(Exception e) { - log.log(Level.WARNING, String.format("Error occurred when loading %s", mod.file), e); + log.log(Level.WARNING, String.format("Error occurred when loading %s", file.name), e); return(Utils.simpleerror(500, "Internal Error", "Could not load JAGI handler")); } Function, Map> handler; try { - handler = gethandler(mod); + handler = gethandler(file); } catch(HandlerException e) { Throwable cause = e.getCause(); if(cause != null)