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 2021/03/28 12:51:11 UTC
[groovy] 03/03: GROOVY-7128: STC: support "List list = [1, 2,
3]"
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 162e91b8cbc65baa4edac32a7b9089b43cfd1659
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 ++++++++++++++++++
2 files changed, 44 insertions(+), 2 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 8a7b9b3..7b6bc43 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4368,11 +4368,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
}
}
@@ -4425,6 +4425,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 0c7e11a..fa96651 100644
--- a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
@@ -720,4 +720,25 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
Queue<String> queue = []
''', 'Cannot assign value of type java.util.List <java.lang.String> 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
+ '''
+ }
}