https://mp.weixin.qq.com/s/so-2x5KLfYF0IMCCqNThwQ
简单调试ValName实现;
1. 使用
Desugar之后如下:
这里补上了省略掉的implicit parameter,如下:
2. 实现
ValName的实现如下:
ValNameImpl的实现如下:
3. 提取
ValName和ValNameImpl实现相对独立,可以提取出来单独调试。
新建一个项目。因为ValNameImpl的实现使用了宏,所以需要单独处在一个编译单元(compile unit)中,在Intellij IDEA中为另一个module。需要在Module之间添加依赖。
ValNameImpl:
有一处需要调整;
ValName实现如下:
4. 调试
运行结果如下:
如下使用方式编译不通过:
5. 总结
ValName需要在一个节点变量定义中使用,如下:
val a_node = BaseNode("lazy_module_name")
这也是起名为“ValName”的原因,ValName返回的就是"val a_node"这个变量的名字,即“a_node”。
6. 附录
ValNameImpl:
package freechips.rocketchip.macros
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
case class ValNameImpl(name: String)
object ValNameImpl
{
implicit def materialize: ValNameImpl = macro detail
def detail(c: Context): c.Expr[ValNameImpl] = {
import c.universe._
def allOwners(s: c.Symbol): Seq[c.Symbol] =
if (s == `NoSymbol`) Nil else s +: allOwners(s.owner)
val terms = allOwners(c.internal.enclosingOwner).filter(_.isTerm).map(_.asTerm)
terms.filter(t => t.isVal || t.isLazy).map(_.name.toString).find(_(0) != '$').map { s =>
val trim = s.replaceAll("\\s", "")
c.Expr[ValNameImpl] { q"_root_.freechips.rocketchip.macros.ValNameImpl(${trim})" }
}.getOrElse(c.abort(c.enclosingPosition, "Not a valid application."))
}
}
ValName:
package freechips.rocketchip.diplomacy
import scala.language.experimental.macros
import freechips.rocketchip.macros.ValNameImpl
case class ValName(name: String)
object ValName
{
implicit def materialize(implicit x: ValNameImpl): ValName = ValName(x.name)
}