[ 
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)

Reply via email to