有没有一种很好的方法来确定Scala宏中的类型包?

时间:2015-04-30 11:35:08

标签: scala macros scala-macros

我正在编写一个宏,需要确定其参数化类型的包。这可能是这样的:

def macroImpl[T: c.WeakTypeTag](c: Context) = {
  import c.universe._

  val typ = weakTypeOf[T]
  val pkg = typ.typeSymbol.fullName.stripSuffix(s".${typ.typeSymbol.name}")
}

但这感觉非常黑客。有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

这不一定是macro,但这里没有任何内容可以排除这种情况。只要您有类型符号,就可以不断检查类型owner,直到找到包裹为止:

def owners[T : WeakTypeTag] = Iterator.iterate(weakTypeOf[T].typeSymbol.owner)(_.owner).takeWhile(!_.isPackageClass)

此迭代器的最后一个元素是包符号。如果你关心的只是包名,你可以这样做:

def package[T : WeakTypeTag] = owners[T].last.fullName

The documentation on symbol reflectionowner属性(我的粗体)有一个很好的说明:

  

符号按层次结构组织。例如,表示方法参数的符号由相应的方法符号拥有,方法符号由其封闭的类,特征或对象拥有,< strong>一个类拥有由一个包含。

     

如果符号没有所有者,例如,因为它引用顶级实体(例如顶级包),则其所有者是特殊的NoSymbol单例对象。表示缺少的符号,NoSymbol通常在API中用于表示空值或默认值。访问NoSymbol的所有者会引发异常。有关Symbol类型提供的常规界面,请参阅API文档。