scala.tools.nsc.Global在第一次编译错误后无法编译

时间:2017-09-25 06:13:45

标签: scala compilation twirl

我已经实现了Twirl模板的动态编译,偶然发现了奇怪的问题 - scala.tools.nsc.Global的实例一直有效,直到它使用错误的源文件失败一次。任何进一步尝试编译有效文件失败,它不会产生.class二进制文件。我在Scala 2.11.8上。

我该如何调试和解决此问题?

以下是我创建Global的实例的方法:

private def createScalaCompiler(compileErrors: mutable.ListBuffer[CompilationError]): Global = {

  val additionalClassPathEntry: String =
    List(twirlCompilerClass, this.getClass).flatMap(_.getClassLoader.asInstanceOf[URLClassLoader].getURLs.map(_.getFile)).distinct.mkString(":")

  val settings = new Settings()
  settings.debug.tryToSet(Nil)
  settings.verbose.tryToSet(Nil)

  val scalaObjectSource = Class.forName("scala.Int").getProtectionDomain.getCodeSource
  if (scalaObjectSource != null) {
    val compilerPath = Class.forName("scala.tools.nsc.Interpreter").getProtectionDomain.getCodeSource.getLocation
    val libPath = scalaObjectSource.getLocation
    val pathList = List(compilerPath, libPath)
    val origBootclasspath = settings.bootclasspath.value
    settings.bootclasspath.value = ((origBootclasspath :: pathList) ::: Some(additionalClassPathEntry).toList) mkString File.pathSeparator
    settings.outdir.value = generatedClasses.getAbsolutePath
  }

  val compiler: Global = new Global(settings, new ConsoleReporter(settings) {
    override def printMessage(pos: Position, msg: String): Unit = {
      pos match {
        case NoPosition =>
          println(msg)
        case _ =>
          compileErrors.append(CompilationError(msg, pos.line, pos.point))
      }
    }
  })

  compiler
}

我使用如下

val compileErrors = new mutable.ListBuffer[CompilationError]
val compiler = createScalaCompiler(compileErrors)

然后compiler的实例在功能上多次使用

def compileScalaFile(fakePath: String, content: String) {
  val run = new compiler.Run
  val sourceFile = new BatchSourceFile(new VirtualFile(fakePath), content)
  run.compileSources(List(sourceFile))
}

如您所见,我启用了详细日志记录。有趣的是,编译有效的scala代码并不会产生任何记录输出,

在我看来,compiler进入破碎状态。如何重置它而不从头开始重新创建(生产需要时间)?

0 个答案:

没有答案