2013-07-01 4 views
5

Ho un WeakTypeTag di qualche tipo nella mia macro, e voglio generare il codice come segue:È possibile generare Apply da WeakTypeTag all'interno di una macro scala?

macroCreate[SomeObject] // => SomeObject(1) 

La definizione di una macro sarà qualcosa di simile:

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

Il problema è , come ottengo Select per il tipo specificato?

È possibile utilizzare una soluzione alternativa per convertire il tipo in stringa, suddividere su "." e quindi creare un numero Select dall'elenco di stringhe, ma ciò sembra intrusivo.

È possibile creare un Select direttamente dal tag di tipo?

risposta

8

È possibile ottenere il simbolo dell'oggetto compagno e quindi utilizzare il metodo Ident(sym: Symbol): Ident fabbrica dell'universo:

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

E poi:

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) 

Se vuoi dire davvero che SomeObject è il tipo di oggetto (vale a dire, non il tipo della sua classe compagno), basta rimuovere il .companionSymbol sopra.

+2

Ho aggiunto una piccola modifica ('newTermName' in Seleziona), perché scalac genera su di esso un avviso di deprecazione. Grazie! – Rogach

+0

Oh, giusto grazie! Digitando troppo velocemente ... –

Problemi correlati