2013-05-14 59 views
25

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

  • 编译单个虚拟源文件(即,不是在文件系统中,但例如String
  • 检索来自编译器
  • 所有阶段所得到的信息的源文件中传播的变化编译器
  • 得到进一步的信息可能异步

似乎是在很多波动和我找不到最新的小例子。所以我非常感谢你的帮助。

+2

嗨这个链接到Eclipse插件可能有助于https://github.com/scala-ide/scala-ide/blob/master/org.scala-ide.sdt.core/src/scala/tools/eclipse /ScalaPresentationCompiler.scala – Iraklis 2013-05-16 13:15:32

+0

@Iraklis这确实是一个有用的链接。我之前看过它,但集成了很多特定于eclipse的功能,我不太明白它的意思......我想单独使用演示编译器。还有[关于ENSIME的博客文章](http://ensime.blogspot.de/2010/08/building-ide-with-scala-presentation.html),但这确实是过时的。 – 2013-05-16 13:29:14

+2

您可能还想检查交互式编译器的测试https://github.com/scala/scala/tree/b380f9ecbe1be8ffaf0f32001e95566747017294/src/interactive/scala/tools/nsc/interactive/tests – Iraklis 2013-05-16 14:14:47

回答

0

也许不正是你所寻找的,但要做到这一点可能是一个办法:

  1. 写上你要编到一个临时文件的源,

  2. 运行汇编后面添加> output.tmp(* nix中)操作者的命令,该命令应该输出的编译器输出到文件中,

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

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

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

9

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

表示编译器的关键类是scala.tools.nsc.interactive.Global。所以要开始,我们需要创建一个编译器的实例。

 
import scala.tools.nsc.interactive.Global
class PresentationCompiler { // we want the compiler output to be virtual val target = new VirtualDirectory("", None)
// need to be adjusted in order to work with // sbt. See this question . val settings = new Settings() // output to virtual target settings.outputDirs.setSingleOutput(target)
// can be replaced by a custom instance // of AbstractReporter to gain control. val reporter = new ConsoleReporter(settings)
val compiler = new Global(settings, reporter)
... }

对于设置the link provided by Abhishek是非常有价值的。

但现在最有趣的部分:

1.编译单个虚拟源文件

要编译字符串有创造与下面VirtualFile一个BatchSourceFile的可能性。 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 
    } 
} 

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

这是棘手的部分。由于编译器的多线程特性以及标志在不同阶段的不同含义中重复使用的事实,不可能一次完成所有内容。基本上,您将不得不求助于种类的方法,这些方法记录在API中。例如:

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 
} 

3.传播到编译器

这是最有趣的部分源文件中的变化,我想了解这个问题。我真的没有得到这个,因为BatchSourceFile被描述为内容不随时间变化的文件。因此需要提供SourceFile的自定义实现?为什么不在interactive包中。我相信我只是没有抓到一些东西。

所以我现在的解决方案是再次调用编译方法。