简体   繁体   English

在reify调用中搜索隐式(scala宏)

[英]Searching for implicit inside a reify call (scala macro)

I need to search for an implicit value at a given position. 我需要在给定位置搜索隐式值。 I retained the position from a previous macro call in a class, like so : 我保留了类中先前的宏调用的位置,如下所示:

class Delayed[+Kind[_[_]]](val sourceFilePath: String, val callSitePoint: Int) {
  def find[F[_]]: Kind[F] = macro Impl.find[Kind, F]
}

The previous macro is very simple : 前面的宏非常简单:

def build[Kind[_[_]]](c: blackbox.Context): c.Expr[Delayed[Kind]] = {
    import c.universe._

    c.Expr(
      q"""
        new Delayed(${c.enclosingPosition.point}, ${c.enclosingPosition.source.path})
       """
    )
  }

With this I have the position, all I need to do is to launch the implicit search right ? 有了这个职位,我需要做的就是启动隐式搜索权吗?

def find[Kind[_[_]], F[_]](c: blackbox.Context)(implicit kindTag: c.WeakTypeTag[Kind[F]], fTag: c.WeakTypeTag[F[_]]): c.Expr[Kind[F]] = {
    import c.universe._

    reify {
      val self = c.prefix.splice.asInstanceOf[Delayed[Kind]]
      val sourceFile = AbstractFile.getFile(self.sourceFilePath)
      val batchSourceFile = new BatchSourceFile(sourceFile, sourceFile.toCharArray)
      val implicitSearchPosition = new OffsetPosition(batchSourceFile, self.callSitePoint).asInstanceOf[c.Position]

      c.Expr[Kind[F]](c.inferImplicitValue(
        appliedType(kindTag.tpe.typeConstructor, fTag.tpe.typeConstructor),
        pos = implicitSearchPosition
      )).splice
    }
  }

I get the position using reify/splice calls and then apply inferImplicitValue . 我使用reify / splice调用获得位置,然后应用inferImplicitValue But the compiler complains about the last splice on the implicit value : 但是编译器抱怨隐式值的最后一个拼接:

the splice cannot be resolved statically, 
which means there is a cross-stage evaluation involved

It asks me to add the compiler jar as dependencies, but by doing so I only get another error : 它要求我将编译器jar添加为依赖项,但这样做只会导致另一个错误:

Macro expansion contains free term variable c defined by find in Delayed.scala

I understand that reify is, conceptually, in the world of values. 我知道,从概念上讲,在价值领域中,辩护是存在的。 What I don't understand is that the implicit search should be resolved before the macro-generated code is written to my source code. 我不明白的是,应在将宏生成的代码写入我的源代码之前解决隐式搜索。 That the only way I can think of for the implicit search to work in macro contexts. 我可以想到的唯一方法是隐式搜索在宏上下文中起作用。

Where I am wrong ? 我哪里错了? I do understand the compiler messages, but to me, it makes no sense in this particular context. 我确实了解编译器消息,但是对我来说,在这种特定情况下没有任何意义。 Maybe I don't get how inferImplicitValue works. 也许我不知道inferImplicitValue是如何工作的。

Try Context#eval(expr) 尝试使用Context#eval(expr)

def find[Kind[_[_]], F[_]](c: blackbox.Context)(implicit kindTag: c.WeakTypeTag[Kind[F]], fTag: c.WeakTypeTag[F[_]]): c.Expr[Kind[F]] = {
  import c.universe._

  val self = c.eval(c.Expr[Delayed[Kind]](c.untypecheck(c.prefix.tree.duplicate)))
  val sourceFile = AbstractFile.getFile(self.sourceFilePath)
  val batchSourceFile = new BatchSourceFile(sourceFile, sourceFile.toCharArray)
  val implicitSearchPosition = new OffsetPosition(batchSourceFile, self.callSitePoint).asInstanceOf[c.Position]

  c.Expr[Kind[F]](c.inferImplicitValue(
    appliedType(kindTag.tpe.typeConstructor, fTag.tpe.typeConstructor),
    pos = implicitSearchPosition
  ))
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM