Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define and use custom annotations in Scala

Tags:

scala

I am trying use a custom annotation in Scala. In this example, I create a string that I want to annotate with metadata (in this case, another string). Then, given an instance of the data, and I want to read the annotation.

scala> case class named(name: String) extends scala.annotation.StaticAnnotation
defined class named

scala> @named("Greeting") val v = "Hello"
v: String = Hello

scala> def valueToName(x: String): String = ???
valueToName: (x: String)String

scala> valueToName(v) // returns "Greeting" 

Is this even possible?

like image 576
Landon Kuhn Avatar asked Feb 15 '16 22:02

Landon Kuhn


People also ask

What are annotations in Scala?

Scala Annotations are metadata added to the program source code. Annotations are allowed on any kind of definition or declaration including vals, vars, classes, objects, traits, defs and types. Annotations are used to associate meta-information with definitions.

What is the use of custom annotations in Java?

Custom annotation is a user-defined annotation to provide metadata. We can use it when we want to store the custom meta for class, methods, constructor or field.


2 Answers

With scala 2.11.6, this works to extract values of a annotation:

case class Named(name: String) extends scala.annotation.StaticAnnotation

val myAnnotatedClass: ClassSymbol = u.runtimeMirror(Thread.currentThread().getContextClassLoader).staticClass("MyAnnotatedClass")
val annotation: Option[Annotation] = myAnnotatedClass.annotations.find(_.tree.tpe =:= u.typeOf[Named])
val result = annotation.flatMap { a =>
  a.tree.children.tail.collect({ case Literal(Constant(name: String)) => doSomething(name) }).headOption
}
like image 104
Remi Thieblin Avatar answered Oct 23 '22 08:10

Remi Thieblin


There are different kinds of annotations in Scala:

Java Annotations that you can access using the Java Reflection API, annotations that are just in the source code, static annotations that are available to the type checker across different compilation units (so they should be somewhere in a class file but not where normal reflections go) and classfile annotations which are stored like java annotations, but cannot be read using the java reflection api.

I have described how to access static and classfile annotations here: What is the (current) state of scala reflection capabilities, especially wrt annotations, as of version 2.11?

If you just need a annotation containing a string using a Java annotation that is loaded by the JVM for you might be the simpler alternative.

like image 29
dth Avatar answered Oct 23 '22 09:10

dth