gpt4 book ai didi

scala - 带有 scala 宏的非 scala 源位置

转载 作者:行者123 更新时间:2023-12-01 01:01:15 27 4
gpt4 key购买 nike

我有一个 scala 宏,它依赖于通过包含其位置的静态字符串指定的任意 xml 文件。

def myMacro(path: String) = macro myMacroImpl

def myMacroImpl(c: Context)(path: c.Expr[String]): c.Expr[Any] = {
// load file specified by path and generate some code
...
}

这意味着,如果 xml 文件格式错误,宏将无法展开。目前,我正在提供一条错误消息,其中包含 xml 文件中错误位置的文本表示。然而,这显然不是最好的解决方案。

是否可以在我生成的代码的不同(可能的非 scala)文件中提供源位置,以便错误将指向 xml 文件而不是包含 xml 文件的 scala 文件?我看不到如何自己创建位置而不是更改现有位置。

最佳答案

这个用例肯定很有趣,看起来应该是反射 API 支持的东西。不幸的是,目前还没有公共(public) API 来实现这一点,尽管内部机制已经到位,尽管是相当低级的。

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
import scala.reflect.io.AbstractFile
import scala.reflect.internal.util.BatchSourceFile
import scala.reflect.internal.util.OffsetPosition

class Impl(val c: Context) {
def impl: c.Tree = {
val filePath = "foo.txt"
val af = AbstractFile.getFile(filePath)
val content = scala.io.Source.fromFile(filePath).mkString
val sf = new BatchSourceFile(af, content)
val pos = new OffsetPosition(sf, 3).asInstanceOf[c.universe.Position]
c.abort(pos, "it works")
}
}

object Macros {
def foo: Any = macro Impl.impl
}

object Test extends App {
Macros.foo
}

在一个简单的文本文件上运行此代码会产生以下结果:
20:56 ~/Projects/Master/sandbox (master)$ cat foo.txt
hello
world
20:56 ~/Projects/Master/sandbox (master)$ scalac Test.scala
foo.txt:1: error: it works
hello
^
one error found

请注意,此解决方案涉及 scala.reflect.internal和类型转换(两者都使我们为 scala-reflect.jar 提供的所有兼容性保证无效),因此我不建议将其用于生产代码。

关于scala - 带有 scala 宏的非 scala 源位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23220132/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com