斯卡拉宏:检查一定的注解 [英] Scala Macros: Checking for a certain annotation

查看:133
本文介绍了斯卡拉宏:检查一定的注解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢答案我的previous问题,我能够创建一个函数宏,使得它返回每个字段名称映射到它的一类值地图,例如:

Thanks to the answers to my previous question, I was able to create a function macro such that it returns a Map that maps each field name to its value of a class, e.g.

...

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)

这是其中元组 S为地图生成(见特拉维斯布朗的answer ):

This is where Tuples for the Map are generated (see Travis Brown's answer):

...

val pairs = weakTypeOf[T].declarations.collect {
  case m: MethodSymbol if m.isAccessor =>
    val name = c.literal(m.name.decoded)
    val value = c.Expr(Select(model, m.name))
    reify(name.splice -> value.splice).tree
}

...

现在我想略过 @Transient 注释字段。我将如何检查的方法有一个 @Transient 注释?

Now I want to ignore fields that have @transient annotation. How would I check if a method has a @transient annotation?

我想修改上面的代码片段作为

I'm thinking of modifying the snippet above as

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 注释,所以我可以通过它呢?

but I can't find what I need to write in exists part. How would I get @transient as an Annotation so I could pass it there?

在此先感谢!

推荐答案

注释将在 VAL 本身,而不是在存取。最简单的方法来访问 VAL 是通过 MethodSymbol 访问方法$ C>:

The annotation will be on the val itself, not on the accessor. The easiest way to access the val is through the accessed method on MethodSymbol:

def isTransient(m: MethodSymbol) = m.accessed.annotations.exists(
  _.tpe =:= typeOf[scala.transient]
)

现在,你可以只写在下面的收集

Now you can just write the following in your collect:

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

请注意, isTransient 我在这里给有版本的宏定义,因为它从 c.universe需要进口,但你可以通过添加如果你做这种事情在几个宏宇宙参数因素出来。

Note that the version of isTransient I've given here has to be defined in your macro, since it needs the imports from c.universe, but you could factor it out by adding a Universe argument if you're doing this kind of thing in several macros.

这篇关于斯卡拉宏:检查一定的注解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆