2015-07-03 209 views
1

我想使用宏和靜態註釋生成case類。斯卡拉宏:c.universe.Tree到c.universe.Name

有什麼辦法可以將c.universe.Tree轉換成另一種c.universe類型,特別是c.universe.Name

+0

什麼樣的樹?你想用這個名字做什麼? –

+0

@TravisBrown我想使用它作爲從宏內生成的新案例類的名稱。理想情況下,案例類用參數列表進行註釋,這些參數將被剝離以生成新的案例類定義。 –

+0

樹是字符串文字嗎? –

回答

1

答案取決於你有什麼樣的樹,但在任何情況下,你想從你的樹去一個字符串,然後你可以創建無論是TypeNameTermNameTypeNameTermName構造。

例如,我們這裏的樹是一個字符串:

import scala.language.experimental.macros 
import scala.reflect.macros.blackbox.Context 

def callFooImpl(c: Context)(name: c.Expr[String]): c.Expr[Unit] = { 
    import c.universe._ 

    val termName: TermName = name.tree match { 
    case Literal(Constant(s: String)) => TermName(s) 
    case _ => c.abort(c.enclosingPosition, "Not a string literal") 
    } 

    c.Expr[Unit](q"$termName.foo()") 
} 

def callFoo(name: String): Unit = macro callFooImpl 

case class Foo(i: Int) { 
    def foo(): Unit = println(s"Called foo() on $this") 
} 

然後:

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

val myFoo = Foo(10) 
callFoo("myFoo") 

// Exiting paste mode, now interpreting. 

Called foo() on Foo(10) 
myFoo: Foo = Foo(10) 

這裏我們解構字符串文字樹LiteralConstant得到一個編譯期然後我們用它來創建一個TermName,我們可以在我們生成的代碼中使用它。

+0

這起作用。謝謝! –