Как я могу использовать отражение времени выполнения Scalas для проверки переданной анонимной функции?

Предполагая, что у меня есть метод, подобный следующему:

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

Как я могу использовать отражение среды выполнения Scala 2.11.1 для проверки переданной анонимной функции func?

Мне особенно интересно получить AST (абстрактное синтаксическое дерево) func и, если возможно, место (номер строки, файл), где этот метод был впервые определен. Все, что я сделал до сих пор, это получить информацию о типе параметра func, а не о самой функции.

Я знаю, что на SO были похожие вопросы, но в основном они нацелены на другие версии Scala.


person Emiswelt    schedule 29.06.2014    source источник
comment
Функция не может этого сделать, потому что AST существует только во время компиляции. getInfo должен быть макросом.   -  person Ben Kovitz    schedule 30.06.2014
comment
Таким образом, теоретически возможно создать макрос, который извлекает информацию во время компиляции и добавляет ее в функцию как своего рода тег?   -  person Emiswelt    schedule 30.06.2014


Ответы (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)")
}

Подробнее об символах, деревьях и типах для анализа.

Более полный пример макроса, который находит все переменные, связанные из другой области в функции, применяя тот же метод.

person Emiswelt    schedule 14.08.2014