Scala宏:检查某个注释

Scala宏:检查某个注释,scala,annotations,scala-macros,Scala,Annotations,Scala Macros,由于对的回答,我能够创建一个函数宏,这样它将返回一个Map,该映射将每个字段名映射到其类的值,例如 ... trait Model case class User (name: String, age: Int, posts: List[String]) extends Model { val numPosts: Int = posts.length ... def foo = "bar" ... } 所以这个命令 val myUser = User("Foo", 2

由于对的回答,我能够创建一个函数宏,这样它将返回一个
Map
,该映射将每个字段名映射到其类的值,例如

...

trait Model

case class User (name: String, age: Int, posts: List[String]) extends Model {
  val numPosts: Int = posts.length

  ...

  def foo = "bar"

  ...
}
所以这个命令

val myUser = User("Foo", 25, List("Lorem", "Ipsum"))

myUser.asMap
返回

Map("name" -> "Foo", "age" -> 25, "posts" -> List("Lorem", "Ipsum"), "numPosts" -> 2)
这是生成
Map
Tuple
s的地方(参见Travis Brown的):

现在我想忽略带有
@transient
注释的字段。如何检查方法是否具有
@transient
注释

我正在考虑将上面的代码片段修改为

val pairs = weakTypeOf[T].declarations.collect {
   case m: MethodSymbol if m.isAccessor && !m.annotations.exists(???) =>
      val name = c.literal(m.name.decoded)
      val value = c.Expr(Select(model, m.name))
      reify(name.splice -> value.splice).tree
}
但是我找不到我需要在
存在部分中编写的内容。如何将
@transient
作为
注释
传递到那里


提前谢谢

注释将位于
val
本身,而不是访问器上。访问
val
的最简单方法是通过
MethodSymbol
上的
accessed
方法:

def isTransient(m: MethodSymbol) = m.accessed.annotations.exists(
  _.tpe =:= typeOf[scala.transient]
)
现在,您可以在您的
collect
中编写以下内容:

case m: MethodSymbol if m.isAccessor && !isTransient(m) =>

请注意,我在这里给出的
isTransient
版本必须在宏中定义,因为它需要从
c.universe
导入,但是如果在多个宏中执行此类操作,则可以通过添加
universe
参数将其分解

再次感谢!我似乎无法获得注释。在上面的示例类中,我在
name
numPosts
之前添加了
@transient
,但它们仍然添加到映射中。奇怪的是,通过
的方法中似乎没有任何一个是瞬态的。
m.accessed.annotations
m.annotations
都是空的。这很奇怪,在这两种情况下,它对我都有效。你能把你的确切密码发出来吗?这是密码。请注意,我在这里构建了一些稍有不同的东西——给定包下所有字段和case类的字段类型的映射。问题是没有WeakTypeTag吗?提前谢谢。今天开始自己工作。。。我不知道发生了什么事。谢谢你的回答。@EugeneBurmako,没错。这正是问题所在。我刚刚发现调用
println(m+”,“+m.typeSignature+”->“+m.accessed.annotations.foreach(a=>println(a.tpe))
可以使宏工作,而
println(m+”->“+m.accessed.annotations.foreach(a=>println(a.tpe))
不会显示任何内容。我是来报案的。真是巧合,我用了确切的方法找出了问题所在。非常感谢。那是一个令人讨厌的问题!:)
case m: MethodSymbol if m.isAccessor && !isTransient(m) =>