在维护用Scala 2.10.x编写的旧Scala代码时,当我尝试在TypeTree
中键入macros
时,发生了意外情况。请查看以下代码,
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
正如您所看到的,我想要做的很简单 - 尝试确定带注释方法的返回类型是否为Unit
。它有用,但是我注意到returnType
确实returnType
时,Unit
的AST有时被重写。例如,
returnType
的原始AST是,
Select(Ident(scala), newTypeName("Unit"))
isUnit
之后,
Select(Ident(scala), scala.Unit)
因此,返回Unit
的某些方法的宏扩展无法编译。
这是一个我应该期待的错误吗?有没有办法解决它?
答案 0 :(得分:0)
好的,确实AST树可以变异。我想我需要传递returnType
的副本,以防止它被转换为其他内容。
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