Scala运行时编译:如何获取错误消息的行号



我发现scala编译器报告编译错误的方式不同,这取决于它是在编译时使用还是在运行时使用。

例如,对于一个简单的隐式未找到案例,在编译时报告为:

newSource1.scala:6: error: type mismatch;
L|R
f(new L)
^

在运行时,当评估相同的代码并直接捕获错误消息时:


class TestCase(code: String, extra: String) {

def toolbox(extra: String): ToolBox[universe.type] = {
ToolBox(cm).mkToolBox(options = s"$opts $extra")
}
def compile(): Any = {
import SpecHelpers._
val tb = toolbox(extra)
tb.eval(tb.parse(code))
}
def compileError(): String =
Try(compile()) match {
case Failure(ee) =>
ee match {
case te: ToolBoxError =>
te.message.linesIterator.toList.drop(2).mkString("n")
case t =>
throw t
}
case Success(_) =>
sys.error("compiling succeeded")
}
}

省略了行号和位置光标:;

implicit error;
!I e: F[Arg]

有没有办法把缺失的部分补回来?

您可以为ToolBox指定frontEnd(默认frontEndmkSilentFrontEnd())

val tb = cm.mkToolBox(
frontEnd = new FrontEnd {
override def display(info: Info): Unit = println(info)
},
options = "-Xlog-implicits -Vimplicits -Vimplicits-verbose-tree -d out" 
// with `-d out` toolbox keeps `.class` files in directory `out` 
// rather than in memory, so you can decompile `.class` files 
// if you want to investigate auto-generated code
)
tb.compile(tb.parse(
"""implicit val i: Int = 1
|implicitly[String]""".stripMargin))
//Info(source-<toolbox>,line-2,offset=34,implicit error;
//!I e: String,ERROR)
//Exception in thread "main" java.lang.ExceptionInInitializerError
//  at App.main(App.scala)
//Caused by: scala.tools.reflect.ToolBoxError: reflective compilation has failed:
//
//implicit error;
//!I e: String
//  at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:332)
//  at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.wrapInPackageAndCompile(ToolBoxFactory.scala:214)
//  at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:268)
//  at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.$anonfun$compile$13(ToolBoxFactory.scala:445)
//  at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.apply(ToolBoxFactory.scala:371)
//  at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:438)
//  at App$.<clinit>(App.scala:20)
//  ... 1 more

最新更新