Skip to content

Commit b954a37

Browse files
committed
implement scala 3 macro
1 parent e4943cc commit b954a37

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

src/main/scala-3/com/github/dwickern/macros/NameOf.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,20 @@ trait NameOf {
2727
*/
2828
transparent inline def nameOf[T](inline expr: T => Any): String = ${NameOfImpl.nameOf('expr)}
2929

30+
/**
31+
* Obtain a fully qualified identifier name as a constant string.
32+
*
33+
* This overload can be used to access an instance method without having an instance of the type.
34+
*
35+
* Example usage:
36+
* {{{
37+
* class Pet(val age: Int)
38+
* class Person(val name: String, val pet: Pet)
39+
* nameOf[Person](_.pet.age) => "pet.age"
40+
* }}}
41+
*/
42+
transparent inline def qualifiedNameOf[T](inline expr: T => Any): String = ${NameOfImpl.qualifiedNameOf('expr)}
43+
3044
/**
3145
* Obtain a type's unqualified name as a constant string.
3246
*

src/main/scala-3/com/github/dwickern/macros/NameOfImpl.scala

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ object NameOfImpl {
99
@tailrec def extract(tree: Tree): String = tree match {
1010
case Ident(name) => name
1111
case Select(_, name) => name
12-
case Block(List(stmt), term) => extract(stmt)
1312
case DefDef("$anonfun", _, _, Some(term)) => extract(term)
13+
case Block(List(stmt), _) => extract(stmt)
1414
case Block(_, term) => extract(term)
1515
case Apply(term, _) if term.symbol.fullName != "<special-ops>.throw" => extract(term)
1616
case TypeApply(term, _) => extract(term)
@@ -22,6 +22,24 @@ object NameOfImpl {
2222
Expr(name)
2323
}
2424

25+
def qualifiedNameOf(expr: Expr[Any])(using Quotes): Expr[String] = {
26+
import quotes.reflect.*
27+
def extract(tree: Tree): List[String] = tree match {
28+
case Ident(name) => List(name)
29+
case Select(tree, name) => extract(tree) :+ name
30+
case DefDef("$anonfun", _, _, Some(term)) => extract(term)
31+
case Block(List(stmt), _) => extract(stmt)
32+
case Block(_, term) => extract(term)
33+
case Apply(term, _) if term.symbol.fullName != "<special-ops>.throw" => extract(term)
34+
case TypeApply(term, _) => extract(term)
35+
case Inlined(_, _, term) => extract(term)
36+
case Typed(term, _) => extract(term)
37+
case _ => throw new MatchError(s"Unsupported expression: ${expr.show}")
38+
}
39+
val name = extract(expr.asTerm).drop(1).mkString(".")
40+
Expr(name)
41+
}
42+
2543
def nameOfType[T](using Quotes, Type[T]): Expr[String] = {
2644
import quotes.reflect.*
2745
val name = TypeTree.of[T].tpe.dealias match {

0 commit comments

Comments
 (0)