[ https://issues.apache.org/jira/browse/GROOVY-10192?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17394884#comment-17394884 ]
Marcin Zajaczkowski commented on GROOVY-10192: ---------------------------------------------- And [another question|https://mail-archives.apache.org/mod_mbox/groovy-dev/202108.mbox/%3cb18e777a-cb55-a761-5b66-04dc3184d...@bruenings-it.net%3e] about that by Leonard Brünings (August 2021): It is possible to define Closures for annotations, e.g., Spock's `@Requires(\{ os.windows })`. However, it is currently impossible to tell the IDE what this annotation will delegate to, as @DelegatesTo is only applicable for parameters. Could we either allow @DelegatesTo for TYPE_USE or mabe add a new dedicated annotation for that. public @interface Requires { Class<DelegatesTo(PreconditionContext.class) ? extends Closure> value(); } Alternatively, we could add METHOD as target, to the annotation. public @interface Requires { DelegatesTo(PreconditionContext.class) Class<? extends Closure> value(); } > Smarter Closure delegation detection in annotation parameters > ------------------------------------------------------------- > > Key: GROOVY-10192 > URL: https://issues.apache.org/jira/browse/GROOVY-10192 > Project: Groovy > Issue Type: Improvement > Components: Compiler > Affects Versions: 3.0.8, 4.0.0-alpha-3 > Reporter: Marcin Zajaczkowski > Priority: Minor > > TL;TR. I would like to have a way to inform IDE that a passed in an > annotation Closure's execution is in fact delegated to a specific object > (type). E.g. "@Requires(\{ jvm.java11 })" should allow to write "jv" and see > jvm in IDE (once a delegate has that field/getter). > More detailed version (based on my question on the mailing list in [January > 2020|https://mail-archives.apache.org/mod_mbox/groovy-users/202001.mbox/%3cb62eefce-5d71-f394-8024-f2dd93c12...@wp.pl%3e]). > One of the nice features of Spock is an ability to define conditions in > Closure when test(s) should (not) be executes with @Required/@IgnoreIf. > > {code:java} > @Requires({ isSpecialConditionFulfilled() }) > def "some test"() {} > {code} > The annotation itself is defined as: > > {code:java} > @Retention(RetentionPolicy.RUNTIME) > @Target({ElementType.TYPE, ElementType.METHOD}) > @ExtensionAnnotation(RequiresExtension.class) > public @interface Requires { > Class<? extends Closure> value(); > } > {code} > Down the line the execution is delegated to PreconditionContext which > provides convenient methods/objects such as os.linux, jvm.java11, env, etc. > {code:java} > @Requires({ jvm.java11 && os.linux }) {code} > Unfortunately, there is no code completion as IDE doesn't know about > that delegation (and jvm, os fields/methods). Groovy 2 introduced > @DelegatesTo, however it cannot be used with other annotations or methods. > It can be tricked by creating a static final instance of PreconditionContext > (it's stateless) somewhere (e.g. in the Specification super class), but > people has to know to refer it, e.g: > {code:java} > @Requires({ CTX.jvm.java11 }){code} > Alternatively, I was thinking about a method in the base Spock class: > {code:java} > protected static def ctx(@DelegatesTo(PreconditionContext) Closure closure) { > closure() > }{code} > which could be referenced as: > {code:java} > @Requires({ ctx { jvm.java10Compatible } }){code} > It works, but again "ctx" has to be referenced on demand. > The best long-term solution would be to allow to use @DelegatesTo at the > method level: > {code:java} > public @interface MyRequires { > @DelegatesTo(PreconditionContext.class) Class<? extends Closure> value(); > } {code} > It would provide code completion out of the box (once IDEs have support for > that ). The second main drawback I see is being not very intuitive > declaration and limited usage. -- This message was sent by Atlassian Jira (v8.3.4#803005)