Typetree在类型检查后重写

时间:2017-03-05 01:00:49

标签: scala scala-macros

在维护用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 的某些方法的宏扩展无法编译。

这是一个我应该期待的错误吗?有没有办法解决它?

1 个答案:

答案 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