处理宏注释时无法访问Parent的成员

jes*_*slg 8 macros code-generation annotations scala companion-object

我有点被以下(宏注释)情况阻止.假设我有一个被调用的注释@factory,它旨在为apply相应的伴随对象中的带注释的特征生成一个方法.例如,鉴于trait A:

@factory
trait A {
  val a1: Int
}
Run Code Online (Sandbox Code Playgroud)

要生成的预期代码如下:

object A extends Factory[A] {
  def apply(_a1: Int) = new A {
    val a1 = _a1
  }
}
Run Code Online (Sandbox Code Playgroud)

现在假设我们有一个特征B,它继承自A:

@factory
trait B extends A {
  val b1: String
}
Run Code Online (Sandbox Code Playgroud)

这应该产生:

object B extends Factory[B] {
  def apply(_a1: Int, _b1: String) = new B {
    val a1 = _a1
    val b1 = _b1
  }
}
Run Code Online (Sandbox Code Playgroud)

在后一种情况下,我需要知道存在哪些属性A,但我不知道如何获取有关它们的任何信息.在处理宏注释时,我只能访问B特征AST(作为a ClassDef).虽然它template包含了对父母(作为参考TypeTrees)两个字段,tpe并且symbol是空的.

对我来说访问AAST 会很棒.但是,我认为这是不可行的.因此,任何符号或类型(指向父类型或当前类型)都足够好.

如果您想查看更多实现细节,我已将项目上传到https://github.com/jesuslopez-gonzalez/cool-factory.它可以生成apply本地值.

Eug*_*ako 10

进入宏注释参数的树是有目的无类型的.但是,运行c.typeCheck(q"(??? : <tree that represents the parent>)").tpe将提供缺少的信息.duplicate在类型检查之前不要忘记那棵树,因为c.typeCheck将树变异到位,这可能是不可取的.

如果父和子都声明在同一个非顶层范围内,则会出现typeCheck看不到父节点的问题,因为宏注释中的c.typeCheck是在父词法范围内执行的,因此注释不会得到看半结构的范围.这里有类似的报道:https://github.com/aztek/scala-workflow/issues/2#issuecomment-23947943.

将当前范围从类型检查中排除的决定不是最终决定.本周我将更多地思考宏注释应如何与封闭范围进行交互,并且可能会将其更改为您希望它执行的操作.我现在正在做改变,但我需要确保不会因为这种改变而产生任何疯狂的行为.