MacroAnnotation从方法的类型成员中删除注释

问题描述

我正在学习如何编写Scala宏并编写了宏注释,该宏注释从带注释的函数的类型参数中删除了注释。在这里

删除的注释

FileUploadSerializer

用于删除注释的宏的实现

class garbage extends StaticAnnotation

测试方法

@compileTimeOnly("Compile-time only annotation")
class removeGarbage extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro impl
}

object removeGarbage {
  def impl(c: whiteBox.Context)(annottees: c.Tree*) = {
    import c.universe._
    println(annottees)
    val expandee = annottees.toList collect {
      case q"$mods def $templatename[..$typeparams](...$paramss): $tpt = $body" =>
        val modifiedParams = typeparams collect {
          case q"$mods type $name[..$args] = $tpt" =>
            val modifiedMods = mods match {
              case Modifiers(flags,privateWithin,annots) =>
                Modifiers(flags,annots.filter(_ == q"new garbage()"))
            }
            q"$modifiedMods type $name[..$args] = $tpt"
        }
        q"$mods def $templatename[..$modifiedParams](...$paramss): $tpt = $body"
      case annottee =>
        c.abort(c.enclosingPosition,s"$annottee cannot be annotated with @removeGarbage. Only def methods are allowed")
    }
    println(expandee)
    q"..$expandee"
  }
}

这似乎很好。为了进行检查,我将添加的日志与trait Test{ @removeGarbage def someMethod[@garbage Source,G[_]](i: Int): G[List[Int]] } println(annottees)进行了比较:

println(expandees)

解决方案的问题 是它似乎很难阅读。也许我没有充分利用准报价。有没有一种方法可以简化宏的实现(可能更广泛地使用准引用...)?

解决方法

没关系让宏代码难以阅读:) 这就是为什么元编程不应该成为工具#1的原因。

我看不到如何大幅减少您的代码。

您可以替换

val modifiedMods = mods match {
  case Modifiers(flags,privateWithin,annots) =>
    Modifiers(flags,annots.filter(_ == q"new garbage()"))
}

单线

val modifiedMods = mods.mapAnnotations(_.filter(_ == q"new garbage()"))

如果您在许多宏中继续进行相同的转换,则可以类似地定义辅助方法,例如mapDefmapTypeParams ...

如果准引号变得过于繁琐,您can consider可以使用ClassDefTemplateDefDef ...代替准引号,或在方便时将它们与准引号混合。 >

(这些问题通常是针对https://codereview.stackexchange.com/的,尽管元编程似乎在not so中很流行。)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...