Scala 3 美味反射宏:CyclicReference
Scala 3 Tasty Reflection Macro: CyclicReference
我正在尝试访问作为宏实现的方法的参数。
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 _ =>
nearestEnclosingMethod(owner.owner)
}
nearestEnclosingMethodParams(Symbol.spliceOwner)
}
println(params) // I would do something useful with params names and types here
'{()}
}
}
呼叫站点可能类似于:
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() }
}
目前,当宏在 defSym.tree
上扩展时,我遇到了 CyclicReference
错误。我知道 defSym.tree
是循环的,因为它包含当前扩展宏的代码,但我仍然需要访问方法定义的“树”版本以访问其名称和参数,而无需方法的主体。我如何在不骑自行车的情况下获取这些信息?
此问题已在最近发布的 Scala 3.0.0-RC1 版本中修复。
在 def foo(a: String, b: Int) = Foo.impl
示例中使用 defSym.tree
现在可以正常工作,并且只对宏主体使用 EmptyTree
。您可以轻松地从方法参数或定义了 foo
的类型层次结构中提取所需的任何信息,这是我的用例。
DefDef(
foo,
List(
List(
ValDef(
a,
TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object Predef),type String)],
EmptyTree
),
ValDef(
b,
TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),class Int)],
EmptyTree
)
)
),
TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit)],
EmptyTree
)
我正在尝试访问作为宏实现的方法的参数。
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 _ =>
nearestEnclosingMethod(owner.owner)
}
nearestEnclosingMethodParams(Symbol.spliceOwner)
}
println(params) // I would do something useful with params names and types here
'{()}
}
}
呼叫站点可能类似于:
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() }
}
目前,当宏在 defSym.tree
上扩展时,我遇到了 CyclicReference
错误。我知道 defSym.tree
是循环的,因为它包含当前扩展宏的代码,但我仍然需要访问方法定义的“树”版本以访问其名称和参数,而无需方法的主体。我如何在不骑自行车的情况下获取这些信息?
此问题已在最近发布的 Scala 3.0.0-RC1 版本中修复。
在 def foo(a: String, b: Int) = Foo.impl
示例中使用 defSym.tree
现在可以正常工作,并且只对宏主体使用 EmptyTree
。您可以轻松地从方法参数或定义了 foo
的类型层次结构中提取所需的任何信息,这是我的用例。
DefDef(
foo,
List(
List(
ValDef(
a,
TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object Predef),type String)],
EmptyTree
),
ValDef(
b,
TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),class Int)],
EmptyTree
)
)
),
TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit)],
EmptyTree
)