Skip to content

Instantly share code, notes, and snippets.

@dwickern
Last active September 23, 2016 20:16
Show Gist options
  • Save dwickern/b47606a1ed2319afa6e2 to your computer and use it in GitHub Desktop.
Save dwickern/b47606a1ed2319afa6e2 to your computer and use it in GitHub Desktop.
Scala "nameOf" macro: get the name of an identifier as a string at compile-time!
import scala.annotation.tailrec
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
// UPDATE: now published for your convenience!
// https://github.com/dwickern/scala-nameof
object Macros {
def nameOfImpl(c: blackbox.Context)(x: c.Tree): c.Tree = {
import c.universe._
@tailrec def extract(x: c.Tree): String = x match {
case Ident(TermName(s)) => s
case Select(_, TermName(s)) => s
case Function(_, body) => extract(body)
case Block(_, expr) => extract(expr)
case Apply(func, _) => extract(func)
}
val name = extract(x)
q"$name"
}
def nameOfMemberImpl(c: blackbox.Context)(f: c.Tree): c.Tree = nameOfImpl(c)(f)
def nameOf(x: Any): String = macro nameOfImpl
def nameOf[T](f: T => Any): String = macro nameOfMemberImpl
}
//
// Sample usage:
//
val someVariable = ""
Macros.nameOf(someVariable) // "someVariable"
def someFunction(x: Int): String = ???
Macros.nameOf(someFunction _) // "someFunction"
case class SomeClass(someParam: String)
val myClass = SomeClass("")
Macros.nameOf(myClass.someParam) // "someParam"
// without having an instance of the class:
Macros.nameOf[SomeClass](_.someParam) // "someParam"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment