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 2023/01/26 18:07:04 UTC
[groovy] 03/04: GROOVY-7128: STC: support "List list = [1,2,3]"
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 fcbd0a0d93453c46dadd101a5ca548d06346158a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Mar 27 17:41:39 2021 -0500
GROOVY-7128: STC: support "List<Number> list = [1,2,3]"
---
.../transform/stc/StaticTypeCheckingVisitor.java | 25 ++++++++++++++++++++--
.../stc/ArraysAndCollectionsSTCTest.groovy | 21 ++++++++++++++++++
.../stc/DefaultGroovyMethodsSTCTest.groovy | 2 +-
3 files changed, 45 insertions(+), 3 deletions(-)
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 3affb67462..e4945662e5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4524,11 +4524,11 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
|| ITERABLE_TYPE.equals(leftRedirect)
|| Collection_TYPE.equals(leftRedirect)
|| ArrayList_TYPE.isDerivedFrom(leftRedirect)) { // GROOVY-6912
- return GenericsUtils.parameterizeType(right, ArrayList_TYPE.getPlainNodeReference());
+ return getLiteralResultType(left, right, ArrayList_TYPE); // GROOVY-7128
}
if (SET_TYPE.equals(leftRedirect)
|| LinkedHashSet_TYPE.isDerivedFrom(leftRedirect)) { // GROOVY-6912
- return GenericsUtils.parameterizeType(right, LinkedHashSet_TYPE.getPlainNodeReference());
+ return getLiteralResultType(left, right, LinkedHashSet_TYPE); // GROOVY-7128
}
}
@@ -4587,6 +4587,27 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
return null;
}
+ /**
+ * For "{@code List<Type> x = [...]}" or "{@code Set<Type> y = [...]}", etc.
+ * the literal may be composed of sub-types of {@code Type}. In these cases,
+ * {@code ArrayList<Type>} is an appropriate result type for the expression.
+ */
+ private ClassNode getLiteralResultType(final ClassNode targetType, final ClassNode sourceType, final ClassNode baseType) {
+ ClassNode resultType = sourceType.equals(baseType) ? sourceType
+ : GenericsUtils.parameterizeType(sourceType, baseType.getPlainNodeReference());
+
+ if (targetType.getGenericsTypes() != null
+ && !GenericsUtils.buildWildcardType(targetType).isCompatibleWith(resultType)) {
+ GenericsType[] lgt = targetType.getGenericsTypes(), rgt = resultType.getGenericsTypes();
+ if (!lgt[0].isPlaceholder() && !lgt[0].isWildcard() && GenericsUtils.buildWildcardType(
+ getCombinedBoundType(lgt[0])).isCompatibleWith(getCombinedBoundType(rgt[0]))) {
+ resultType = GenericsUtils.parameterizeType(targetType, baseType.getPlainNodeReference());
+ }
+ }
+
+ return resultType;
+ }
+
private ClassNode getMathResultType(final int op, final ClassNode leftRedirect, final ClassNode rightRedirect, final String operationName) {
if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) {
if (isOperationInGroup(op)) {
diff --git a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
index c7a467a19c..970d5d63ec 100644
--- a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
@@ -887,4 +887,25 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
''',
'Cannot assign value of type java.util.List', ' to variable of type java.util.Queue <String>'
}
+
+ // GROOVY-7128
+ void testCollectionTypesInitializedByListLiteral4() {
+ assertScript '''
+ Collection<Number> collection = [1,2,3]
+ assert collection.size() == 3
+ assert collection.last() == 3
+ '''
+
+ assertScript '''
+ List<Number> list = [1,2,3]
+ assert list.size() == 3
+ assert list.last() == 3
+ '''
+
+ assertScript '''
+ Set<Number> set = [1,2,3,3]
+ assert set.size() == 3
+ assert set.last() == 3
+ '''
+ }
}
diff --git a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
index f9401f7957..b481e43e62 100644
--- a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
@@ -108,7 +108,7 @@ class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase {
'''
shouldFailWithMessages '''
- List<Number> numbers = [(Number)1, 2, 3]
+ List<Number> numbers = [1, 2, 3]
numbers.getSequence()
numbers.getString()
numbers.sequence