Вывод типа дерева в макросе scala

Как я могу попросить компилятор определить тип построенного дерева внутри макроса? Я нашел только Context.typeCheck, но он проверяет только типы, но не возвращает результат.


person edofic    schedule 30.06.2013    source источник


Ответы (2)


Если вы проверили тип дерева, вы можете просто использовать его метод tpe:

scala> def impl(c: Context) = c.literal(c.typeCheck(c parse "1+1").tpe.toString)
impl: (c: scala.reflect.macros.Context)c.Expr[String]

scala> def mac = macro impl
mac: String

scala> println(mac)
Int(2)

Конечно, вы можете обернуть его выражением, но в этом нет необходимости, если вам нужен только тип.

person Travis Brown    schedule 30.06.2013

Я понял это, и я надеюсь, что это избавит кого-то еще от хлопот

import reflect.macros.Context
import language.experimental.macros

def impl(c: Context) = {
  val tree = c.parse("1+1")
  val expr = c.Expr[Any](c.typeCheck(tree))
  println(expr.staticType)
  println(expr.actualType)
  c.literalUnit
}

def mac = macro impl

Оборачивая в Expr, вы получаете возможность запрашивать фактический тип. Любой из них может обеспечить юридическую верхнюю границу. Без этого выводимый тип был бы Expr[Nothing], и у вас были бы проблемы. Уловка заключается в том, чтобы обернуть дерево, возвращенное из c.typeCheck, иначе Type будет просто нулевым.

Метод mac просто возвращает (), но выводит Any-верхнюю границу и Int(2) - фактический тип.

person edofic    schedule 30.06.2013