问题
I have a WeakTypeTag
of some type in my macro, and I want to generate code as follows:
macroCreate[SomeObject] // => SomeObject(1)
The definition of a macro will be something like this:
def macroCreate[A] = macro _macroCreate[A]
def _macroCreate[A](c: Context)(implicit wtt: c.WeakTypeTag[A]) = {
c.Expr(Apply(Select(???, newTermName("apply")), List(c.literal(1).tree)))
}
The problem is, how do I get Select
for the given type?
I can use a workaround of converting the type to string, splitting on "."
and then creating a Select
from list of strings, but that seems hacky.
Is it possible to create a Select
directly from type tag?
回答1:
You can get the symbol of the companion object and then use the universe's Ident(sym: Symbol): Ident
factory method:
def macroCreate[A] = macro _macroCreate[A]
def _macroCreate[A](c: Context)(implicit wtt: c.WeakTypeTag[A]) = {
import c.universe._
c.Expr(
Apply(
Select(Ident(wtt.tpe.typeSymbol.companionSymbol), newTermName("apply")),
c.literal(1).tree :: Nil
)
)
}
And then:
scala> case class SomeObject(i: Int)
defined class SomeObject
scala> macroCreate[SomeObject]
res0: SomeObject = SomeObject(1)
scala> macroCreate[List[Int]]
res1: List[Int] = List(1)
If you really mean that SomeObject
is the type of the object (i.e., not the type of its companion class), just remove the .companionSymbol
above.
来源:https://stackoverflow.com/questions/17399998/is-it-possible-to-generate-apply-from-weaktypetag-inside-a-scala-macro