使用scala 2.12进行动态编译 - 来自sbt test

时间:2017-05-27 12:59:56

标签: scala dynamic compilation sbt scala-compiler

我想测试一个我编写的工具,它会转换一些scala源代码,我想检查转换的代码是否从sbt测试编译(使用scalatest)。

我想以编程方式调用带有源代码的String上的scala编译器(所有这些都在一个独立的文件中)。

自最初的问题以来,我取得了一些进展。此代码适用于我的IDE(IntelliJ),但不适用于precision = Keyboard.IsKeyDown(Key.Control) ? 3 : 2; 会话

sbt test

这是我的import java.io.File import scala.reflect.internal.util.BatchSourceFile import scala.tools.nsc.{GenericRunnerSettings, Global} object Compilation { val settings = new GenericRunnerSettings(System.out.println _) // val sbtClasspath = System.getProperty("sbt-classpath") // val s = File.pathSeparator // val classPath = s".${s}$sbtClasspath" // settings.classpath.append(classPath) settings.usejavacp.value = true val global = new Global(settings) def compiles(code: String): Boolean = { val r = new global.Run r.compileSources(List(new BatchSourceFile("<partest>", code))) val errors = global.reporter.hasErrors if (errors) r.reporting.summarizeErrors() !errors } }

build.sbt

初始错误是

name := "CodinGame-Scala-Kit"
version := "0.1.0"
scalaVersion := "2.12.2"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.12.2" % "test"

enablePlugins(JmhPlugin)

//val sbtcp = taskKey[Unit]("sbt-classpath")
//
//sbtcp := {
//  val files: Seq[File] = (fullClasspath in Compile).value.files
//  val sbtClasspath: String = files.map(x => x.getAbsolutePath).mkString(java.io.File.pathSeparator)
//  println("Set SBT classpath to 'sbt-classpath' environment variable")
//  println(sbtClasspath)
//  System.setProperty("sbt-classpath", sbtClasspath)
//}
//
//compile <<= (compile in Compile).dependsOn(sbtcp)

我添加了scala.reflect.internal.MissingRequirementError: object scala.annotation.Annotation in compiler mirror not found. [info] at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:17) [info] at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:18) [info] at scala.reflect.internal.Mirrors$RootsBase.$anonfun$getModuleOrClass$4(Mirrors.scala:54) [info] at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:54) [info] at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:45) [info] at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:66) [info] at scala.reflect.internal.Mirrors$RootsBase.getClassByName(Mirrors.scala:101) [info] at scala.reflect.internal.Mirrors$RootsBase.getRequiredClass(Mirrors.scala:104) [info] at scala.reflect.internal.Mirrors$RootsBase.requiredClass(Mirrors.scala:107) [info] at scala.reflect.internal.Definitions$DefinitionsClass.AnnotationClass$lzycompute(Definitions.scala:1141) 中注释的行以及this answer后面的build.sbt对象中添加的行。它在IDE中没有任何改变。

我现在在sbt test上有这个错误(编译正确打印了类路径):

Compilation

2 个答案:

答案 0 :(得分:1)

第二种方法看起来类似于对我有用的东西,你显然在某处缺少依赖。空设置无法正常工作。 更改设置bootclasspath

或者只是使用 settings.usejavacp.value = true

答案 1 :(得分:0)

我终于找到了编译任何String的可靠方法:

import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox

object Compiler {

  def compile[A](string: String): A = {
    val toolbox = currentMirror.mkToolBox()
    val tree    = toolbox.parse(string)
    toolbox.eval(tree).asInstanceOf[A]
  }
}

使用

libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.12.10"