You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2018/12/09 08:13:00 UTC

[jira] [Comment Edited] (GROOVY-8907) StringGroovyMethods.findAll(String, Pattern, Closure) and StringGroovyMethods.findAll(CharSequence, Pattern, Closure) is with @ClosureParams incorrect

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

Paul King edited comment on GROOVY-8907 at 12/9/18 8:12 AM:
------------------------------------------------------------

There are a few aspects to this issue.

Groovy does automatic coercion of lists into arrays for Closure parameters, e.g.:
{code}
def repeatString = { String x, int y -> x * y }
assert repeatString ('*', 4) == '****'
assert repeatString (['*', 4]) == '****'
{code}
So, if we know that {{String[]}} is supported, we always know {{List<String>}} will be supported.

Currently, Intellij doesn't seem to know this. Perhaps programmers don't know either and the additional information you supplied, while not essential, could be considered a useful reminder for users of the DGM methods.

Secondly, the fact that {{String[]}} is the designated type isn't intended to mean that you have a single {{String[]}} parameter. Instead it is for the explicit multi-arg style:
{code}
"75001 Paris".find(/(\d{5})\s(\w+)/) { all, code, city -> println "$code ${city.toUpperCase()}" }
{code}
You'll get the same {{ClassCastException}} before and after your change wrt the {{String[]}} parameter.

In some sense, that {{ClassCastException}} is a little misleading. Groovy is trying to do the auto-list coercion. At one point it detects that the coercion is possible but at the point that the exception occurs it has converted the "object" list ['75001 Paris', '75001', 'Paris'] to the String "['75001 Paris', '75001', 'Paris']" in a String array of size 1, then it is trying to convert that string array into a list.



was (Author: paulk):
There are a few aspects to this issue.

Groovy does automatic coercion of lists into arrays for Closure parameters, e.g.:
{code}
def pairToString = { String x, int y -> x * y }
assert pairToString('*', 4) == '****'
assert pairToString(['*', 4]) == '****'
{code}
So, if we know that {{String[]}} is supported, we always know {{List<String>}} will be supported.

Currently, Intellij doesn't seem to know this. Perhaps programmers don't know either and the additional information you supplied, while not essential, could be considered a useful reminder for users of the DGM methods.

Secondly, the fact that {{String[]}} is the designated type isn't intended to mean that you have a single {{String[]}} parameter. Instead it is for the explicit multi-arg style:
{code}
"75001 Paris".find(/(\d{5})\s(\w+)/) { all, code, city -> println "$code ${city.toUpperCase()}" }
{code}
You'll get the same {{ClassCastException}} before and after your change wrt the {{String[]}} parameter.

In some sense, that {{ClassCastException}} is a little misleading. Groovy is trying to do the auto-list coercion. At one point it detects that the coercion is possible but at the point that the exception occurs it has converted the "object" list ['75001 Paris', '75001', 'Paris'] to the String "['75001 Paris', '75001', 'Paris']" in a String array of size 1, then it is trying to convert that string array into a list.


> StringGroovyMethods.findAll(String, Pattern, Closure) and StringGroovyMethods.findAll(CharSequence, Pattern, Closure) is with @ClosureParams incorrect
> ------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-8907
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8907
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>    Affects Versions: 3.x, 2.4.x, 2.5.x, 3.0.0-alpha-4, 2.6.0-alpha-5
>            Reporter: Henrique Mota
>            Priority: Minor
>         Attachments: image.png
>
>
> StringGroovyMethods.find(arg1, arg2, Closure) and  StringGroovyMethods.findAll(arg1, arg2, Closure) is with @ClosureParams(value=SimpleType.class, options="java.lang.String[]") but the Closure receive a instance of List<String> from DefaultGroovyMethods.collect(matcher, closure), this cause a Exception
> {code:java}
> Caught: java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.util.List
> java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.util.List
> at CLass.m(brasileiro.groovy:7)
> at CLass$m.call(Unknown Source)
> at brasileiro.run(brasileiro.groovy:13)
> {code}
> Exemple:
> {code:java}
> import groovy.transform.CompileStatic
> @CompileStatic
> class CLass {
>     List m(){
>         String string = 'ABCD'
>         //ClassCastException here
>         return string.findAll(/(A)(B)(C)/) { String[] group->
>              return group[2]
>         }
>     }
> }
> new CLass().m(){code}
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)