类型检查后重写的类型树
Typetree rewritten after type checking
在维护用 Scala 2.10.x 编写的旧 Scala 代码时,当我尝试对 macros
中的 TypeTree
进行类型检查时,发生了意想不到的事情。看下面的代码,
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
如您所见,我想做的很简单——尝试判断注释方法的 return 类型是否为 Unit
。它达到了目的,但是我注意到有时 returnType
的 AST 被重写 而 returnType
确实是 Unit
。例如,
returnType
的原始 AST 是,
Select(Ident(scala), newTypeName("Unit"))
isUnit
之后,
Select(Ident(scala), scala.Unit)
因此, return Unit
的某些方法的宏扩展编译失败。
这是错误还是我应该预料到的?有办法绕过它吗?
好的,所以 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
在维护用 Scala 2.10.x 编写的旧 Scala 代码时,当我尝试对 macros
中的 TypeTree
进行类型检查时,发生了意想不到的事情。看下面的代码,
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
如您所见,我想做的很简单——尝试判断注释方法的 return 类型是否为 Unit
。它达到了目的,但是我注意到有时 returnType
的 AST 被重写 而 。例如,returnType
确实是 Unit
returnType
的原始 AST 是,
Select(Ident(scala), newTypeName("Unit"))
isUnit
之后,
Select(Ident(scala), scala.Unit)
因此, return 的某些方法的宏扩展编译失败。 Unit
这是错误还是我应该预料到的?有办法绕过它吗?
好的,所以 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