首先,我的宏的一些片段:
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
答案 0 :(得分:2)
这就是scalac的工作方式。 Typechecked定义(即DefTree
的子类)与NoType
一起分配。相比之下,无类型定义在null
中有tpe
(就像其他无类型树一样),因此可以辨别它们。