1

リフレクションAPIを使用してASTを手動で生成しようとしています。また、showRawを使用して、必要な構文に関するヒントを提供しています。このコード:

object myfn extends Function2[ Double, Double, Double ] {
    def apply( x : Double, y : Double ) = x + y
}

val x = 0.0
println( showRaw( reify( myfn( x, x ) ).tree ) )

生のAST出力を提供します。

Apply(Select(Ident(myfn), newTermName("apply")), 
    List(Ident(newTermName("x")), Ident(newTermName("x"))))

生の出力のリテラルテキストをプログラムに戻すと、コンパイルされません。

val v = Apply(Select(Ident(myfn), newTermName("apply")), 
    List(Ident(newTermName("x")), Ident(newTermName("x"))))
// ^ doesn't compile

Identは明らかに引数として文字列を必要とするためです。文字列「myfn」を渡すと、

val v = Apply(Select(Ident("myfn"), newTermName("apply")), 
    List(Ident(newTermName("x")), Ident(newTermName("x"))))

runtimeMirror( getClass.getClassLoader ).mkToolBox().eval( v )

コンパイルされますが、実行時に評価が失敗します。

"scala.tools.reflect.ToolBoxError: reflective compilation has failed: 
value apply is not a member of <notype>
[...]

したがって、生のAST出力のmyfnの実際のタイプは、おそらくString以外のものですが、APIドキュメントからはそれが何であるかは明らかではありません。

だから、誰かが私が必要なASTを構築する方法を教えてもらえますか?

4

1 に答える 1

1

私はそれを少し違ったものにしました.1つの問題は、値xがグローバルに知られていないことでもあります.そのため、簡単に置き換えることができる定数値を使用しました. また、呼び出しmyfnに対してグローバルレベルで定義されているかどうかもわかりません。evalここにある小さなサンプル プログラムが動作するようになりました (最新の 2.10.1-RC3 でコンパイルされていますが、何か修正されているのでしょうか?)。

import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox

object myfn extends Function2[Double, Double, Double] {
  def apply(x: Double, y: Double) = x + y
  def printTree {println(showRaw(reify(myfn(1.0, 2.0)).tree))}
}

object ReflectTest extends App {
  myfn.printTree // prints the tree that is used below - myfn is replaced with "myfn"
  val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
  println("result = " + tb.eval(Apply(Select(Ident("myfn"), newTermName("apply")), List(Literal(Constant(1.0)), Literal(Constant(2.0))))))
}

編集

以下のコメントの後に、mypackageドットを含む任意のパッケージ パスである別のパッケージを含む呼び出しがあります。

tb.eval(Apply(
  Select(Select(Ident(newTermName("mypackage")), newTermName("myfn")), newTermName("apply")), 
  List(Literal(Constant(1.0)), Literal(Constant(2.0)))))
于 2013-03-12T19:22:43.140 に答える