将类作为参数传递给scala中的StaticAnnotation宏

将类作为参数传递给scala中的StaticAnnotation宏,scala,macros,Scala,Macros,我想将一个类作为参数传递给Scala中的StaticAnnotation宏,假设我需要一个检查DateTime实例的宏: class CheckDate(date: DateTime) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro CheckDate.impl } object CheckDate { def impl(c: Context)(annottees: c.Ex

我想将一个类作为参数传递给Scala中的
StaticAnnotation
宏,假设我需要一个检查DateTime实例的宏:

class CheckDate(date: DateTime) extends StaticAnnotation {
    def macroTransform(annottees: Any*): Any = macro CheckDate.impl
}

object CheckDate {
    def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
        import c.universe._

        ???
}
和执行:

@CheckDate(new DateTime(...))
class Sth(...) {...}

如何从AST检索DateTime实例?

经过一点调整后,我终于找到了一种方法来检索scala中
StaticAnnotation
宏的更复杂参数

首先,我通过
c.prefix.tree
上的模式匹配提取了所有参数,它实际上引用了注释类,如下所示:

val params = c.prefix.tree match {
  case q"""new CheckDate(...$paramss)""" => paramss
  case _ => c.warning(NoPosition, "Oops, something went terribly wrong!")
}
我试图通过打印带有
showRaw(params)
的树来检查树中的参数,有两种可能的模式(带或不带参数名):

为了使用
DateTime
对象,我们需要提取适当的字段并创建新的
DateTime
实例:

val d: DateTime = params match {
   case List(List(AssignOrNamedArg(
   _, Apply(_, List(Literal(Constant(y)), Literal(Constant(m)), Literal(Constant(d))))))) =>
       new DateTime(y.asInstanceOf[Int], m.asInstanceOf[Int], d.asInstanceOf[Int], 0, 0)
   case List(List(Apply(_, List(Literal(Constant(y)),
   Literal(Constant(m)), Literal(Constant(d)))))) =>
       new DateTime(y.asInstanceOf[Int], m.asInstanceOf[Int], d.asInstanceOf[Int], 0, 0)

事实上,有很多样板,但这种方法非常有效。关键是检查要分析的结构的AST,并为其创建适当的案例。

经过一点调整,我终于找到了一种方法,可以在scala中为
StaticAnnotation
宏检索更复杂的参数

首先,我通过
c.prefix.tree
上的模式匹配提取了所有参数,它实际上引用了注释类,如下所示:

val params = c.prefix.tree match {
  case q"""new CheckDate(...$paramss)""" => paramss
  case _ => c.warning(NoPosition, "Oops, something went terribly wrong!")
}
我试图通过打印带有
showRaw(params)
的树来检查树中的参数,有两种可能的模式(带或不带参数名):

为了使用
DateTime
对象,我们需要提取适当的字段并创建新的
DateTime
实例:

val d: DateTime = params match {
   case List(List(AssignOrNamedArg(
   _, Apply(_, List(Literal(Constant(y)), Literal(Constant(m)), Literal(Constant(d))))))) =>
       new DateTime(y.asInstanceOf[Int], m.asInstanceOf[Int], d.asInstanceOf[Int], 0, 0)
   case List(List(Apply(_, List(Literal(Constant(y)),
   Literal(Constant(m)), Literal(Constant(d)))))) =>
       new DateTime(y.asInstanceOf[Int], m.asInstanceOf[Int], d.asInstanceOf[Int], 0, 0)
事实上,有很多样板,但这种方法非常有效。关键是检查要解析的结构的AST,并为其创建适当的案例