Question

I have this code:

object M {
  implicit class Obj(str: List[_]) {
    def mm(other: String) = macro Test.impl
  }
}

//macro
//in macro i would get a `str` argument with actual value which pass into Obj
//
object Test {
  def impl(c: Context)(other: c.Expr[String]) = { 
    import c.universe._
    ???
    reify{}
  }
} 

At the moment, I use

c.prefix.tree {
  case ....
}

But is there a better choice available? Because at compile time, I have a full tree for the class and there may be available something like this:

c.prefix.actualType.someMethodForInitialize.str //get `str` from object

Is this possible or are there others?

Example:

List("a", "b", "c") mm "z"

in macro i got a tree:

Apply(Select(Ident(M), newTermName("Obj")),  List(Apply(TypeApply(Select(Select(This(newTypeName("immutable")), scala.collection.immutable.List), newTermName("apply")), List(TypeTree())), List(Literal(Constant("a")), Literal(Constant("b")), Literal(Constant("c"))))))

and an actual type M.Obj is it possible without tree traversal extract a List?

Was it helpful?

Solution

Although this might not answer your question directly but in soon to be released 2.11 you'll be able to use quasiquotes to do all the hard work for you:

 val q"${s: String}" = other.tree

OTHER TIPS

If you're trying to extract the String from other, use

val otherStr: String = other.tree match {
  case Literal(Constant(str: String)) => str
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top