Ich habe ein Makro und Teil dieses Makros besteht darin, jeden Aufruf einer bestimmten Methode durch etwas anderes zu ersetzen. Um dies zu erreichen, verwende ich eine Transformer
und versuche, alle Tree
, die die transform
-Methode gegen eine Quasiquote eintritt. Wenn ich es unten schreibe, scheint es zu funktionieren.Robustheit des Mustervergleichs Bäume mit Quasiquoten
package mypackage
object myobject {
implicit def mymethod[T](t: Option[T]): T = ???
}
object Macros {
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
def myMacro(c: Context)(expr: c.Tree): c.Tree = {
import c.universe._
val transformer = new Transformer {
private def doSomething(value: c.Tree): TermName = {
???
}
override def transform(tree: c.Tree) = tree match {
case q"mypackage.myobject.mymethod[..$_]($value)" =>
val result = doSomething(value)
q"$result"
case _ => super.transform(tree)
}
}
val transformed = transformer.transform(expr)
???
}
}
Aber ich dachte, Sie sollten immer voll qualifizierte Namen in Makros verwenden oder Sie könnten in Schwierigkeiten geraten. So schrieb ich es wie q"_root_.mypackage.myobject.mymethod[..$_]($value)"
, aber dann nicht mehr übereinstimmte und die Anrufe zu mymethod
nicht mehr ersetzt.
Ich schaute auch auf den Vorschlag in the scala docs Symbole zu entmarkieren, aber ich konnte das auch nicht funktionieren.
Also meine Frage ist: wird dieser Code (mit q"mypackage.myobject.mymethod[..$_]($value)"
) immer alle Anrufe zu mymethod
ersetzen und nie irgendwelche anderen Methodenaufrufe ersetzen? Und wenn nicht, wie kann ich es robuster machen?
Wenn ich einen Methodenaufruf in einem 'Tree' finde, wie kann ich überprüfen, dass die Methode, die aufgerufen wird, eine bestimmte Anmerkung hat? –
'mods' wird es enthalten. http://docs.scala-lang.org/overviews/quasiquotes/definition-details könnte nützlich sein. – dveim
Okay, eine Alternative, die für mich funktioniert: 'methodCallFromTree.symbol.asMethod.annotations'. –