Scala Presentation Compiler - 最小的例子

Mar*_*ing 26 compiler-construction scala

有人可以提供使用当前scala表示编译器(即)的最小示例scala.tools.nsc.interactive.Global,它可以完成以下任务吗?

  • 编译单个虚拟源文件(即不在文件系统中,但例如a String)
  • 从编译器检索所有阶段的结果信息
  • 将源文件中的更改传播到编译器
  • 可能异步接收进一步的信息

似乎有很多波动nsc,我找不到最新的小例子.所以我非常感谢你的帮助.

Mar*_*ing 9

好的,一周100赏金,但仍然没有答案所以我会自己尝试... 编辑非常欢迎!

表示编译器的关键类是scala.tools.nsc.interactive.Global.首先,我们需要创建一个编译器实例.

import scala.tools.nsc.interactive.Global
class PresentationCompiler { //我们希望编译器输出是虚拟的 val target = new VirtualDirectory("",None)
//需要进行调整才能使用 // sbt.看到这个问题. val设置=新设置() //输出到虚拟目标 settings.outputDirs.setSingleOutput(目标)
//可以由自定义实例替换 // AbstractReporter获得控制权. val reporter = new ConsoleReporter(设置)
val compiler = new Global(设置,记者)
... }

对于设置,Abhishek提供的链接非常有价值.

但现在有趣的是:

1.编译单个虚拟源文件

要编译String,可以BatchSourceFile使用底层创建一个VirtualFile.api在这里被标记为实验性的并且看起来不完整.

def compile(code: String) {
  val source = new BatchSourceFile("<virtual>", code)
  val response = new Response[Unit]
  compiler.askReload(List(source), response)    
  response.get.left.foreach { _ =>
    // success
  }
}
Run Code Online (Sandbox Code Playgroud)

2.从编译器中检索所有阶段的结果信息

这是棘手的部分.由于编译器的多线程特性以及标志在不同阶段中以不同含义重用的事实,因此不可能一次性获取所有内容.基本上,您将不得不求助于APIaskSomething中记录的那种方法.例如:

val tcompletion = new Response[List[global.Member]]      
val pos = compiler.ask(() => new OffsetPosition(source, p))
global.askTypeCompletion(pos, tcompletion)
tcompletion.get(5000).get match {
  case Left(members) => // do something with members
  case Right(e) =>
    e.printStackTrace
}
Run Code Online (Sandbox Code Playgroud)

3.将源文件中的更改传播到编译器

这是有趣的部分,我想知道这个问题.我真的不明白,因为它BatchSourceFile被描述为一个文件,其内容不会随着时间的推移而改变.那么SourceFile需要提供自定义实现吗?为什么不在interactive包中.我相信我只是没有抓到什么.

所以我现在的解决方案是再次调用compile方法.


FMa*_*008 0

可能不完全是您正在寻找的,但一种方法可能是:

  1. 将要编译的源代码写入临时文件,

  2. > output.tmp对命令运行编译后缀(*nix) 运算符,这会将编译器输出输出到文件中,

  3. 读取该文件并将其加载到内存中...

  4. 最后删除两个 tmp 文件。

我希望这不是唯一的解决方案,但如果没有其他可能,至少这应该可行......