簡體   English   中英

在reify調用中搜索隱式(scala宏)

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

我需要在給定位置搜索隱式值。 我保留了類中先前的宏調用的位置,如下所示:

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

前面的宏非常簡單:

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})
       """
    )
  }

有了這個職位,我需要做的就是啟動隱式搜索權嗎?

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
    }
  }

我使用reify / splice調用獲得位置,然后應用inferImplicitValue 但是編譯器抱怨隱式值的最后一個拼接:

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

它要求我將編譯器jar添加為依賴項,但這樣做只會導致另一個錯誤:

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

我知道,從概念上講,在價值領域中,辯護是存在的。 我不明白的是,應在將宏生成的代碼寫入我的源代碼之前解決隱式搜索。 我可以想到的唯一方法是隱式搜索在宏上下文中起作用。

我哪里錯了? 我確實了解編譯器消息,但是對我來說,在這種特定情況下沒有任何意義。 也許我不知道inferImplicitValue是如何工作的。

嘗試使用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