Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to generate Apply from WeakTypeTag inside a scala macro?

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?

like image 543
Rogach Avatar asked Jul 01 '13 08:07

Rogach


1 Answers

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.

like image 159
Travis Brown Avatar answered Nov 15 '22 09:11

Travis Brown