Как программно вызывать компилятор Scala?

Я хочу, чтобы мой код Scala принимал класс Scala в качестве ввода, компилировал и выполнял этот класс. Как я могу программным образом вызывать компилятор Scala? Я буду использовать последнюю версию Scala, т.е. 2.10.

Ответы

Ответ 1

ToolBox

Я думаю, что надлежащий способ вызова компилятора Scala делает это через Reflection API, зарегистрированный в Overview. В частности, Дерево Создание через раздел синтаксического анализа на панели инструментов > в разделе "Символы, деревья и типы" говорит о разборе String в Tree с помощью ToolBox. Затем вы можете вызвать eval() и т.д.

scala.tools.nsc.Global

Но, как писал Шьямендра Соланки, на самом деле вы можете управлять scalac Global, чтобы сделать больше. Я написал CompilerMatcher, поэтому я могу скомпилировать сгенерированный код с примером кода для выполнения тестов интеграции.

scala.tools.ncs.IMain

Вы можете вызвать REPL IMain для оценки кода (это также доступно в приведенном выше CompilerMatcher, если вы хотите что-то, что работает с Scala 2.10):

  val main = new IMain(s) {
    def lastReq = prevRequestList.last
  }
  main.compileSources(files.map(toSourceFile(_)): _*)
  code map { c => main.interpret(c) match {
    case IR.Error => sys.error("Error interpreting %s" format (c))
    case _ => 
  }}
  val holder = allCatch opt {
    main.lastReq.lineRep.call("$result")
  }

Это было продемонстрировано в вставке сообщения Scala Interpreter Джоша Суэрета в 2009 году.

Ответ 2

Класс, который нужно скомпилировать и запустить (в файле test.scala)

class Test {

   println ("Hello World!")

}

//compileAndRun.scala(в том же каталоге)

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.