2013-07-01 15 views
5

私は私のマクロでいくつかのタイプのWeakTypeTagを持っており、次のように私は、コードを生成したい:スカラマクロ内のWeakTypeTagからApplyを生成することは可能ですか?

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

マクロの定義は次のようなものになります。問題がある

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

、どのように私は与えられたタイプのSelectを得ますか?

タイプを文字列に変換し、"."に分割して文字列のリストからSelectを作成するという回避策を使用できますが、これはハッキーです。

タイプタグから直接Selectを作成することはできますか?

答えて

8

あなたはコンパニオンオブジェクトのシンボルを取得し、宇宙のIdent(sym: Symbol): Identファクトリメソッドを使用することができます:あなたは本当にSomeObjectはのタイプであることを意味する場合

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) 

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

そしてをオブジェクト(つまり、そのコンパニオンクラスのタイプではない)の場合は、上記の.companionSymbolを削除してください。

+2

scalagが廃止予定の警告をスローするため、小さな編集(Selectに 'newTermName')を追加しました。ありがとう! – Rogach

+0

ああ、ありがとう!入力が速すぎます... –

関連する問題