4

「type」キーワードで定義された型を使用するマクロを使用したいと考えています。どのように参照すればよいですか?

私の開始コードは

import scala.reflect.macros.Context
import scala.language.experimental.macros

trait Demo6 {
  type T

  def add(param: Any): T = macro Demo6.addImpl[T]

  def fullAdd(param: Any, toStringBasedOnAST: String): T = {
    doesSomeThing_and_returnsSomething_OfTypeT
  }
  def doesSomeThing_and_returnsSomething_OfTypeT: T //just to allow compilation
}

object Demo6 {
  def addImpl[T: c.WeakTypeTag](c: Context)(param: c.Expr[Any]): c.Expr[T] = {
    import c.universe._
    reify { (c.Expr[Demo6](c.prefix.tree)).splice.fullAdd(param.splice, 
                                        c.literal(show(param.tree)).splice) }
    //        ^ - type mismatch; found : org.autotdd.scalamacros.Demo6#T 
    //                           required: T
  }
}

この例では、コンパイラ エラーをマークアップしました。何が起こっているかは明らかです。keyword で定義された型 T は、私が渡している型 T と同じではありません。

試したこと scala-macros に関するドキュメントはまだ多くありません。http://docs.scala-lang.org/overviews/macros/overview.htmlのセクションは、ここまで到達するのに非常に役立ちましたが、その例ではクラス レベルとメソッド レベルのジェネリックを使用しています。ドキュメントで参照されているプロジェクトである Expecty と macrocosm のコードを参照しましたが、このようなコードは見つかりませんでした。

4

1 に答える 1

4

あなたのコードはほぼ正しいです。型パラメータを変更するだけですExpr:

val expr = reify { ... }
c.Expr[T](expr.tree)

reifyあなたがこれを返す必要がなければ:

c.Expr[T](Apply(Select(c.prefix.tree, newTermName("fullAdd")),
                List(param.tree, Literal(Constant(show(param.tree))))))

reify同じものを作成しますが、型パラメーターが間違っています。

使用方法については、この回答を参照してくださいshowRaw

この場合:

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> {
     |   object Demo { def fullAdd(param1: Any, param2: String): String = "result" }
     |   showRaw{ reify { Demo.fullAdd("param1", "param2") } }
     | }
res0: String = Expr(Apply(Select(Ident(newTermName("Demo")), newTermName("fullAdd")), List(Literal(Constant("param1")), Literal(Constant("param2")))))

、およびに置き換えるIdent(newTermName("Demo"))c.prefix.tree、結果が得られます。Literal(Constant("param1"))param.tree"param2"show(param.tree)

于 2013-05-08T10:39:50.837 に答える