为什么typecheck会返回NoType,即使计算出有效符号也是如此?

时间:2014-03-17 09:53:19

标签: scala macros scala-macros scala-macro-paradise

继续:How to Typecheck a DefDef

首先,我的宏的一些片段:

object log {
  def err(msg: String): Unit = c.error(c.enclosingPosition, msg)
  def warn(msg: String): Unit = c.warning(c.enclosingPosition, msg)
  def info(msg: String): Unit = c.info(c.enclosingPosition, msg, force=true)
  def rawInfo(name: String, obj: Any): Unit = info(name + " = " + showRaw(obj))
}

methodsIn(body) foreach { dd => //dd: DefDef
  val name = dd.name.toString
  log.rawInfo(name, dd)
  log.rawInfo(name + ".rhs", dd.rhs)

  try {
    val typechecked = ctx.typecheck(dd.duplicate)
    log.rawInfo(name + ".typechecked", typechecked)
    log.info(name + ".typechecked.symbol = " + typechecked.symbol)
    log.rawInfo(name + ".typechecked.symbol [raw]", typechecked.symbol)
    log.info(name + ".typechecked.symbol.info = " + typechecked.symbol.info)
    log.rawInfo(name + ".typechecked.symbol.info [raw]", typechecked.symbol.info)
    log.rawInfo(name + ".typechecked.tpe", typechecked.tpe)
  } catch { case e: Throwable => log.warn(e.toString)}
}

然后我用这个类提供宏:

class BorgMe(@mymacro val param: Nanites) {
  def one(s: String) = s
}

是的......它是一个天堂注释宏。但我不认为这与此相关。

令我困惑的是该代码的日志输出,如下所示:

one = DefDef(
  Modifiers(),
  TermName("one"),
  List(),
  List(List(ValDef(
    Modifiers(PARAM),
    TermName("s"),
    Ident(TypeName("String")),
    EmptyTree
  ))),
  TypeTree(),
  Ident(TermName("s"))
)

one.rhs = Ident(TermName("s"))

one.typechecked = DefDef(
  Modifiers(),
  TermName("one"),
  List(),
  List(List(ValDef(
    Modifiers(PARAM),
    TermName("s"),
    TypeTree().setOriginal(
      Select(
        Select(
          This(TypeName("scala")),
          scala.Predef
        ),
        TypeName("String")
      )
    ),
    EmptyTree
  ))),
  TypeTree(),
  Ident(TermName("s"))
)

one.typechecked.symbol = method one
one.typechecked.symbol [raw] = TermName("one")

one.typechecked.symbol.info = (s: String)String
one.typechecked.symbol.info [raw] =
  MethodType(
    List(TermName("s")),
    TypeRef(
      SingleType(ThisType(scala), scala.Predef),
      TypeName("String"),
      List()
    )
  )

one.typechecked.tpe = NoType

鉴于typecheck成功,我们显然有所有预期的符号信息:

one.typechecked.symbol = method one
one.typechecked.symbol.info = (s: String)String

该方法的tpe如何NoType形式出现?

one.typechecked.tpe = NoType

1 个答案:

答案 0 :(得分:2)

这就是scalac的工作方式。 Typechecked定义(即DefTree的子类)与NoType一起分配。相比之下,无类型定义在null中有tpe(就像其他无类型树一样),因此可以辨别它们。