Класс vs Тип аннотации с Shapeless - PullRequest
0 голосов
/ 17 апреля 2019

Согласно документации scala существует четыре вида аннотаций:

  1. Аннотации классов: @ClassAnnotation case class Foo(...)
  2. Переменные / аннотации значений: @ValAnnotation val field: String
  3. Тип аннотации: field: String @TypeAnnotation
  4. Аннотации выражений

Используя shapeless.Annotation и shapeless.Annotations, легко получить аннотации класса и переменной (1 и 2) из ​​тематического класса.Как получить аннотации типа его полей (3)?

Пример:

@ClassAnnotation
case class Foo(
  @ValAnnotation field: String @TypeAnnotation
)

1 Ответ

2 голосов
/ 17 апреля 2019

Вы можете написать макрос

import scala.language.experimental.macros
import scala.reflect.macros.blackbox

def getAnnotation[A]: Any = macro impl[A]

def impl[A: c.WeakTypeTag](c: blackbox.Context): c.Tree = {
  import c.universe._

  println(weakTypeOf[A].typeSymbol.annotations) // List(ClassAnnotation)

  println(weakTypeOf[A]
    .member(termNames.CONSTRUCTOR)
    .asMethod
    .paramLists
    .map(_.map(_.annotations))
  ) // List(List(List(ValAnnotation)))

  println(weakTypeOf[A]
    .member(termNames.CONSTRUCTOR)
    .asMethod
    .paramLists
    .map(_.map(_.typeSignature match {
      case AnnotatedType(annots, _) => annots
      case _ => List()
    })) // List(List(List(TypeAnnotation)))
  )

  q""
}

import scala.annotation.StaticAnnotation

case class ClassAnnotation() extends StaticAnnotation
case class ValAnnotation() extends StaticAnnotation
case class TypeAnnotation() extends StaticAnnotation

@ClassAnnotation
case class Foo(
                @ValAnnotation field: String @TypeAnnotation
              )

getAnnotation[Foo]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...