わかりました、100 報奨金の 1 週間、まだ答えがないので、自分で試してみます...編集は大歓迎です!
プレゼンテーション コンパイラの主要なクラスはscala.tools.nsc.interactive.Global
. まず、コンパイラのインスタンスを作成する必要があります。
import scala.tools.nsc.interactive.Global
クラスPresentationCompiler {
// コンパイラ出力を仮想にしたい
val target = new VirtualDirectory("", None)
// 動作するように調整する必要があります
// sbt. この質問を参照してください。
val 設定 = 新しい設定()
// 仮想ターゲットに出力
settings.outputDirs.setSingleOutput(ターゲット)
// カスタムインスタンスに置き換えることができます
// AbstractReporter の制御を取得します。
val レポーター = 新しい ConsoleReporter(設定)
val コンパイラー = 新しいグローバル(設定、レポーター)
...
}
設定については、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
}
}
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
}
3. ソースファイルの変更をコンパイラに伝達する
これは興味深い部分です。この質問で知りたかったのです。BatchSourceFile
コンテンツが時間の経過とともに変化しないファイルとして説明されているため、これは本当にわかりません。のカスタム実装をSourceFile
提供する必要がありますか?? interactive
なぜそれがパッケージに入っていないのでしょうか。私は何かを捕まえなかったと確信しています。
したがって、今の私の解決策は、コンパイル メソッドを再度呼び出すことです。