26

次のタスクを実行する現在の scala プレゼンテーション コンパイラ (つまり ) を使用する最小限の例を誰か提供できますか?scala.tools.nsc.interactive.Global

  • 単一の仮想ソース ファイルをコンパイルします (つまり、ファイル システムではなく、たとえば a String) 。
  • コンパイラからすべてのフェーズの結果情報を取得する
  • ソースファイルの変更をコンパイラに伝達する
  • おそらく非同期で追加情報を受け取る

には多くの変動があるようで、nsc最新の小さな例を見つけることができませんでした。ですから、ここであなたの助けをいただければ幸いです。

4

3 に答える 3

10

わかりました、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なぜそれがパッケージに入っていないのでしょうか。私は何かを捕まえなかったと確信しています。

したがって、今の私の解決策は、コンパイル メソッドを再度呼び出すことです。

于 2013-05-22T21:28:09.190 に答える
2

以下のリンクが役立つかもしれません

https://github.com/twitter/util/blob/master/util-eval/src/main/scala/com/twitter/util/Eval.scala

あなたが求めているすべての要件を満たしていると思います。:)

于 2013-10-25T05:16:09.203 に答える
0

まさにあなたが探しているものではないかもしれませんが、それを行う 1 つの方法は次のとおりです。

  1. コンパイルしたいソースを一時ファイルに書き込み、

  2. コンパイル サフィックス> output.tmp(*nix) 演算子をコマンドに実行します。これにより、コンパイラ出力がファイルに出力されます。

  3. そのファイルを読み取り、メモリにロードします...

  4. 最後に、両方の tmp ファイルを削除します。

これが唯一の解決策ではないことを願っていますが、他に何もできない場合は、少なくともこれでうまくいくはずです...

于 2013-05-18T05:05:45.123 に答える