You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Damir Murat (Jira)" <ji...@apache.org> on 2021/04/23 08:52:00 UTC

[jira] [Created] (GROOVY-10052) STC sometimes requires explicit closure to SAM cast inside of another closure

Damir Murat created GROOVY-10052:
------------------------------------

             Summary: STC sometimes requires explicit closure to SAM cast inside of another closure
                 Key: GROOVY-10052
                 URL: https://issues.apache.org/jira/browse/GROOVY-10052
             Project: Groovy
          Issue Type: Improvement
          Components: Static compilation, Static Type Checker
    Affects Versions: 3.0.8
            Reporter: Damir Murat


After upgrading to the 3.0.8 version, I observed several improvements in STC, but it looks like some cases are still uncovered. Say I have the following script (tested with Groovy console):
{code:java}
import groovy.transform.CompileStatic

import java.util.function.Predicate
import java.util.function.Supplier
import java.util.stream.Collectors

@CompileStatic
class Test {
  void testMe() {
    String maybeSomeString = Optional.of("Some Name")
        .orElseThrow({ new NoSuchElementException("Nothing found") }) // line 1 - no explicit cast

    println maybeSomeString
    
    List stringList = ["1ab", "2cd"]
        .stream()
        .flatMap({ it.toList().stream() })
        .filter({ Character.isLetterOrDigit(it.chars[0]) }) // line 2 - no explicit cast
        .collect(Collectors.toList())
    
    println stringList

    [1, 2, 3]
        .stream()
        .map({
          String maybeSomeOtherString = Optional
              .of("Some Other Name")
              .orElseThrow({ new NoSuchElementException("Nothing found") } as Supplier) // line 3 - explicit cast needed

          return "$it: $maybeSomeOtherString".toString()
        })
        .peek({
          List list = it.toList()
              .stream()
              .filter({ Character.isLetterOrDigit(it.chars[0]) }) // line 4 - no explicit cast and no explicit parameter type
              .collect(Collectors.toList())

          println list
        })
        .forEach({println it })
  }
}

new Test().testMe()
{code}

In line 3, an explicit cast to Supplier is needed. It wasn't required for 3.0.7. When removed, the checker throws

{code}
[Static type checking] - Cannot call <X extends java.lang.Throwable> java.util.Optional <java.lang.String>#orElseThrow(java.util.function.Supplier <? extends X>) with arguments [groovy.lang.Closure <java.util.NoSuchElementException>] 
 at line: 26, column: 41
{code}

As can be seen from the sample, coercion works if the closure is not nested inside of another closure.

For comparison, with the 3.0.7 version, line 1 and 2 behaves the same as for 3.0.8.
In 3.0.7, line 3 did not require an explicit cast. In line 4, 3.0.7 requires explicit cast and explicit parameter declaration, while 3.0.8 does not require either.

Tnx



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