Scala 当从宏中检查代码时,是否可能检测到该代码中的宏扩展导致的类型检查失败?

Scala 当从宏中检查代码时,是否可能检测到该代码中的宏扩展导致的类型检查失败?,scala,reflection,typechecking,scala-macros,Scala,Reflection,Typechecking,Scala Macros,我想编写一个宏,该宏编译它作为字符串文本接收的代码,并检测由于宏扩展失败(宏被中止,或扩展的宏未能进行类型检查)而导致的编译代码中的类型检查错误 我是这样想的: def myMacro(c: Context)(codeStringLiteral: c.Expr[String]): c.Expr[Unit] = { val codeString = getString(codeStringLiteral) // this part is easy val ast = c.parse

我想编写一个宏,该宏编译它作为字符串文本接收的代码,并检测由于宏扩展失败(宏被中止,或扩展的宏未能进行类型检查)而导致的编译代码中的类型检查错误

我是这样想的:

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)
}
这可能吗

上下文 这样一个宏将由于宏扩展而导致的故障推迟到运行时进行测试,从而使测试其他宏变得更加愉快,因此即使宏的测试用例被破坏,也可以执行整个测试套件

当然,简单地将类型检查完全区别于运行时是很容易的,但是如果是测试代码本身出了问题,那么只区分由于在测试中编写的宏而导致的错误和编译时失败的错误是非常好的


当然,不相关的宏可能会失败,但这种情况不太可能经常发生。

c.typecheck有一个模糊的标志,名为
withMacrosDisabled
。如果在那里传递
true
,则应防止任何宏被展开。现在,您可以比较
c.typecheck(withMacrosDisabled=false)
c.typecheck(withMacrosDisabled=true)
的状态,并相应地进行分派


这对白盒宏不起作用,因为
withMacrosDisabled=false
使用白盒宏可能会使合法代码无法通过类型检查,但对于黑盒宏,这应该或多或少是可以的。

这不是你想要的,但是你可以看看Shapeless的
illTyped
来了解一般方法的一个例子,但是我的目的是想弄清楚宏是否因为类型检查错误而出错
c.typecheck(withMacrosDisabled=true)
只告诉我代码中是否有宏(可能大部分都有宏,因为此宏的目的是帮助测试其他宏)。然后
c.typecheck(withMacrosDisabled=false)
然后只告诉我整个事情在哪里进行类型检查。我遗漏了什么吗?事实上,withMacrosDisabled不会扩展宏,但如果代码中有宏,它也不会导致类型检查失败。如果宏是blackbox,那么您可以将其作为常规方法键入Check,而无需展开任何内容,这就是禁用MacroseDisabled的作用。哦,谢谢澄清!我错误地认为它会表现得不一样。是的,我相信这可以奏效。