You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/09/12 17:54:44 UTC
[groovy] branch GROOVY_3_0_X updated: GROOVY-10052: STC: resolve SAM return type before extracing conections
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
new 3173d7312b GROOVY-10052: STC: resolve SAM return type before extracing conections
3173d7312b is described below
commit 3173d7312b81af498cd3fe3f846103757f2f1bf9
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Sep 12 12:18:53 2022 -0500
GROOVY-10052: STC: resolve SAM return type before extracing conections
---
.../transform/stc/StaticTypeCheckingSupport.java | 9 +++----
.../transform/stc/StaticTypeCheckingVisitor.java | 10 +++++++-
src/test/groovy/bugs/Groovy8310.groovy | 30 ++++++++++------------
.../groovy/transform/stc/ClosuresSTCTest.groovy | 4 +--
4 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index df46cfe2b9..6ca1e6bc04 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -94,7 +94,6 @@ import static org.codehaus.groovy.ast.ClassHelper.boolean_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.byte_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.char_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.double_TYPE;
-import static org.codehaus.groovy.ast.ClassHelper.findSAM;
import static org.codehaus.groovy.ast.ClassHelper.float_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.getUnwrapper;
import static org.codehaus.groovy.ast.ClassHelper.getWrapper;
@@ -1702,17 +1701,15 @@ public abstract class StaticTypeCheckingSupport {
if (target == null || target == type || !isUsingGenericsOrIsArrayUsingGenerics(target)) return;
if (type == null || type == UNKNOWN_PARAMETER_TYPE) return;
- MethodNode sam;
-
if (target.isGenericsPlaceHolder()) {
connections.put(new GenericsTypeName(target.getUnresolvedName()), new GenericsType(type));
} else if (type.isArray() && target.isArray()) {
extractGenericsConnections(connections, type.getComponentType(), target.getComponentType());
- } else if (type.equals(CLOSURE_TYPE) && (sam = findSAM(target)) != null) {
- // GROOVY-9974: Lambda, Closure, Pointer or Reference for SAM-type receiver
- ClassNode returnType = StaticTypeCheckingVisitor.wrapTypeIfNecessary(sam.getReturnType());
+ } else if (type.equals(CLOSURE_TYPE) && isSAMType(target)) {
+ // GROOVY-9974, GROOVY-10052: Lambda, Closure, Pointer or Reference for SAM-type receiver
+ ClassNode returnType = StaticTypeCheckingVisitor.wrapTypeIfNecessary(GenericsUtils.parameterizeSAM(target).getV2());
extractGenericsConnections(connections, type.getGenericsTypes(), new GenericsType[] {new GenericsType(returnType)});
} else if (type.equals(target) || !implementsInterfaceOrIsSubclassOf(type, target)) {
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 75f8027297..3c44234b0b 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -3530,9 +3530,17 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
ClassNode returnType = getType(directMethodCallCandidate);
if (isUsingGenericsOrIsArrayUsingGenerics(returnType)) {
visitMethodCallArguments(chosenReceiver.getType(), argumentList, true, directMethodCallCandidate);
+ for (Expression argument : argumentList.getExpressions()) {
+ if (argument instanceof ClosureExpression) {
+ // GROOVY-10052: return type known now
+ args = getArgumentTypes(argumentList);
+ break;
+ }
+ }
+ callArgsVisited = true;
+
ClassNode irtg = inferReturnTypeGenerics(chosenReceiver.getType(), directMethodCallCandidate, callArguments, call.getGenericsTypes());
returnType = (irtg != null && implementsInterfaceOrIsSubclassOf(irtg, returnType) ? irtg : returnType);
- callArgsVisited = true;
}
// GROOVY-6091: use of "delegate" or "getDelegate()" does not make use of @DelegatesTo metadata
if (directMethodCallCandidate == GET_DELEGATE && typeCheckingContext.getEnclosingClosure() != null) {
diff --git a/src/test/groovy/bugs/Groovy8310.groovy b/src/test/groovy/bugs/Groovy8310.groovy
index 838566faf8..5a142eeae7 100644
--- a/src/test/groovy/bugs/Groovy8310.groovy
+++ b/src/test/groovy/bugs/Groovy8310.groovy
@@ -18,13 +18,11 @@
*/
package groovy.bugs
-import groovy.transform.CompileStatic
import org.junit.Test
import static groovy.test.GroovyAssert.assertScript
import static groovy.test.GroovyAssert.shouldFail
-@CompileStatic
final class Groovy8310 {
@Test
@@ -35,84 +33,82 @@ final class Groovy8310 {
}
@groovy.transform.CompileStatic
- def use() {
+ def foo() {
bar {
[1]
}
}
'''
-
assert err =~ /Cannot find matching method \w+#bar\(groovy.lang.Closure <java.util.List>\)/
}
@Test
void testClosureReturnType2() {
def err = shouldFail '''
- public <T> T bar(Closure<Collection<Integer>> block) {
+ def <T> T bar(Closure<Collection<Integer>> block) {
block()
}
@groovy.transform.CompileStatic
- def use() {
+ def foo() {
bar {
[1]
}
}
'''
-
- assert err =~ /Cannot find matching method \w+#bar\(groovy.lang.Closure <java.util.List>\)/
+ assert err =~ /Cannot call <T> \w+#bar\(groovy.lang.Closure <java.util.Collection>\) with arguments \[groovy.lang.Closure <java.util.List>\]/
}
@Test
void testClosureReturnType3() {
assertScript '''
- public <T> T bar(Closure<? extends Collection<Integer>> block) {
+ def <T> T bar(Closure<? extends Collection<Integer>> block) {
block()
}
@groovy.transform.CompileStatic
- def use() {
+ def foo() {
bar {
[1]
}
}
- assert use() == [1]
+ assert foo() == [1]
'''
}
@Test
void testClosureReturnType4() {
assertScript '''
- public <T> T bar(Closure<Collection<Integer>> block) {
+ def <T> T bar(Closure<Collection<Integer>> block) {
block()
}
@groovy.transform.CompileStatic
- def use() {
+ def foo() {
bar {
(Collection<Integer>) [1]
}
}
- assert use() == [1]
+ assert foo() == [1]
'''
}
@Test
void testClosureReturnType5() {
assertScript '''
- public <T> T bar(Closure<Collection<Integer>> block) {
+ def <T> T bar(Closure<Collection<Integer>> block) {
block()
}
- def use() {
+ def foo() {
bar {
[1] as Collection<Integer>
}
}
- assert use() == [1]
+ assert foo() == [1]
'''
}
}
diff --git a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
index 0cdefd461b..c60c723b8b 100644
--- a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
@@ -18,8 +18,6 @@
*/
package groovy.transform.stc
-import groovy.test.NotYetImplemented
-
/**
* Unit tests for static type checking : closures.
*/
@@ -351,7 +349,7 @@ class ClosuresSTCTest extends StaticTypeCheckingTestCase {
'''
}
- @NotYetImplemented // GROOVY-10052
+ // GROOVY-10052
void testClosureSharedVariable5() {
assertScript '''
def x