For completeness, here's a lightly adapted version of the solution I mention above:
import scala.language.experimental.macros
import scala.reflect.macros.Context
object Example {
def doIt(s: String): String = macro doItImpl
def doItImpl(c: Context)(s: c.Expr[String]): c.Expr[String] = {
import c.universe._
c.enclosingClass.collect {
case ValDef(_, name, _, rhs) if rhs.pos == c.macroApplication.pos =>
c.literal(s"Okay, defining a variable named ${name.decoded}.")
}.headOption.getOrElse(
c.abort(c.enclosingPosition, "Not a valid application.")
)
}
}
Now in a REPL:
scala> import Example._
import Example._
scala> object Test1 { val x = doIt("foo") }
defined module Test1
scala> Test1.x
res0: String = Okay, defining a variable named x.
And in the case that we don't have an definition:
scala> object Test2 { doIt("foo") }
<console>:13: error: Not a valid application.
object Test2 { doIt("foo") }
^
As expected. See the comments on the question linked above for some caveats, but unless your real use case is much more complicated, this approach should work fine.