Reorganize compiler for more flexibility.
authorFredrik Tolf <fredrik@dolda2000.com>
Thu, 9 Nov 2023 16:08:14 +0000 (17:08 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Thu, 9 Nov 2023 16:08:14 +0000 (17:08 +0100)
src/jagi/fs/Compiler.java
src/jagi/fs/JavaHandler.java

index 02c3a7f..14b3786 100644 (file)
@@ -8,7 +8,7 @@ import java.nio.file.attribute.*;
 import java.io.*;
 
 public class Compiler {
-    private final Map<Path, Module> modules = new HashMap<>();
+    private final Map<Path, File> 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<String> args = new ArrayList<>();
            args.add("javac");
@@ -159,15 +131,6 @@ public class Compiler {
        }
     }
 
-    public static Collection<ClassOutput> 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<String, byte[]> 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);
        }
     }
index 111264f..6579097 100644 (file)
@@ -9,7 +9,7 @@ import java.nio.file.*;
 
 public class JavaHandler implements Function<Map<Object, Object>, Map<Object, Object>> {
     private static final Logger log = Logger.getLogger("jagi-fs");
-    private final Map<ClassLoader, Function<Map<Object, Object>, Map<Object, Object>>> handlers = new WeakHashMap<>();
+    private final Map<Compiler.Module, Function<Map<Object, Object>, Map<Object, Object>>> handlers = new WeakHashMap<>();
 
     public static class HandlerException extends RuntimeException {
        public final Path file;
@@ -31,7 +31,7 @@ public class JavaHandler implements Function<Map<Object, Object>, Map<Object, Ob
     private static Function<Map<Object, Object>, Map<Object, Object>> 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<Object, Object>, Map<Object, Ob
        throw(new HandlerException(mod.file, "no wmain and not directly applicable"));
     }
 
-    private Function<Map<Object, Object>, Map<Object, Object>> gethandler(Compiler.Module mod) {
-       ClassLoader code = mod.code();
+    private Function<Map<Object, Object>, Map<Object, Object>> gethandler(Compiler.File file) {
+       Compiler.Module mod = file.mod();
        synchronized(handlers) {
-           Function<Map<Object, Object>, Map<Object, Object>> ret = handlers.get(code);
+           Function<Map<Object, Object>, Map<Object, Object>> ret = handlers.get(mod);
            if(ret == null)
-               handlers.put(code, ret = makehandler(mod));
+               handlers.put(mod, ret = makehandler(mod));
            return(ret);
        }
     }
 
     public Map<Object, Object> apply(Map<Object, Object> 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<Object, Object>, Map<Object, Object>> handler;
        try {
-           handler = gethandler(mod);
+           handler = gethandler(file);
        } catch(HandlerException e) {
            Throwable cause = e.getCause();
            if(cause != null)