Scala 宏:c.universe.Tree 到 c.universe.Name
Scala Macros: c.universe.Tree to 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
,我们可以在我们生成的代码中使用。
我正在尝试使用宏和静态注释生成案例 类。
有什么方法可以将 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
,我们可以在我们生成的代码中使用。