简体   繁体   English

Scala:使用Scala宏生成带有参数的Java注释

[英]Scala: generate Java annotation with parameter using Scala macros

I have simple Java annotation with one parameter: 我有一个带有一个参数的简单Java注释:

public @interface Annot {
   String value();
}

Also I have Java annotation that takes array of Annot as parameter: 我还有Java注释,它将Annot数组作为参数:

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

I want to generate Annot with paramter "value" using Scala macro like this: 我想使用Scala宏生成带有参数“value”的Annot,如下所示:

object MyAnnotations {

  def MyAnnotation: Annot = macro myAnnotationMacro

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

While this works: 虽然这有效:

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

This doesn't work: 这不起作用:

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

Why? 为什么? And how can I generate Annot? 我怎样才能生成Annot?

I'm afraid that you can't do what you want with macros. 我担心你不能用宏来做你想做的事。

Typechecking of Java annotations is implemented in a very weird way that is significantly different from the rest of the typechecker. Java注释的类型检查以非常奇怪的方式实现,与typechecker的其他部分明显不同。 While everything else is typechecked from Tree to Tree , arguments to Java annotations are typechecked from Tree to ClassfileAnnotArg (with the latter not being trees). 虽然其他所有内容都是从TreeTree ,但Java注释的参数是从TreeClassfileAnnotArg (后者不是树)的类型。 Your macro expands into a Tree , whereas the typechecker expects ClassfileAnnotArg , so things don't work (and the error message is quite misleading). 你的宏扩展为一个Tree ,而ClassfileAnnotArg期望ClassfileAnnotArg ,所以事情不起作用(错误信息是非常误导的)。

I think that it would be possible to change the typechecker to work in your case, but that will require patching the compiler. 我认为可以将typechecker更改为适用于您的情况,但这需要修补编译器。 No idea how to do that from within a macro. 不知道如何从宏中做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM