1
我想使用宏和静态注释生成case类。斯卡拉宏:c.universe.Tree到c.universe.Name
有什么办法可以将c.universe.Tree
转换成另一种c.universe
类型,特别是c.universe.Name
?
我想使用宏和静态注释生成case类。斯卡拉宏:c.universe.Tree到c.universe.Name
有什么办法可以将c.universe.Tree
转换成另一种c.universe
类型,特别是c.universe.Name
?
答案取决于你有什么样的树,但在任何情况下,你想从你的树去一个字符串,然后你可以创建无论是TypeName
或TermName
与TypeName
和TermName
构造。
例如,我们这里的树是一个字符串:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
def callFooImpl(c: Context)(name: c.Expr[String]): c.Expr[Unit] = {
import c.universe._
val termName: TermName = name.tree match {
case Literal(Constant(s: String)) => TermName(s)
case _ => c.abort(c.enclosingPosition, "Not a string literal")
}
c.Expr[Unit](q"$termName.foo()")
}
def callFoo(name: String): Unit = macro callFooImpl
case class Foo(i: Int) {
def foo(): Unit = println(s"Called foo() on $this")
}
然后:
scala> :paste
// Entering paste mode (ctrl-D to finish)
val myFoo = Foo(10)
callFoo("myFoo")
// Exiting paste mode, now interpreting.
Called foo() on Foo(10)
myFoo: Foo = Foo(10)
这里我们解构字符串文字树Literal
和Constant
得到一个编译期然后我们用它来创建一个TermName
,我们可以在我们生成的代码中使用它。
这起作用。谢谢! –
什么样的树?你想用这个名字做什么? –
@TravisBrown我想使用它作为从宏内生成的新案例类的名称。理想情况下,案例类用参数列表进行注释,这些参数将被剥离以生成新的案例类定义。 –
树是字符串文字吗? –