【问题标题】:How can I specify the order of macro annotation expansion of multiple classes?如何指定多个类的宏注解展开顺序?
【发布时间】:2014-05-07 07:11:17
【问题描述】:

假设我有两个带有宏注释的类,并且在扩展期间定义了它们的字段之后,一个依赖于另一个:

@Annotation case class A(i: Int) @Annotation case class B(a: A)

我需要在B 之前扩展A,但它们的定义顺序并不能确保这一点。

例如,将B 作为类型参数引用到不相关的编译单元中的对象,例如:

class X{val b = B(A(1))} 在一个文件中,class Y{Z[B]} 在另一个文件中,

导致B首先被扩展,因此我的编译失败。

在这种情况下,是什么决定了宏展开的顺序?有什么方法可以强制执行所需的命令?

感谢您的意见,

朱利安

【问题讨论】:

  • 您能详细说明您的用例吗? Annotation 宏有什么作用?也许你可以分享一些代码?
  • 感谢您的回复,并为我的延误道歉。该代码使案例类 Avro 可序列化,部分是通过将其转换为 Schema 对象并将其存储以备不时之需。如果一个字段的类型是另一个案例类,那么那个其他案例类需要已经被存储了。
  • This branch 是一个最小化的示例,它表明扩展顺序不仅取决于在给定文件中首先被引用,还取决于引用文件名的词法顺序。即,将A.scala 重命名为Z.scala,使其在词法上遵循Test.scala,编译将成功。

标签: scala annotations scala-macros scala-macro-paradise


【解决方案1】:

typecheck 是我的解决方案。

如果类型 A(A 的 tree.tpe)在其宏展开之前用于编译时反射,则一旦发现它就可以展开:

import c.universe._
import Flag._

def expandType(typeTree: Tree) = {
  c.typecheck(q"type T = $typeTree") match {
    case x @ TypeDef(mods, name, tparams, rhs)  => rhs.tpe
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多