简体   繁体   中英

How to generate a “qualified Select” using Scala macros?

I'm playing around with Scala macros. When reading examples, I often see this kind of pattern:

Select(
  Select(
    Ident(TermName("scala")), 
    TermName("Some")
  ), 
  TermName("apply")
)

That's quite verbose and repetitive. Is there any way to express this more concisely? I'm looking for something like:

select("scala.Some.apply")

Don't pay any attention to the commenter. [Ed. Dry humor alert.]

Only truly sane people use quasiquotes .

Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0).
Type in expressions to have them evaluated.
Type :help for more information.

scala> q"scala.Some(42)"
res0: reflect.runtime.universe.Tree = scala.Some(42)

scala> showRaw(res0)
res1: String = Apply(Select(Ident(TermName("scala")), TermName("Some")), List(Literal(Constant(42))))

scala> showRaw(q"scala.Some.apply")
res2: String = Select(Select(Ident(TermName("scala")), TermName("Some")), TermName("apply"))

scala> showRaw(q"scala.Some")
res3: String = Select(Ident(TermName("scala")), TermName("Some"))

scala> showRaw(tq"scala.Some")
res4: String = Select(Ident(TermName("scala")), TypeName("Some"))

Generally, you use a qq to document the insanely complex expression:

// tq"scala.Some"
val t = Select(Ident(TermName("scala")), TypeName("Some"))

A trivial solution to this problem would be to implement the following function:

def select(identifier : String) : Tree = {
  val terms = identifier.split("\\.").map { TermName(_) }
  terms.tail.foldLeft[Tree](Ident(terms.head)) { Select(_, _) }
}

Example output from the REPL:

scala> select("scala")
res0: Tree = Ident(TermName(scala))

scala> select("scala.Some")
res1: Tree = Select(Ident(TermName(scala)),TermName(Some))

scala> select("scala.Some.apply")
res2: Tree = Select(Select(Ident(TermName(scala)),TermName(Some)),TermName(apply))

Now, I don't know if this somehow prevents some compiler optimisations that could've been performed otherwise, if explicitly writing out the AST...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM