Maarten
Maarten

Reputation: 239

Can I access the value(s) of the argument(s) of an annotation in the body of the variable (val/var) that is being annotated?

In my project, programmers can annotate certain fields of a class as a prediction in the following way :

class Foo() {
  @prediction('p1) var quality = // access 'p1 here
}

A Symbol is given in the definition of a prediction annotation that represents its id (in this case the id of quality is 'p1).

My problem: I want to access the value of that Symbol in the implementation of the quality variable. I think this is achievable by using a macro but I wasn't able to implement it.

My question: How can I achieve this (macros are allowed)?

Upvotes: 1

Views: 78

Answers (1)

Dmytro Mitin
Dmytro Mitin

Reputation: 51658

Yes, you can. Try to make prediction a macro annotation

class Foo() {
  @prediction('p1) var quality = {
    println(access) //'p1
  }
}

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox

@compileTimeOnly("enable macro paradise to expand macro annotations")
class prediction(s: Symbol) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro predictionMacro.impl
}

object predictionMacro {
  def impl(c: whitebox.Context)(annottees: c.Tree*): c.Tree = {
    import c.universe._
    val symb = c.prefix.tree match {
      case q"new prediction($s)" => s
    }
    annottees match {
      case q"$mods var $tname: $tpt = $expr" :: _ =>
        q"""$mods var $tname: $tpt = {
            val access = $symb
            $expr
          }"""
    }
  }
}

Upvotes: 2

Related Questions