You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2022/07/05 17:15:00 UTC
[jira] [Commented] (GROOVY-10192) Smarter Closure delegation detection in annotation parameters
[ https://issues.apache.org/jira/browse/GROOVY-10192?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17562763#comment-17562763 ]
Eric Milles commented on GROOVY-10192:
--------------------------------------
Eclipse provides [DSLD|https://github.com/groovy/groovy-eclipse/wiki/DSL-Descriptors] and IntelliJ provides [GDSL|https://confluence.jetbrains.com/display/GRVY/Scripting+IDE+for+DSL+awareness] to describe delegation semantics and more.
Any change to allow {{@ClosureParams}} or {{@DelegatesTo}} in new positions would require IDE changes to support for purposes of content assist, syntax highlighting, etc.
> 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
> Labels: annotations
>
> 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-f2dd93c12c04@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.20.10#820010)