scala - 将字符串插值器宏包装在另一个中
问题描述
我有插值xxx
器由宏实现(我拥有代码)并返回 XXX。yyy
当我有函数时,我想实现插值器f: XXX => YYY
编码
class XXXMacro(val c: blackbox.Context) {
import c.universe._
final def xxx(args: c.Expr[Any]*): c.Expr[XXX] = {
val Apply(_, Apply(_, parts) :: Nil) = c.prefix.tree
???
}
}
implicit class XXXInterpolator(sc: StringContext) {
def xxx(args: Any*): XXX = macro XXXMacro.xxx
}
class YYYMacro(val c: blackbox.Context) {
import c.universe._
final def yyy(args: c.Expr[Any]*): c.Expr[YYY] = q"yyy($xxx\"args\")"
}
implicit class YYYInterpolator(sc: StringContext) {
def yyy(args: Any*): YYY = macro XXXMacro.yyy
}
问题是我不能轻易参数化代码。编译器不会让我做macro XXXMacro(f).yyy
or macro XXXMacro.yyy(f)
。
此外,当我将它像宏中的上下文一样包装时,它def yyy(args: Any*): YYY = f(new XXXInterpolator(sc).xxx(args))
完全不同并使其复杂化,我无法重用它。有什么办法让它更容易吗?
解决方案
我不希望 XXXMacro 依赖于 YYY。所以解决方案是用户trait
和 Tree
trait XXXMacroTree {
val c: blackbox.Context
import c.universe._
final def xxxTree(args: c.Expr[Any]*): Tree = ???
final def xxx(args: c.Expr[Any]*): c.Expr[XXX] = c.Expr[XXX](xxxTree(args: _*))
}
class XXXMacro(val c: blackbox.Context) extends XXXMacroTree
implicit class XXXInterpolator(sc: StringContext) {
def xxx(args: Any*): XXX = macro XXXMacro.xxx
}
class YYYMacro(val c: blackbox.Context) extends XXXMacroTree {
import c.universe._
final def yyy(args: c.Expr[Any]*): c.Expr[YYY] = c.Expr[YYY](q"f(${xxxTree(args: _*)}))
}
implicit class YYYInterpolator(sc: StringContext) {
def yyy(args: Any*): YYY = macro YYYMacro.yyy
}
推荐阅读
- google-apps-script - Pull-down list by another answer in Google Form
- angular - Can We add hash(#) after query params(with ?) in Angular 4/6 routing?
- ios - TTTAttributedLabel didSelectLink 没有在 swift 4.0 中调用
- jquery - Bootstrap 4 下拉菜单在使用 create-react-app 生成的项目中不起作用
- java - 无法为事务打开 JDBC 连接
- java - 找不到 Spring 安全类 DefaultLogoutPageGeneratingFilter
- java - Log4j 不创建日志文件
- android - 在 Android Studio / IntellIJ 中调整 png 图标的大小
- sql - 计数值检查是否连续
- resharper - Resharper StackOverflowException