Как часть макроса, я хочу манипулировать определениями частичной функции.Как сопоставить шаблон определения частичной функции в макросе Scala?
Для этого я использую Transformer манипулировать определения случае частичной функции и Traverser, чтобы проверить образцы определений случая:
def myMatchImpl[A: c.WeakTypeTag, B: c.WeakTypeTag](c: Context)
(expr: c.Expr[A])(patterns: c.Expr[PartialFunction[A, B]]): c.Expr[B] = {
import c.universe._
val transformer = new Transformer {
override def transformCaseDefs(trees: List[CaseDef]) = trees map {
case caseDef @ CaseDef(pattern, guard , body) => {
// println(show(pattern))
val traverser = new Traverser {
override def traverse(tree: Tree) = tree match {
// match against a specific pattern
}
}
traverser.traverse(pattern)
}
}
}
val transformedPartialFunction = transformer.transform(patterns.tree)
c.Expr[B](q"$transformedPartialFunction($expr)")
}
Теперь давайте предположим, интересные данные я хочу чтобы соответствовать против представлен класс данных (который является частью объекта примера):
case class Data(x: Int, y: String)
При вызове Теперь макрокоманду на примере ниже
abstract class Foo
case class Bar(data: Data) extends Foo
case class Baz(string: String, data: Data) extends Foo
def test(foo: Foo) = myMatch(foo){
case Bar(Data(x,y)) => y
case Baz(_, Data(x,y)) => y
}
паттерны определений случае частичной функции преобразуются компилятором следующим образом (классы Foo, Bar и Baz являются членами объекта примера, тоже):
(data: Example.Data)Example.Bar((x: Int, y: String)Example.Data((x @ _), (y @ _)))
(string: String, data: Example.Data)Example.Baz(_, (x: Int, y: String)Example.Data((x @ _), (y @ _)))
Это результат печати лекал, как намекнули в макросе выше (с использованием шоу), сырые абстрактные синтаксические деревья (распечатаны с помощью showRaw) выглядит следующим образом:
Apply(TypeTree().setOriginal(Select(This(newTypeName("Example")), Example.Bar)), List(Apply(TypeTree().setOriginal(Select(This(newTypeName("Example")), Example.Data)), List(Bind(newTermName("x"), Ident(nme.WILDCARD)), Bind(newTermName("y"), Ident(nme.WILDCARD))))))
Apply(TypeTree().setOriginal(Select(This(newTypeName("Example")), Example.Baz)), List(Ident(nme.WILDCARD), Apply(TypeTree().setOriginal(Select(This(newTypeName("Example")), Example.Data)), List(Bind(newTermName("x"), Ident(nme.WILDCARD)), Bind(newTermName("y"), Ident(nme.WILDCARD))))))
Как написать шаблон-цитату, которая соответствует против них деревья?
Попробуйте распечатать деревья с помощью 'showRaw', он покажет вам точную структуру дерева (а не только код-подобное представление). – ghik
@ghik Я добавил вывод 'shawRaw' к вопросу. К сожалению, это тоже не очень помогает, так как я не знаю, как написать шаблон для такого дерева. Я соответствующим образом обновил этот вопрос. –