经过一番调整,我终于找到了一种在 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) 打印树来检查树的参数,并且有两种可能的模式(带或不带参数名称):
List(List(AssignOrNamedArg(
Ident(TermName("date")),
Apply(Select(New(Ident(TypeName("DateTime"))), termNames.CONSTRUCTOR),
List(Literal(Constant(2016)), Literal(Constant(5)), Literal(Constant(10)))))))
或
List(List(Apply(
Select(New(Ident(TypeName("DateTime"))), termNames.CONSTRUCTOR),
List(Literal(Constant(2016)), Literal(Constant(5)), Literal(Constant(11))))))
为了使用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 并为其创建适当的案例。