I want my Scala code to take a Scala class as input, compile and execute that class. How can I programmatically invoke a Scala compiler? I will be using the latest Scala version, i.e. 2.10.
How to invoke the Scala compiler programmatically?
3.4k views Asked by Anuj Mehta At
2
There are 2 answers
1
On
The class to be compiled and run (in file test.scala)
class Test {
println ("Hello World!")
}
// compileAndRun.scala (in same directory)
import scala.tools.nsc._
import java.io._
val g = new Global(new Settings())
val run = new g.Run
run.compile(List("test.scala")) // invoke compiler. it creates Test.class.
val classLoader = new java.net.URLClassLoader(
Array(new File(".").toURI.toURL), // Using current directory.
this.getClass.getClassLoader)
val clazz = classLoader.loadClass("Test") // load class
clazz.newInstance // create an instance, which will print Hello World.
ToolBox
I think the proper way of invoking the Scala compiler is doing it via Reflection API documented in Overview. Specifically, Tree Creation via parse on ToolBoxes section in 'Symbols, Trees, and Types' talks about parsing
StringintoTreeusingToolBox. You can then invokeeval()etc.scala.tools.nsc.Global
But as Shyamendra Solanki wrote, in reality you can drive scalac's
Globalto get more done. I've written CompilerMatcher so I can compile generated code with sample code to do integration tests for example.scala.tools.ncs.IMain
You can invoke the REPL
IMainto evaluate the code (this is also available in the aboveCompilerMatcherif you want something that works with Scala 2.10):This was demonstrated in Embedding the Scala Interpreter post by Josh Suereth back in 2009.