2016-04-22 4 views
1

у меня есть простой Java аннотаций с одним параметром:Scala: генерировать Java аннотаций с параметром с помощью Scala макросы

public @interface Annot { 
    String value(); 
} 

Также у меня есть Java аннотаций, который принимает массив Annot в качестве параметра:

public @interface Annotations { 
    Annot[] value(); 
} 

I хотите генерировать Annot с параметром «value» с использованием макроса Scala следующим образом:

object MyAnnotations { 

    def MyAnnotation: Annot = macro myAnnotationMacro 

    def myAnnotationMacro(c: whitebox.Context): c.Expr[Annot] = { 
    import c.universe._ 
    c.Expr(q"""new Annot("value")""") 
    } 
} 

В то время как th это работает:

@Annotations(Array(
    new Annot("value") 
)) 
trait T 

Это не работает:

@Annotations(Array(
    MyAnnotations.MyAnnotation 
)) // too many arguments for constructor Annot:()Annot 
trait T 

Почему? И как я могу генерировать Annot?

ответ

0

Боюсь, что вы не можете делать то, что хотите, с помощью макросов.

Typechecking аннотаций Java реализован очень странным образом, что существенно отличается от остальной части typechecker. В то время как все остальное является typechecked от Tree до Tree, аргументы для аннотаций Java являются typechecked от Tree до ClassfileAnnotArg (при этом последние не являются деревьями). Ваш макрос расширяется до Tree, тогда как typechecker ожидает ClassfileAnnotArg, поэтому все не работает (и сообщение об ошибке довольно вводит в заблуждение).

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

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