我想编写一个宏来编译它作为String文字接收的代码,并检测由于宏扩展失败导致的编译代码中的类型检查错误(宏被中止,或者扩展宏未能类型检测)
我在想这样的事情:
def myMacro(c: Context)(codeStringLiteral: c.Expr[String]): c.Expr[Unit] = {
val codeString = getString(codeStringLiteral) // this part is easy
val ast = c.parse(code)
val actualCode = util.Try(c.typecheck(ast)).recover{ case t: TypecheckException =>
if(t.isMacroExpansionFailure) doOneThing
else doOtherThing
}
c.Expr(actualCode.get)
}
这可能吗?
这样的宏可以通过延迟运行时由宏扩展引起的故障来测试其他宏更加令人愉快,因此即使宏的测试用例被破坏,也可以执行整个测试套件。
当然,简单地将完全不同的类型检查与运行时区分开是很容易的,但是如果只是由于您正在测试的宏而导致的错误不同而且如果它是测试代码本身则在编译时失败将是非常好的这是错误的。
当然,不相关的宏可能会失败,但不太可能经常发生。
答案 0 :(得分:1)
c.typecheck是一个模糊的标志,名为withMacrosDisabled
。如果您在那里传递true
,则应该阻止任何宏展开。现在,您可以比较c.typecheck(withMacrosDisabled = false)
和c.typecheck(withMacrosDisabled = true)
的状态并相应地发送。
这对于whitebox宏不起作用,因为withMacrosDisabled = false
可能会使用whitebox宏来使合法代码无法进行类型检查,但对于blackbox宏,它应该或多或少都可以。