这是我所面临的问题的简化版本,但潜在的问题仍然存在。 在调用宏之后,我想动态生成case类。我能够从宏调用等中检索参数。我遇到的问题是尝试在quasiquotes中使用字符串变量。我基本上想要有以下内容:
def expand_impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
val toGen = "case class Foo()"
val toReturn = c.Expr[Any](
q"$toGen"
)
toReturn
}
但是,不会生成案例类。现在我知道如果我将toGen更改为q“case class Foo()”它将起作用,但是toGen是一个字符串,我将在其他一些返回字符串的处理后生成,所以我不能这样做。 像这样编译并手动查看toReturn的值我得到以下内容:
Expr[Any]("case class Foo()")
字符串toGen简单地粘贴在引号中,意味着不生成案例类。
我找过类似的问题,但无法在任何地方找到这个例子。如何在quasiquotes中取消引用字符串变量的双引号?
答案 0 :(得分:4)
parse
上定义了Context
方法。它返回一个Tree
,因为树可以在quasiquotes中插值,所以你可以很容易地将解析与quasiquoting混合和匹配。
例如:
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.reflect.macros.whitebox.Context
import scala.language.experimental.macros
def test_impl(c: Context)(): c.Tree = {
import c.universe._
val tree = c.parse("""println(2)""")
q"println(1); $tree; println(3)"
}
def test(): Unit = macro test_impl
// Exiting paste mode, now interpreting.
import scala.reflect.macros.whitebox.Context
import scala.language.experimental.macros
test_impl: (c: scala.reflect.macros.whitebox.Context)()c.Tree
defined term macro test: ()Unit
scala> test()
1
2
3
在这个例子中,我定义了一个def宏,但它应该与宏注释一样好(如你的情况)。