微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在scala宏中,如何在编译时提升一个对象并在quasiquote中使用它?

如何解决在scala宏中,如何在编译时提升一个对象并在quasiquote中使用它?

以下代码片段是来自 Thoughtworks 项目的简短 scala 宏包定义:

  private[SelfType] final class Macros(val c: whiteBox.Context) {
    import c.universe._

    def apply[A: WeakTypeTag]: Tree = {
      val a = weakTypeOf[A]
      val selfTypes: List[Type] = {
        val selfTypeBuilder = List.newBuilder[Type]
        def buildSelfTypes(t: Type): Unit = {
          val dealiased = t.dealias
          dealiased match {
            case RefinedType(superTypes,refinedScope) =>
              superTypes.foreach(buildSelfTypes)
            case typeRef: TypeRef =>
              val symbol = dealiased.typeSymbol
              if (symbol.isClass) {
                selfTypeBuilder += symbol.asClass.selfType.asSeenFrom(dealiased,symbol)
              }
            case _ =>
          }
        }
        buildSelfTypes(a)
        selfTypeBuilder.result()
      }
      val out = selfTypes match {
        case Nil =>
          deFinitions.AnyTpe
        case _ =>
          internal.refinedType(selfTypes,c.internal.enclosingOwner)
      }
      q"_root_.com.thoughtworks.feature.SelfType.make[$a,$out]"

    }

  }

(由 https://github.com/ThoughtWorksInc/feature.scala/blob/4d19cc19016d85f26925895f43f618e1b7552d09/SelfType/src/main/scala/com/thoughtworks/feature/SelfType.scala 提供)

作为准引用的最后一行似乎包含很多样板文本:

q"_root_.com.thoughtworks.feature.SelfType.make[$a,$out]"

假设这个宏包是作为家族多态设计模式的一部分在特征内定义的:没有确定性的q"_root_.com.thoughtworks.feature.SelfType.make[$a,$out]",它必须从宏包的对象变量vvv派生编译的时候。如何使用此变量使准引用更短且更具适应性?

可能有多种方法来实现这一点(例如,对于每个实现,为 SelfType 对象定义一个 Liftable)。但这更像是样板。我正在寻找最短的解决方案。理想情况下,是这样的:

val sym = Term(vvv)
q"$sym.make[$a,$out]"

解决方法

如果您有静态引用(例如导入类型/伴随),您可以:

q"${symbolOf[SelfType.type]}.make[$a,$out]"

如果您有 symbolOf[A].companion 但没有关于它的同伴的信息,您也可以使用 A: WeakTypeTag。如果编译器不认为 object Aclass A

的伴侣,这可能不起作用 ,

找到我的第一个解决方案:

val name = SelfTypes.getClass.getCanonicalName.stripSuffix("$")
val tree = c.parse(name)
q"$tree.make[$a,$out]"

不确定这是否是最有效或最惯用的解决方案,我将问题搁置一段时间

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。