我需要将 az
Expr
转换为 Tree
进行 Scala 3 宏开发,但我还没有找到合适的转换机制。
在 Scala 2 中,
tree
上存在一个 Expr
方法,正如我所见,这使得这项任务变得简单,如下所示:
def expr_impl(c: blackbox.Context)(expr: c.Expr[AnyRef]): c.Expr[Expression] = {
import c.universe._
expr.tree match {
//...
}
}
但是这个方法似乎在Scala 3中被删除了。
我需要它来检查使用 Quotes 表达式的结果。 如果我使用
showRaw
,输出并不详细,这是我的情况的问题:
import scala.quoted.*
import scala.reflect.runtime.universe.showRaw
import quotes.reflect.*
//...
val obj: Expr[_] = '{object AnObject}
report.error(s"from macro annotation1 ${showRaw(obj)}")
这会产生如下非详细输出:
from macro annotation1 '{ ... }
还尝试了
Printer.TreeStructure.show
,它需要一个Tree
而不是Expr
,这就是为什么我需要提到的转换,因为Printer.TreeStructure.show
会导致详细的输出。
如果有任何冗长且类似于
Printer.TreeStructure.show
的方法,并且期望 Expr
作为参数,那也可以解决我的问题。
我不会说
.tree
已被删除 - Scala 3 的 Quotes 应该被视为全新的实现,它可以有一些与 Scala 2 的 Contexts 内容相对应的内容,但并非总是如此,即使有,它的命名也可能不同。
要将
Expr[A]
转换为 quotes.reflect.Tree
,您应该调用 .asTerm
- Term
是 Tree
的子类型。
要以原始格式而不是漂亮的打印方式打印 AST,可以向
(using Printer.TreeStructure)
扩展方法提供 show
(当您将 Expr
转换为 Term
并从 Quotes
导入内容时可用):
inline def printExpr[A](a: A): Unit = ${ printExprImpl[A]('{ a }) }
def printExprImpl[A: Type](expr: Expr[A])(using quotes: Quotes): Expr[Unit] = {
import quotes.*, quotes.reflect.*
report.info(expr.asTerm.show(using Printer.TreeStructure))
'{ () }
}