2014-02-12 62 views
0

我有這樣的代碼:有什麼好辦法讓斯卡拉宏的值?

object M { 
    implicit class Obj(str: List[_]) { 
    def mm(other: String) = macro Test.impl 
    } 
} 

//macro 
//in macro i would get a `str` argument with actual value which pass into Obj 
// 
object Test { 
    def impl(c: Context)(other: c.Expr[String]) = { 
    import c.universe._ 
    ??? 
    reify{} 
    } 
} 

目前,我用

c.prefix.tree { 
    case .... 
} 

但有一個更好的選擇可用?因爲在編譯的時候,我有一個完整的樹類,並有可能獲得這樣的:

c.prefix.actualType.someMethodForInitialize.str //get `str` from object 

這是可能的,或者還有沒有其他方面?

實施例:

List("a", "b", "c") mm "z" 

在宏我有一個樹:

Apply(Select(Ident(M), newTermName("Obj")), List(Apply(TypeApply(Select(Select(This(newTypeName("immutable")), scala.collection.immutable.List), newTermName("apply")), List(TypeTree())), List(Literal(Constant("a")), Literal(Constant("b")), Literal(Constant("c")))))) 

與實際類型M.Obj 是可能的,而不樹遍歷提取List

+0

你的參數中的str標識符在哪裏?你可以添加一個宏的用法的例子嗎? –

回答

1

雖然這可能不是直接回答你的問題,但在即將發佈的2.11你就可以使用quasiquotes盡一切努力爲你服務:

val q"${s: String}" = other.tree 
+0

哇,是在斯卡拉2.10.3可用? – lito

+0

@lito Quasiquotes在2.10與[編譯器插件(http://docs.scala-lang.org/overviews/macros/paradise.html) –

+0

可惜unlifting沒有(還)在2.10版本quasiquotes的工作都可以。 –

2

如果你想提取Stringother,使用

val otherStr: String = other.tree match { 
    case Literal(Constant(str: String)) => str 
} 
+0

是的,這是一種明顯的方式。沒有樹遍歷提取一個'List'可能嗎? – lito