4

次のインスタンスを使用して、プログラムで Scala ファイルをコンパイルしようとしていますGlobal.Run

val settings = new Settings                 
val reporter = new ConsoleReporter(settings)
val compiler = new Global(settings, reporter)
val run = new compiler.Run // MissingRequirementError
run compile List(path)

残念ながら、私はMissingRequirementError言います:

コンパイラ ミラー内のオブジェクト scala.runtime が見つかりません

だから私の質問は、クラスを使用してプログラムでファイルをコンパイルする方法Run、またはここで何が間違っているのですか?

settings動作させるために を変更できるかどうかを調べてみました。実際には、Scala ファイルにあるクラスのリストが必要ですがpath、完全に実行可能な出力である必要はありません。したがって、シンボルが未解決のままであれば問題ありません (コンパイラ フェーズのサブセットを実行できれば)。

私もWriting Scala Compiler Pluginsにいますが、 Compiler Run オブジェクトをインスタンス化して実行できるのであれば、このソリューションを好むでしょう。私も偶然出くわしました Scalaコンパイラは再入可能ですか? (同様のコード、別の質問)、私が考えているように機能する可能性があると思います。

編集 1: Scala JAR をに追加しましたtoolcp(絶対パスを使用したサンプル コードだけです!)

コメントによると、scalac.batのクラスパス生成スクリプトを Scala コードに適合させました。

// scalac.bat
// if "%_TOOL_CLASSPATH%"=="" (
//   for %%f in ("!_SCALA_HOME!\lib\*") do call :add_cpath "%%f"
//   for /d %%f in ("!_SCALA_HOME!\lib\*") do call :add_cpath "%%f"
// )
new File("C:\\Program Files\\scala\\lib").listFiles.foreach(f => {
  settings.classpath.append(f.getAbsolutePath)
  settings.toolcp.append(f.getAbsolutePath)
})
4

1 に答える 1

2

bootclasspathの代わりに使用して、実行しましtoolcpた(ペドロフルラのヒントのおかげで):

val settings = new Settings
new File("C:\\Program Files\\scala\\lib").listFiles.foreach(f => {
  settings.classpath.append(f.getAbsolutePath)
  settings.bootclasspath.append(f.getAbsolutePath)
})

private val reporter = new ConsoleReporter(settings)
private val compiler = new Global(settings, reporter)

val run = new compiler.Run
run compile List(path)

コンパイラはファイルをコンパイルしようとします。ただし、これは正確にはそうではないようscalac.batです。-cpこれは通常のクラスパスである で始まりますが、 はコンソールでbootclasspath渡され、トレイトに表示されます:-bootclasspathStandardScalaSettings

val bootclasspath = PathSetting ("-bootclasspath", "Override location of bootstrap class files.", Defaults.scalaBootClassPath)
于 2012-12-03T17:07:27.680 に答える