2017-01-13 21 views
1

Мне нужно действительно untypecheck деревья, которые испускаются моим макросом. Это означает не только удаление выводимых типов и всего этого, но и удаление неявных аргументов, которые выводятся компилятором. Даже не resetAllAttrs, похоже, позаботится об этом.Как удалить все намеченные импликации в макрос?

Symbol s, как представляется, имеет метод isSynthetic, который указывает, был ли код сгенерирован компилятором, но, по-видимому, этот флаг установлен только для таких вещей, как автогенерируемые геттеры и сеттеры, а не для неявных значений, которые вставляет компилятор.

Я мог бы, конечно, вручную искать все неявные списки аргументов и удалять их, но тогда я также удалю те, которые были явно предоставлены пользователем моего макроса.

Так идеально для следующего кода

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

Спасибо! Насколько вероятно, что этот API изменится в ближайшее время? (до того, как все изменится на scala.meta в любом случае) –

+0

Я не знаю больше, чем в источнике. Я бы поспорил, что менее вероятен до 2.13. –

 Смежные вопросы

  • Нет связанных вопросов^_^