简体   繁体   中英

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?

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 (ie, not the type of its companion class), just remove the .companionSymbol above.

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