[英]How to write a Scala macro that evaluates to a Tree similar to “reify”
[英]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.