Я пытаюсь создать макрос, который позволит мне захватить текст выражения, передаваемого конструктору. Мне нужен текст выражения для целей отладки. Реализация макроса следующая:
package nimrandsLibrary.react.macroImpl
object Macros {
def applyImpl[T : context.WeakTypeTag, U : context.WeakTypeTag](context : scala.reflect.macros.Context) (expression : context.Expr[T]) : context.Expr[U] = {
import context.universe._
context.Expr[U](context.universe.New(context.universe.weakTypeOf[U], expression.tree, context.universe.Literal(context.universe.Constant(expression.tree.toString()))))
}
}
Определение выглядит следующим образом:
class Signal(expression : => T, expressionText : String) {
...
}
object Signal {
def apply[T](expression : T) = macro nimrandsLibrary.react.macroImpl.Macros.applyImpl[T, Signal[T]]
}
Однако везде, где я это вызываю, как показано ниже, я получаю сообщение об ошибке.
val mySignal = Signal{ 2 } //type mismatch; found : Int required : T
Но, разумеется, тип T — Int, поэтому ошибка не имеет смысла.
Кажется, что компилятор каким-то образом в расширении макроса забывает заменить Signal[T] на Signal[Int]. В качестве эксперимента я попытался изменить сайт определения так, чтобы были предоставлены оба типа, например:
def apply[T, U](expression : T) = macro nimrandsLibrary.react.macroImpl.Macros.applyImpl[T, U]
Затем я называю это так:
Signal[Int, Signal[Int]]{ 2 }
И это работает. Но, конечно, это совсем не тот синтаксис, к которому я стремлюсь. Это баг или я как-то не так делаю? Есть ли обходной путь?