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 <[email protected]> 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'])
