diff --git a/src/main/java/org/eclipse/golo/cli/command/GoloGoloCommand.java b/src/main/java/org/eclipse/golo/cli/command/GoloGoloCommand.java index 51c25772c..518a1f0b1 100644 --- a/src/main/java/org/eclipse/golo/cli/command/GoloGoloCommand.java +++ b/src/main/java/org/eclipse/golo/cli/command/GoloGoloCommand.java @@ -78,7 +78,7 @@ private Class loadGoloFile(String goloFile, String module, GoloClassLoader lo } } else if (file.getName().endsWith(".golo")) { try (FileInputStream in = new FileInputStream(file)) { - Class loadedClass = loader.load(file.getName(), in); + Class loadedClass = loader.load(file.getName(), in, file.toURI().toURL()); if (module == null || loadedClass.getCanonicalName().equals(module)) { return loadedClass; } diff --git a/src/main/java/org/eclipse/golo/cli/command/ShebangCommand.java b/src/main/java/org/eclipse/golo/cli/command/ShebangCommand.java index 58c87b6bf..d507d5fd7 100644 --- a/src/main/java/org/eclipse/golo/cli/command/ShebangCommand.java +++ b/src/main/java/org/eclipse/golo/cli/command/ShebangCommand.java @@ -78,7 +78,7 @@ private Class loadGoloFile(GoloClassLoader loader, Path path) { try (InputStream is = Files.newInputStream(path)) { Path filename = path.getFileName(); if (filename != null) { - return loader.load(filename.toString(), is); + return loader.load(filename.toString(), is, path.toUri().toURL()); } else { throw new RuntimeException(message("not_regular_file", path)); } diff --git a/src/main/java/org/eclipse/golo/compiler/GoloClassLoader.java b/src/main/java/org/eclipse/golo/compiler/GoloClassLoader.java index cbf0b6bbc..bf223d5fc 100644 --- a/src/main/java/org/eclipse/golo/compiler/GoloClassLoader.java +++ b/src/main/java/org/eclipse/golo/compiler/GoloClassLoader.java @@ -10,6 +10,10 @@ package org.eclipse.golo.compiler; import java.io.InputStream; +import java.net.URL; +import java.security.CodeSource; +import java.security.ProtectionDomain; +import java.security.cert.Certificate; import java.util.List; /** @@ -58,4 +62,25 @@ public synchronized Class load(String goloSourceFilename, InputStream sourceC } return lastClassIsModule; } + + /** + * Compiles and loads the resulting JVM bytecode for a Golo source file. + * This method declares a URL for the CodeSource of this class, which + * is useful for retrieving the location at runtime. + * + * @param goloSourceFilename the source file name. + * @param sourceCodeInputStream the source input stream. + * @param sourceCodeLocation the source file location. + * @return the class matching the Golo module defined in the source. + * @throws GoloCompilationException if either of the compilation phase failed. + */ + public synchronized Class load(String goloSourceFilename, InputStream sourceCodeInputStream, URL sourceCodeLocation) throws GoloCompilationException { + List results = compiler.compile(goloSourceFilename, sourceCodeInputStream); + Class lastClassIsModule = null; + for (CodeGenerationResult result : results) { + byte[] bytecode = result.getBytecode(); + lastClassIsModule = defineClass(null, bytecode, 0, bytecode.length, new ProtectionDomain(new CodeSource(sourceCodeLocation, (Certificate[])null), null)); + } + return lastClassIsModule; + } }