Я хотел бы использовать макросы scala (v2.12.8) для манипулирования всеми объявлениями переменных данного блока.В этом примере добавить значение 23.
Например:
val myblock = mymanipulator {
var x = 1
x = 4
var y = 1
x + y
}
print( myblock )
становится
{
var x = (1).+(23);
x = 4;
var y = (1).+(23);
x.+(y)
}
Для этого я реализовал mymanipulator следующим образом:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
import scala.language.implicitConversions
object mymanipulator {
def apply[T](x: => T): T = macro impl
def impl(c: Context)(x: c.Tree) = { import c.universe._
val q"..$stats" = x
val loggedStats = stats.flatMap { stat =>
stat match {
case ValDef(mods, sym, tpt, rhs) => {
List( q"var $sym : $tpt = $rhs + 23" )
}
case _ => {
List( stat )
}
}
}
val combined = q"..$loggedStats"
c.info(c.enclosingPosition, "combined: " + showRaw(combined), true)
combined
}
}
И я получаю эту информацию во время компиляции макроса:
Information:(21, 31) combined: {
var x = (1).+(23);
x = 4;
var y = (1).+(23);
x.+(y)
}
val myblock = mymanipulator {
Но когда я выполняю mymanipulator с указанным выше блоком, я получаю это сообщение об ошибке:
Error:scalac: Error while emitting Test.scala
variable y
Эта ошибка возникает также, когда я изменяю реализацию, чтобы ничего не делать:
stat match {
case ValDef(mods, sym, tpt, rhs) => {
List( q"var $sym : $tpt = $rhs" )
}
case _ => {
List( stat )
}
}
Только когда я возвращаю stat, ошибка исчезает
stat match {
case ValDef(mods, sym, tpt, rhs) => {
List( stat )
}
case _ => {
List( stat )
}
}
Может кто-нибудь сказать мне, что я делаюнеправильно?Спасибо