我需要真正地检查我的宏发出的树。这意味着不仅要删除推断类型和所有这些,还要删除由编译器推断的隐式参数。甚至resetAllAttrs
似乎都没有解决这个问题。
Symbol
似乎有一个方法isSynthetic
,指示代码是否是由编译器生成的,但显然该标志仅为自动生成的getter和setter设置,而不是为隐式值设置编译器插入。
我当然可以手动查找所有隐式参数列表并将其删除,但之后我还会删除宏用户明确提供的参数列表。
理想情况下,以下代码
scala> def foo(a: Int)(implicit e: DummyImplicit) = a
foo: (a: Int)(implicit e: DummyImplicit)Int
scala> myMacro{ foo(4); foo(2)(DummyImplicit.dummyImplicit) }
myMacro
会发出树
{
foo(4);
foo(2)(Predef.this.DummyImplicit.dummyImplicit)
}
然后再次进行类型检查并编译 但我担心这不可能......
答案 0 :(得分:2)
他们有internal API来检测隐式提供的args,但它被评为不稳定。 (他们将使用树附件而不是Apply的子类型。)
$ scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.
scala> import language.experimental.macros
import language.experimental.macros
scala> import reflect.macros.blackbox.Context
import reflect.macros.blackbox.Context
scala> def fImpl(c: Context)(block: c.Expr[Any]): c.Expr[Boolean] = c.Expr { import c._, universe._
| val trees = universe.asInstanceOf[reflect.internal.Trees]
| block.tree match {
| case t@Apply(_,_) => Literal(Constant(t.isInstanceOf[trees.ApplyToImplicitArgs]))
| case _ => Literal(Constant(false)) }}
fImpl: (c: scala.reflect.macros.blackbox.Context)(block: c.Expr[Any])c.Expr[Boolean]
scala> def f(block: Any): Boolean = macro fImpl
defined term macro f: (block: Any)Boolean
scala> def g(implicit d: DummyImplicit) = 42
g: (implicit d: DummyImplicit)Int
scala> f(println(""))
res0: Boolean = false
scala> f(g)
res1: Boolean = true
scala> f(g(new DummyImplicit))
res2: Boolean = false