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/01/29 21:14:21 UTC
[groovy] 02/02: GROOVY-8974: STC: missesGenericsTypes(ClassNode) true for unresolved <>
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
commit a2856d92a48283321af3b0ec05e8ff23e27ce7fb
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun May 2 09:29:12 2021 -0500
GROOVY-8974: STC: missesGenericsTypes(ClassNode) true for unresolved <>
Conflicts:
src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
src/test/groovy/transform/stc/GenericsSTCTest.groovy
---
.../transform/stc/StaticTypeCheckingSupport.java | 28 +++++++---------------
.../transform/stc/StaticTypeCheckingVisitor.java | 7 +++---
.../groovy/transform/stc/GenericsSTCTest.groovy | 11 +++++++++
3 files changed, 22 insertions(+), 24 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 4069ff6..5a63f55 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -2098,26 +2098,14 @@ public abstract class StaticTypeCheckingSupport {
return node.getSuperClass() != null && isParameterizedWithString(node.getUnresolvedSuperClass());
}
- public static boolean missesGenericsTypes(final ClassNode cn) {
- if (cn.isArray()) return missesGenericsTypes(cn.getComponentType());
- GenericsType[] cnTypes = cn.getGenericsTypes();
- GenericsType[] rnTypes = cn.redirect().getGenericsTypes();
- if (rnTypes != null && cnTypes == null) return true;
- if (cnTypes != null) {
- for (GenericsType genericsType : cnTypes) {
- if (genericsType.isPlaceholder()) return true;
- if (genericsType.isWildcard()) {
- ClassNode lowerBound = genericsType.getLowerBound();
- ClassNode[] upperBounds = genericsType.getUpperBounds();
- if (lowerBound != null) {
- if (lowerBound.isGenericsPlaceHolder() || missesGenericsTypes(lowerBound)) return true;
- } else if (upperBounds != null) {
- if (upperBounds[0].isGenericsPlaceHolder() || missesGenericsTypes(upperBounds[0])) return true;
- }
- }
- }
- }
- return false;
+ /**
+ * Determines if node is a raw type or references any generics placeholders.
+ */
+ public static boolean missesGenericsTypes(ClassNode cn) {
+ while (cn.isArray()) cn = cn.getComponentType();
+ GenericsType[] cnGenerics = cn.getGenericsTypes();
+ GenericsType[] rnGenerics = cn.redirect().getGenericsTypes();
+ return cnGenerics == null || cnGenerics.length == 0 ? rnGenerics != null : GenericsUtils.hasUnresolvedGenerics(cn);
}
/**
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 2bf2504..69feed6 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -798,6 +798,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
boolean isAssignment = isAssignment(expression.getOperation().getType());
+ if (isAssignment && rightExpression instanceof ConstructorCallExpression) {
+ inferDiamondType((ConstructorCallExpression) rightExpression, lType);
+ }
if (isAssignment && lType.isUsingGenerics() && missesGenericsTypes(resultType)) {
// unchecked assignment
// examples:
@@ -833,10 +836,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
boolean isEmptyDeclaration = (expression instanceof DeclarationExpression && rightExpression instanceof EmptyExpression);
if (isAssignment && !isEmptyDeclaration) {
- if (rightExpression instanceof ConstructorCallExpression) {
- inferDiamondType((ConstructorCallExpression) rightExpression, lType);
- }
-
ClassNode originType = getOriginalDeclarationType(leftExpression);
typeCheckAssignment(expression, leftExpression, originType, rightExpression, resultType);
// if assignment succeeds but result type is not a subtype of original type, then we are in a special cast handling
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 1ef7b24..ce74806 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -325,6 +325,17 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-8974
+ void testDiamondInferrenceFromConstructor8() {
+ assertScript '''
+ def <T> T identity(T t) { t }
+ List<String> list = identity(new ArrayList<>())
+ list.add('foo')
+ def foo = list[0]
+ assert foo.toUpperCase() == 'FOO'
+ '''
+ }
+
void testLinkedListWithListArgument() {
assertScript '''
List<String> list = new LinkedList<String>(['1','2','3'])