我有一个表面上简单的宏观问题,我一直在努力解决几个小时,但没有运气。也许有更多经验的人可以提供帮助。
我有以下宏:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
object MacroObject {
def run(s: String): Unit =
macro runImpl
def runImpl(c: Context)(s: c.Tree): c.Tree = {
import c.universe._
println(s) // <-- I need the macro to know the value of s at compile time
q"()"
}
}
问题是这样的:我希望宏知道s
传递给它的值——不是 的 AST s
,而是s
自身的值。具体来说,我希望它有这种行为:
def runTheMacro(str: String): Unit = MacroObject.run(str)
final val HardCodedString1 = "Hello, world!"
runTheMacro(HardCodedString1) // the macro should print "Hello, world!"
// to the console during macro expansion
final val HardCodedString2 = "So long!"
runTheMacro(HardCodedString2) // the macro should print "So long!"
// to the console during macro expansion
保证将传递给的唯一字符串是runTheMacro
硬编码的常量值(即,在编译时已知)。
这可能吗,如何做到这一点?
--
编辑:还有以下限制:
- 它必须是一个黑盒宏。
- 宏签名必须使用
c.Tree
s,而不是c.Expr[_]
s(遗留代码;不能更改该部分) - 如果需要,我确实可以使用
toolbox
宏内部:
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
private val toolbox = currentMirror.mkToolBox()
/** Evaluate the given code fragment at compile time. */
private def eval[A](code: String): A = {
import scala.reflect.runtime.{universe => u}
val uTree: u.Tree = toolbox.parse(code)
toolbox.eval(uTree).asInstanceOf[A]
}