2014-06-29 63 views
1

假設我有類似下面的方法:如何使用Scalas運行時反射來檢查傳遞的匿名函數?

def getInfo(func:() => T) = { 
    //Code goes here. 
} 

我怎麼能使用Scala的2.11.1的運行時反射來檢查通過匿名函數func

我特別感興趣的是獲取func的AST(抽象語法樹),如果可能的話,首先定義方法的位置(行號,文件)。 到目前爲止,我所完成的所有工作都是獲取有關參數func類型的信息,而不是函數本身。

我知道在SO上有類似的問題,但它們主要針對其他Scala版本。

+2

函數不能這樣做,因爲AST只存在於編譯時。 'getInfo'必須是一個宏。 –

+0

因此理論上可以構建一個宏,它在編譯時提取信息並將其作爲某種標記添加到函數中? – Emiswelt

+0

是的,確實如此。 –

回答

1

正如本評論中提到的,這可以在編譯時使用Scala宏來完成。

一個可能的選擇是將原始調用擴展到一個宏,它查詢必要的信息,然後調用一個內部的getInfoMethod,它對信息做了一些事情。

getInfo功能

示例:

import scala.language.experimental.macros 
//getInfo method which gets expanded to macro 
def getInfo(func: => Any):Unit = macro FindFreeVars.findMacro 

def getInfoInternal(info: Any) { 
    //Do something with the collected information 
} 

實施例:

//Macro delclaration 
def getInfoMacro(c: Context)(func: c.Tree): c.Expr[Unit] = { 
    import c.universe._ 

    //Extract information, like enclosingPosition or symols from the function tree. 
    val functionInfo = getFunctionInfo(func) 

    //Call internal method 
    c.Expr[List[(String, Any)]](q"getInfoInternal($func, $closedVars)") 
} 

更多關於Symbols, Trees and Types用於分析。

More complete example通過應用相同的技術來查找從函數中的另一範圍綁定的所有變量的宏。

相關問題