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

Eric Milles commented on GROOVY-6837:
-------------------------------------

 This is what I have so far.  It is efficient, but the type parameters are not 
true to the runtime behavior.  The simplest solution would be to have all the 
array plus methods return {{Object[]}}.  Another option is to have the right 
operand be of type {{Object[]}} and just describe the array store exception or 
provide inline coercion.

I looked for an example in Java and the closest I found was Arrays#fill, which 
is described this way (possibly for the same reasons): {{void fill(Object[] a, 
Object v)}}

{code:java}
    /**
     * Create an array as a union of two arrays.
     * <pre class="groovyTestCase">
     * Integer[] a = [1, 2, 3]
     * Integer[] b = [4, 5, 6]
     * def result = a + b
     * assert result.class == Integer[]
     * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
     *
     * Number[] c = [-1, 0.0, null]
     * result = c + a
     * assert result.class == Number[]
     * assert result == new Number[]{-1, 0.0, null, 1, 2, 3}
     * // improper type arguments; Number doesn't extend Integer
     * groovy.test.GroovyAssert.shouldFail(ArrayStoreException) { a + c }
     * </pre>
     *
     * @param left  the left Array
     * @param right the right Array
     * @return A new array containing right appended to left.
     * @since 1.8.7
     */
    public static <T> T[] plus(final T[] left, final T[] right) {
        T[] result = Arrays.copyOf(left, left.length + right.length);
        System.arraycopy(right, 0, result, left.length, right.length);
        return result;
    }

    /**
     * Create an array containing elements from an original array plus an 
additional appended element.
     * <pre class="groovyTestCase">
     * Integer[] a = [1, 2, 3]
     * def result = a + 4
     * assert result.class == Integer[]
     * assert result == new Integer[]{1, 2, 3, 4}
     *
     * // improper type arguments; Double doesn't extend Integer
     * groovy.test.GroovyAssert.shouldFail(ArrayStoreException) { a + 5d }
     * </pre>
     *
     * @param left  the array
     * @param right the value to append
     * @return A new array containing left with right appended to it.
     * @since 1.8.7
     */
    public static <T> T[] plus(final T[] left, final T right) {
        T[] result = Arrays.copyOf(left, left.length + 1);
        result[left.length] = right;
        return result;
    }

    /**
     * Create an array containing elements from an original array plus those 
from a Collection.
     * <pre class="groovyTestCase">
     * Integer[] a = [1, 2, 3]
     * def result = a + [4, 5]
     * assert result.class == Integer[]
     * assert result == new Integer[]{1, 2, 3, 4, 5}
     * </pre>
     *
     * @param left  the array
     * @param right a Collection to be appended
     * @return A new array containing left with right appended to it.
     * @since 1.8.7
     */
    public static <T> T[] plus(final T[] left, final Collection<? extends T> 
right) {
        T[] result = Arrays.copyOf(left, left.length + right.size());
        int i = left.length;
        for (T t : right) {
            result[i] = t;
            i += 1;
        }
        return result;
    }

    /**
     * Create an array containing elements from an original array plus those 
from an Iterable.
     * <pre class="groovyTestCase">
     * class AbcIterable implements Iterable<String> {
     *     Iterator<String> iterator() { "abc".iterator() }
     * }
     * String[] array = ['x', 'y', 'z']
     * def result = array + new AbcIterable()
     * assert result.class == String[]
     * assert result == new String[]{'x', 'y', 'z', 'a', 'b', 'c'}
     * </pre>
     *
     * @param left  the array
     * @param right an Iterable to be appended
     * @return A new array containing elements from left with those from right 
appended.
     * @since 1.8.7
     */
    public static <T> T[] plus(final T[] left, final Iterable<? extends T> 
right) {
        return plus(left, toList(right));
    }
{code}

> String[] + String[] gives Object[]
> ----------------------------------
>
>                 Key: GROOVY-6837
>                 URL: https://issues.apache.org/jira/browse/GROOVY-6837
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>    Affects Versions: 2.3.1
>            Reporter: Dmitry Ovchinnikov
>            Assignee: Eric Milles
>            Priority: Major
>         Attachments: image-2022-01-12-10-43-14-275.png
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> {code:java}
> def a1 = ["a", "b"] as String[], a2 = ["c", "d"] as String[];
> def concatenated = a1 + a2;
> java.nio.file.Paths.get("parent", concatenated)
> {code}
> ==>
> {noformat}
> groovy.lang.MissingMethodException: No signature of method: static 
> java.nio.file.Paths.get() is applicable for argument types: 
> (java.lang.String, [Ljava.lang.Object;) values: [parent, [a, b, c, d]]
> Possible solutions: get(java.lang.String, [Ljava.lang.String;), 
> get(java.net.URI), grep(), getAt(java.lang.String), wait(), any()
>       at 
> groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1373)
>       at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1359)
>       at 
> org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:50)
>       at 
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
>       at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
>       at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
>       at ideaGroovyConsole.run(ideaGroovyConsole.groovy:4)
>       at 
> groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:258)
>       at groovy.lang.GroovyShell.run(GroovyShell.java:502)
>       at groovy.lang.GroovyShell.run(GroovyShell.java:481)
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>       at java.lang.reflect.Method.invoke(Method.java:606)
>       at 
> org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:166)
>       at 
> org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:68)
>       at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
>       at console.run(console.txt:25)
> {noformat}



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

Reply via email to