开发者

How to put annotation on getter or setter automatically generated by Groovy compiler?

Groovy automatically generates getters and setters, so e.g. when I type:

int someField

I get the field + getter + setter. Now I want to put an annotation on the setter (e.g. @Requires/Ensures from GContracts):

@Ensures({someField >= 0 && someField <= 100})
int someField

And then I get error: Annotation groovy.lang.GrUnit is not allowed on element FIELD - GrU开发者_如何转开发nit and GContracts recognize annotations on methods only. The workaround for this is coding getter explicitly:

@Requires({...})
void setSomeField(int newValue) { ... }

Is there a better solution for this? In Scala there is an elegant solution for this: http://www.scala-lang.org/api/current/scala/annotation/target/package.html

Is there something like that in Groovy? Or alternatively: maybe some workaround for GContracts to allow such annotations?


There are 9 compile phases in the Groovy compiler. The getters and setters are generated very late in the compilation phases, and they are generated after GContracts runs.

If you want to have your code appear as if generated getters/setters are annotated then you'll have to generate the getter/setter pairs yourself and annotate them. Specifically, add two new FieldNodes to the ClassNode (as long as they don't already exist). A field node is an AnnotatedNode, so you can add whatever annotations you want. As long as you do this in a phase before GContracts runs, then GContracts should never know the different.

That said, this sounds like a GContracts feature request.


As you've noted, GContracts does not provide field annotations (current version: 1.2.4). It even does not execute AST transformations on synthetic (generated) methods which might have been added before GContracts runs.

In a nutshell: an easy workaround is to add a custom setter method.

On the other hand, if you would annotate a class with @Invariant holding a class invariant, it would pre-generate setter methods for all properties to check the class invariant before and after execution of the setter method.

That being said, it might be worth to think about including @Requires and @Ensures in that process - i created an issue: http://gcontracts.lighthouseapp.com/projects/71511-gcontracts-core/tickets/32

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜