Je suis en train d'essayer d'accéder aux paramètres d'une méthode qui est implémentée en tant que macro.
object Macros {
def impl()(using Quotes): Expr[Unit] = {
import quotes.reflect._
val params: List[List[ValDef]] = {
def nearestEnclosingMethodParams(owner: Symbol): List[List[ValDef]] =
owner match {
case defSym if defSym.isDefDef =>
defSym.tree.asInstanceOf[DefDef].paramss
case _ =>
nearestEnclosingMethodParams(owner.owner)
}
nearestEnclosingMethodParams(Symbol.spliceOwner)
}
println(params) // Je ferais quelque chose d'utile avec les noms et les types des paramètres ici
'{()}
}
}
Le site d'appel pourrait ressembler à quelque chose comme :
object Test {
def foo(a: String, b: Int) = Foo.impl
@main def run(): Unit = {
val x = foo("blah", 24)
()
}
}
object Foo {
inline def impl = ${ Macros.impl() }
}
Pour l'instant, j'obtiens une erreur CyclicReference
lorsque la macro se développe, sur defSym.tree
. Je comprends que defSym.tree
est cyclique car il inclut le code de la macro en cours d'expansion, mais j'ai toujours besoin d'accéder à une version "arborescente" de la définition de la méthode pour accéder à son nom et ses paramètres, sans le corps de la méthode. Comment puis-je obtenir cette information sans boucler ?