1

続き: DefDef を Typecheck する方法

まず、私のマクロからのいくつかのスニペット:

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

型チェックが成功していることを考えると、予想されるすべてのシンボル情報が明確に得られます。

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

tpeメソッドがまだとして出てくるのはどうしてNoTypeですか?

one.typechecked.tpe = NoType
4

1 に答える 1