I need to convert an Expr
to a Tree
doing Scala 3 macro development, and I did not yet find an appropriate conversion mechanism for that.
In Scala 2 there existed a tree
method on Expr
which made this task easy as I see, like this:
def expr_impl(c: blackbox.Context)(expr: c.Expr[AnyRef]): c.Expr[Expression] = {
import c.universe._
expr.tree match {
//...
}
}
But this method seems to be removed in Scala 3.
I need this to examine the results of using a Quotes expression.
If I use showRaw
, the output is not verbose, which is a problem is my case:
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)}")
This results in a non-verbose output like this: from macro annotation1 '{ ... }
Also tried Printer.TreeStructure.show
, which expects a Tree
instead of Expr
, and that's why I need the mentioned conversion, as Printer.TreeStructure.show
would result in a verbose output.
If there is any method that is verbose and similar to Printer.TreeStructure.show
and expects an Expr
as an argument, that would also solve my problem.
I wouldn't say .tree
was removed - Scala 3's Quotes should be consider completely new implementation which can have some counterparts to Scala 2's Contexts content but not always and even when it has, it might be named differently.
To turn Expr[A]
into quotes.reflect.Tree
you should call .asTerm
on it - Term
is a subtype of Tree
.
And to print AST in raw form rather than a pretty print, one can provide (using Printer.TreeStructure)
to the show
extension method (available when you convert Expr
to Term
and import things from 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))
'{ () }
}