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 2021/06/01 16:18:00 UTC

[jira] [Updated] (GROOVY-10120) STC: Guava Multimap#asMap bridge method

     [ https://issues.apache.org/jira/browse/GROOVY-10120?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Eric Milles updated GROOVY-10120:
---------------------------------
    Description: 
Consider the following:
{code:java}
@Grab('com.google.guava:guava:30.1.1-jre')
import com.google.common.collect.*

@groovy.transform.TypeChecked
void test() {
    ListMultimap<String, Integer> mmap = ArrayListMultimap.create()
    Map<String, Set<Integer>> map = mmap.asMap() // no STC error
    // ...
}
{code}

Due to the presence of multiple bridge methods in {{ArrayListMultimap}}, generics checking of {{asMap()}} is currently lacking.  The following are all bridge methods in {{ArrayListMultimap}} (30.1.1):
{code}
asMap()
equals(Object)
put(Object,Object)
replaceValues(Object,Iterable)
removeAll(Object)
get(Object)
forEach(BiConsumer)
entries()
values()
clear()
containsKey(Object)
size()
createCollection() // non-synthetic returns List not Collection
toString()
hashCode()
keys()
keySet()
putAll(Multimap)
putAll(Object,Iterable)
remove(Object,Object)
containsEntry(Object,Object)
containsValue(Object)
isEmpty()
{code}

  was:
When using CompileStatic and groovy 2.5.0, type checking appears wrong with [Guava's Multimap.asMap |https://google.github.io/guava/releases/25.1-jre/api/docs/com/google/common/collect/ListMultimap.html#asMap--] method.  Return type from that method is Map<K, Collection<V>>, but attempting to assign to a variable of that type results in the error message:
{noformat}
Incompatible generic argument types. Cannot assign java.util.Map <K, V> to: java.util.Map <K, Collection>
{noformat}
This previously worked fine with Groovy 2.4.15. Adding an explicit cast to the asMap() call appears to work around the error.

Here is a small script demonstrating the problem:
{code:java}
@Grab('com.google.guava:guava:25.1-jre')

import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.ListMultimap
import groovy.transform.CompileStatic

@CompileStatic
class Test {

    void test() {
        ListMultimap<String, Integer> mmap = ArrayListMultimap.create()
        // This extra cast fixes all the errors...
        //ListMultimap<String, Integer> mmap = ArrayListMultimap.create() as ListMultimap<String, Integer>
        Map<String, Collection<Integer>> map = mmap.asMap()
        
        Set<Map.Entry<String, Collection<Integer>>> entrySet = map.entrySet()
        Iterator<Map.Entry<String, Collection<Integer>>> iter = entrySet.iterator()
        
        while (iter.hasNext()) {
            Map.Entry<String, Collection<Integer>> group = iter.next()
            Collection<Integer> values = group.value
        }
    }
    
    static void main(String... args) {
        Test test = new Test()
        test.test()
    }
    
}
{code}
And the full error output:
{noformat}
5 compilation errors:

[Static type checking] - Incompatible generic argument types. Cannot assign java.util.Map <java.lang.String, java.lang.Integer> to: java.util.Map <String, Collection>
 at line: 14, column: 48

[Static type checking] - Incompatible generic argument types. Cannot assign java.util.Set <java.util.Map$Entry> to: java.util.Set <Map.Entry>
 at line: 16, column: 64

[Static type checking] - Incompatible generic argument types. Cannot assign java.util.Iterator <java.util.Map$Entry> to: java.util.Iterator <Map.Entry>
 at line: 17, column: 65

[Static type checking] - Incompatible generic argument types. Cannot assign java.util.Map$Entry <java.lang.String, java.lang.Integer> to: java.util.Map$Entry <String, Collection>
 at line: 20, column: 60

[Static type checking] - Cannot assign value of type java.lang.Integer to variable of type java.util.Collection <Integer>
 at line: 21, column: 42
{noformat}


> STC: Guava Multimap#asMap bridge method
> ---------------------------------------
>
>                 Key: GROOVY-10120
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10120
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.5.0, 3.0.5
>            Reporter: Eric Milles
>            Assignee: Eric Milles
>            Priority: Major
>             Fix For: 4.0.0-beta-1
>
>
> Consider the following:
> {code:java}
> @Grab('com.google.guava:guava:30.1.1-jre')
> import com.google.common.collect.*
> @groovy.transform.TypeChecked
> void test() {
>     ListMultimap<String, Integer> mmap = ArrayListMultimap.create()
>     Map<String, Set<Integer>> map = mmap.asMap() // no STC error
>     // ...
> }
> {code}
> Due to the presence of multiple bridge methods in {{ArrayListMultimap}}, generics checking of {{asMap()}} is currently lacking.  The following are all bridge methods in {{ArrayListMultimap}} (30.1.1):
> {code}
> asMap()
> equals(Object)
> put(Object,Object)
> replaceValues(Object,Iterable)
> removeAll(Object)
> get(Object)
> forEach(BiConsumer)
> entries()
> values()
> clear()
> containsKey(Object)
> size()
> createCollection() // non-synthetic returns List not Collection
> toString()
> hashCode()
> keys()
> keySet()
> putAll(Multimap)
> putAll(Object,Iterable)
> remove(Object,Object)
> containsEntry(Object,Object)
> containsValue(Object)
> isEmpty()
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)