5

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?

4

1 回答 1

8

你可以得到伴生对象的符号,然后使用宇宙的Ident(sym: Symbol): Ident工厂方法:

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
    )
  )
}

接着:

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)

如果你真的是指SomeObject对象的类型(即,不是它的伴生类的类型),只需删除.companionSymbol上面的内容。

于 2013-07-01T10:10:56.377 回答