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/04/15 13:53:00 UTC

[jira] [Commented] (GROOVY-10574) @NamedVariant generation does not work with extension methods

    [ https://issues.apache.org/jira/browse/GROOVY-10574?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17522837#comment-17522837 ] 

Eric Milles commented on GROOVY-10574:
--------------------------------------

One thing you can do is to combine {{@Category}} and {{@NamedVariant}}.  NamedVariant runs in compiler phase 4 and Category in phase 5.
{code:groovy}
@Category(File)
class Groovy10574 {
  @groovy.transform.NamedVariant
  def ext(String one, String two) {
  }
}
{code}

 !screenshot-1.png! 

> @NamedVariant generation does not work with extension methods
> -------------------------------------------------------------
>
>                 Key: GROOVY-10574
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10574
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.5.16, 3.0.10, 4.0.1
>            Reporter: Leonard Brünings
>            Priority: Major
>              Labels: named-parameters
>         Attachments: screenshot-1.png
>
>
> Based on the discussion in GROOVY-10567 I tried creating a extension method by explicitly annotating the other parameters with {{@NamedParam}}. However, the method was not picked up as an extension method.
> As an example:
> {code:groovy}
> import groovy.transform.*
> @NamedVariant
> static javaBlockingTest(File self,
>                      @NamedParam String packageName = 'com.example',
>                      @NamedParam String className = "BlockingTest") {
> }
> {code}
> will generate as 
> {code:groovy}
>     @groovy.transform.Generated
>     public static java.lang.Object javaBlockingTest(@groovy.transform.NamedParams(value = [@groovy.transform.NamedParam(value = 'packageName', type = java.lang.String), @groovy.transform.NamedParam(value = 'className', type = java.lang.String)]) java.util.Map namedArgs, java.io.File self) {
>         if ( namedArgs == null) {
>             throw new java.lang.IllegalArgumentException('Named parameter map cannot be null')
>         }
>         for (java.lang.String namedArgKey : namedArgs.keySet()) {
>             assert ['self', 'packageName', 'className'].contains( namedArgKey ) : 'Unrecognized namedArgKey: ' + namedArgKey }
>         return this.javaBlockingTest(self, namedArgs.containsKey('packageName') ? namedArgs.packageName : 'com.example', namedArgs.containsKey('className') ? namedArgs.className : 'BlockingTest')
>     }
> {code}
> Important to note is that the {{namedArgs}} parameter was moved before the {{self}} parameter, basically shifting the extended type from {{File}} to {{Map}}.
> If we handcraft
> {code:groovy}
>     public static java.lang.Object javaBlockingTest(java.io.File self, @groovy.transform.NamedParams(value = [@groovy.transform.NamedParam(value = 'packageName', type = java.lang.String), @groovy.transform.NamedParam(value = 'className', type = java.lang.String)]) java.util.Map namedArgs) {
> }
> {code}
> it works as expected.
> IMHO we would need a flag {{@NamedVariant(extensionMethod = true)}}, which changes the generated code by preserving the first parameter. 



--
This message was sent by Atlassian Jira
(v8.20.1#820001)