You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/09/12 16:26:28 UTC
[groovy] 15/19: GROOVY-9570: collect context generics starting at
innermost class/method
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 68ded928dde9f4aac016e456441d2f4e6f934d93
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Aug 29 20:09:29 2020 -0500
GROOVY-9570: collect context generics starting at innermost class/method
closes #1353
(cherry picked from commit ba63acef326cd206bd709cd6e9026bb656d54ad4)
---
.../transform/stc/StaticTypeCheckingSupport.java | 12 ++++++++++-
.../transform/stc/StaticTypeCheckingVisitor.java | 4 ++--
.../stc/ClosureParamTypeInferenceSTCTest.groovy | 24 ++++++++++++++++++++++
3 files changed, 37 insertions(+), 3 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 2a1dc79..b569fc9 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1991,7 +1991,17 @@ public abstract class StaticTypeCheckingSupport {
return false;
}
- static Map<GenericsTypeName, GenericsType> extractGenericsParameterMapOfThis(final MethodNode mn) {
+ static Map<GenericsTypeName, GenericsType> extractGenericsParameterMapOfThis(final TypeCheckingContext context) {
+ ClassNode cn = context.getEnclosingClassNode();
+ MethodNode mn = context.getEnclosingMethod();
+ // GROOVY-9570: find the innermost class or method
+ if (cn != null && cn.getEnclosingMethod() == mn) {
+ return getGenericsParameterMapOfThis(cn);
+ }
+ return extractGenericsParameterMapOfThis(mn);
+ }
+
+ private static Map<GenericsTypeName, GenericsType> extractGenericsParameterMapOfThis(final MethodNode mn) {
if (mn == null) return null;
Map<GenericsTypeName, GenericsType> map;
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 4e9ae6e..f977ce1 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -5100,7 +5100,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
if (resolvedPlaceholders.isEmpty()) {
return boundUnboundedWildcards(returnType);
}
- Map<GenericsTypeName, GenericsType> placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod());
+ Map<GenericsTypeName, GenericsType> placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext);
applyGenericsConnections(placeholdersFromContext, resolvedPlaceholders);
// then resolve receivers from method arguments
@@ -5271,7 +5271,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
private ClassNode resolveGenericsWithContext(final Map<GenericsTypeName, GenericsType> resolvedPlaceholders, final ClassNode currentType) {
- Map<GenericsTypeName, GenericsType> placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod());
+ Map<GenericsTypeName, GenericsType> placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext);
return resolveClassNodeGenerics(resolvedPlaceholders, placeholdersFromContext, currentType);
}
diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
index 618f46f..d991a6f 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -1376,6 +1376,30 @@ method()
'''
}
+ void testGroovy9570() {
+ assertScript '''
+ interface Item {}
+
+ class C<I extends Item> {
+ Queue<I> queue
+
+ def c = { ->
+ queue.each { I item ->
+ println item
+ }
+ }
+
+ def m() {
+ queue.each { I item ->
+ println item
+ }
+ }
+ }
+
+ new C()
+ '''
+ }
+
void testGroovy9597a() {
assertScript '''
import groovy.transform.stc.*