From d7e59902e059954a7f764c8b09da2dff76bc5ee4 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Mon, 13 Nov 2023 17:46:51 +0100 Subject: [PATCH] Allow jagidir modules to include other compiled modules. --- src/jagi/fs/Compiler.java | 59 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/src/jagi/fs/Compiler.java b/src/jagi/fs/Compiler.java index b277e00..2f0d81c 100644 --- a/src/jagi/fs/Compiler.java +++ b/src/jagi/fs/Compiler.java @@ -11,6 +11,7 @@ import java.net.*; public class Compiler { private static final Logger log = Logger.getLogger("jagi-fs"); + private static final Path cwd = Paths.get("").toAbsolutePath(); private final Map files = new HashMap<>(); private final Map libs = new HashMap<>(); private final Collection searchpath = new ArrayList<>(); @@ -86,15 +87,17 @@ public class Compiler { } public static class Compilation implements AutoCloseable { - public final Path dir, srcdir, outdir; + public final Path dir, srcdir, outdir, libdir; private final List infiles = new ArrayList<>(); private final List classpath = new ArrayList<>(); private List output = null; + private boolean haslib; public Compilation() throws IOException { dir = Files.createTempDirectory("javac"); srcdir = dir.resolve("src"); outdir = dir.resolve("out"); + libdir = dir.resolve("lib"); Files.createDirectory(srcdir); Files.createDirectory(outdir); } @@ -107,6 +110,32 @@ public class Compiler { classpath.add(p); } + public void addlib(String clnm, byte[] contents) throws IOException { + if(!haslib) { + Files.createDirectory(libdir); + classpath(libdir); + haslib = true; + } + Path p = libdir; + int p1 = 0; + while(true) { + int p2 = clnm.indexOf('.', p1); + if(p2 < 0) + break; + p = p.resolve(clnm.substring(p1, p2)); + if(!Files.isDirectory(p)) + Files.createDirectory(p); + p1 = p2 + 1; + } + p = p.resolve(clnm.substring(p1) + ".class"); + Files.write(p, contents); + } + + public void addlib(Map classes) throws IOException { + for(Map.Entry ent : classes.entrySet()) + addlib(ent.getKey(), ent.getValue()); + } + public boolean compile() throws IOException { List args = new ArrayList<>(); args.add("javac"); @@ -253,10 +282,12 @@ public class Compiler { private static final Pattern classpat = Pattern.compile("^((public|abstract)\\s+)*(class|interface)\\s+(\\S+)"); private static final Pattern libpat = Pattern.compile("\\$use\\s*:\\s*(\\S+)"); + private static final Pattern incpat = Pattern.compile("\\$include\\s*:\\s*(\\S+)"); public class Module { public final Path file; - public final ClassLoader code; + public final BufferedClassLoader code; public final Collection classpath = new ArrayList<>(); + public final Collection include = new ArrayList<>(); public Module(Path file) throws IOException { this.file = file; @@ -267,10 +298,12 @@ public class Compiler { if(!c.compile()) throw(new CompilationException(file, c.output())); ClassLoader parent = Compiler.class.getClassLoader(); - if(!classpath.isEmpty()) { + if(!classpath.isEmpty() || !include.isEmpty()) { Collection libs = new ArrayList<>(); for(Path cp : classpath) libs.add(libloader(cp)); + for(Module mod : include) + libs.add(mod.code); parent = new LibClassLoader(parent, libs); } code = new BufferedClassLoader(parent, c.classes()); @@ -289,6 +322,26 @@ public class Compiler { throw(new CompilationException(file, Arrays.asList("no such library: " + m.group(1)))); classpath.add(lib); } + m = incpat.matcher(ln); + if(m.find()) { + String nm = m.group(1); + File f= null; + if(f == null) { + Path p = file.resolveSibling(nm); + if(Files.isRegularFile(p)) + f = file(p); + } + if(f == null) { + Path p = cwd.resolve(nm); + if(Files.isRegularFile(p)) + f = file(p); + } + if(f == null) + throw(new CompilationException(file, Arrays.asList("no such file to include: " + nm))); + f.update(); + c.addlib(f.mod().code.contents); + include.add(f.mod()); + } m = classpat.matcher(ln); if(m.find()) { String clnm = m.group(4); -- 2.11.0