【问题标题】:Scala 3 Tasty Reflection Macro: CyclicReferenceScala 3 美味的反射宏:CyclicReference
【发布时间】:2021-05-17 12:35:55
【问题描述】:

我正在尝试访问作为宏实现的方法的参数。

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 scala-macros dotty scala-3


    【解决方案1】:

    此问题已在最近发布的 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
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2022-08-04
      • 1970-01-01
      • 2013-01-17
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 2010-12-22
      相关资源
      最近更新 更多