2017-03-05 3 views
0

Während ich den alten Scala-Code in Scala 2.10.x geschrieben habe, passierte etwas unerwartetes, als ich versuchte, eine TypeTree in macros zu tippen. Betrachten Sie den folgenden Code,TypeTree nach Typprüfung neu geschrieben

annottees.map(_.tree).toList match { 
    case q"$mods def $name[..$tpes](...$args) : $returnType = { ..$body }" :: Nil => 
    val isUnit = c.typeCheck(q"type T = $returnType;()").children.head match { 
     case TypeDef(_, _, _, tpt) => tpt.tpe =:= typeOf[Unit] 
    } 
    //... business logic 

Wie Sie sehen können, was ich tun möchte, ist einfach - versuchen, zu entscheiden, ob der Rückgabetyp der kommentierten Methode Unit ist. Es dient dem Zweck, jedoch bemerkte ich, dass manchmal AST von returnType umgeschrieben wurde, wenn returnType tatsächlich Unit ist. Zum Beispiel

Die ursprüngliche AST für returnType ist,

Select(Ident(scala), newTypeName("Unit")) 

Nach isUnit,

Select(Ident(scala), scala.Unit) 

Als Ergebnis werden die Makroerweiterungen für einige der Methoden die Unit Rückkehr sind gescheitert kompilieren.

Ist das ein Fehler oder etwas, was ich erwarten sollte? Gibt es einen Weg, um es zu umgehen?

Antwort

0

Ok, also in der Tat kann AST-Baum veränderbar sein. Ich habe mir gedacht, dass ich ein Duplikat von returnType übergeben muss, damit es nicht in etwas anderes umgewandelt wird.

annottees.map(_.tree).toList match { 
    case q"$mods def $name[..$tpes](...$args) : $returnType = { ..$body }" :: Nil => 
    val isUnit = c.typeCheck(q"type T = ${returnType.duplicate};()").children.head match { 
     case TypeDef(_, _, _, tpt) => tpt.tpe =:= typeOf[Unit] 
    } 
//... business logic 
Verwandte Themen