我想写一个宏来检查和修改一个lamba。现在宏看起来像这样(它没有做任何修改):
object Macro {
def literalInt(c: blackbox.Context)(func: c.Expr[Int => Int]): c.Expr[Int => Int] = {
import c.universe._
val Function(params, body) = func.tree
c.Expr(Function(params, body))
}
def lit(func: Int => Int): Int => Int = macro literalInt
}
对于琐碎的lambdas可以很好地工作,例如:
Macro.lit(_ + 19)
但是在
上失败了Macro.lit { args =>
val temp = 10
args + temp * 2
}
与错误:
scalac: Error while emitting App.scala
value temp
有谁知道这是怎么回事吗?
阅读Macrology 201关于业主链腐败的报告
https://github.com/scalamacros/macrology201/tree/part1
https://github.com/scalamacros/macrology201/commits/part1(特别是第21步及以后)
一个简单的解决所有者链损坏问题的方法是擦除符号表中相应代码正在进行根治的块转换。在有问题的树中的符号被删除之后,扩展后的类型检查将从头开始重新创建它们符号表一致。这是通过调用一个专用的宏API来完成的Scala 2.11*中的
c.untypecheck
和Scala 2.10中的c.resetLocalAttrs
。
(*)和Scala 2.12-2.13.
尝试取消传入树的类型检查(在简单的情况下,这应该足够了)
def literalInt(c: blackbox.Context)(func: c.Expr[Int => Int]): c.Expr[Int => Int] = {
import c.universe._
val Function(params, body) = c.untypecheck(func.tree)
c.Expr(Function(params, body))
}
使用scala宏操作变量声明
宏untypecheck
这个def macro有什么问题?
如何使用"宇宙"。在一个Scala宏执行中创建和类型检查树,在另一个宏执行中?