Mam następujące makra:Jaki jest najlepszy sposób, aby ponownie ustanowić rodzaj spójności po transformacji drzewo z makrami
def testMacro[T](x: T): Option[T] = macro testMacroImpl[T]
def testMacroImpl[T: c.WeakTypeTag](c: Context)(x: c.Expr[T]): c.Expr[Option[T]] = {
import c.universe._
val newTree = x.tree match {
case Block(List(first), second) => {
val newFirst = first match {
case ValDef(mods, name, _, rhs) => ValDef(mods, name, EmptyTree, q"Some($rhs)")
}
Block(List(newFirst), second)
}
}
c.Expr[Option[T]](newTree)
}
Zasadniczo powinno to tylko przemienia to:
testMacro {
val aa = "hello"
aa
}
do
{
val aa = Some("hello")
aa
}
Nie powiedzie się jednak z następującym błędem:
[error] found : String
[error] required: Option[String]
[error] val f = IdiomBracket.testMacro{
[error]
^
Moje dochodzenie pokazuje, że jest to spowodowane tym, że otrzymuje wpisane drzewo, dla którego identyfikator aa
ma typ String
. Ze względu na przekształcenie kodu jest to teraz typ Option[String]
, ale typ identyfikatora nie został zaktualizowany. Próbowałem tworzenia nowego (bez typu) identyfikator, a to tylko sprawia, że błąd ten:
[error] found : <notype>
[error] required: Option[String]
[error] val f = IdiomBracket.testMacro{
[error] ^
Próbowałem typ sprawdzania drzewa przed wysłaniem go w nadziei, że będzie wypełnienie odpowiedniego typu, ale że wydaje się nie mieć żadnego efektu.
Dla odniesienia, tutaj jest to samo makro, które tworzy nowy Ident i wykonuje typologię, która niestety nadal nie działa.
def testMacroImpl[T: c.WeakTypeTag](c: Context)(x: c.Expr[T]): c.Expr[Option[T]] = {
import c.universe._
val newTree = x.tree match {
case Block(List(first), second) => {
val newFirst = first match {
case ValDef(mods, name, _, rhs) => ValDef(mods, name, EmptyTree, q"Some($rhs)")
}
val newSecond = second match {
case ident: Ident => Ident(ident.name)
}
Block(List(newFirst), newSecond)
}
}
c.Expr[Option[T]](c.typecheck(newTree))
}
Rzeczywiście działa, ale nie rozwiązuje podstawowego problemu, jeśli nie mogę z jakiegoś powodu użyć quasiquotes. – jedesah