2017-01-13 27 views
1

我需要真的 untypecheck我的宏发出的树。这意味着不仅要移除推断的类型和所有这些,还要移除由编译器推断的隐含参数。甚至没有resetAllAttrs似乎照顾这一点。如何在宏中删除所有推断的含义?

Symbol s似乎有一个方法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) 
} 

被再次typechecked和编译。
但我恐怕这不能做...

回答

2

他们有internal API检测隐式提供的参数,但它被评论为不稳定。 (他们将使用树附件而不是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 [email protected](_,_) => 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 
+0

Thanks!这个API很可能会很快改变吗? (无论如何,一切都将改变为scala.meta) –

+0

我不知道什么是源代码。在2.13之前我不太可能下注。 –

相关问题