Skip to content

Commit 1265aca

Browse files
authored
GROOVY-9985, GROOVY-9994, GROOVY-10111: STC: check array sizes and values (not like cast)
1 parent 84b03c4 commit 1265aca

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4121,14 +4121,20 @@ protected Map<VariableExpression, List<ClassNode>> pushAssignmentTracking() {
41214121
}
41224122

41234123
@Override
4124-
public void visitArrayExpression(ArrayExpression source) {
4125-
super.visitArrayExpression(source);
4126-
ClassNode elementType = source.getElementType();
4127-
for (Expression expression : source.getExpressions()) {
4128-
if (!checkCast(elementType, expression)) {
4129-
addStaticTypeError("Cannot assign value of type " +
4130-
prettyPrintType(getType(expression)) + " into array of type " +
4131-
prettyPrintType(source.getType()), expression);
4124+
public void visitArrayExpression(final ArrayExpression expression) {
4125+
super.visitArrayExpression(expression);
4126+
ClassNode elementType;
4127+
List<Expression> expressions;
4128+
if (expression.hasInitializer()) {
4129+
elementType = expression.getElementType();
4130+
expressions = expression.getExpressions();
4131+
} else {
4132+
elementType = int_TYPE;
4133+
expressions = expression.getSizeExpression();
4134+
}
4135+
for (Expression elementExpr : expressions) {
4136+
if (!checkCompatibleAssignmentTypes(elementType, getType(elementExpr), elementExpr, false)) {
4137+
addStaticTypeError("Cannot convert from " + prettyPrintType(getType(elementExpr)) + " to " + prettyPrintType(elementType), elementExpr);
41324138
}
41334139
}
41344140
}

src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
2727
assertScript '''
2828
String[] strings = ['a','b','c']
2929
String str = strings[0]
30+
assert str == 'a'
3031
'''
3132
}
3233

33-
void testArrayElementReturnType() {
34+
void testArrayElementTypeInference() {
3435
shouldFailWithMessages '''
3536
String[] strings = ['a','b','c']
3637
int str = strings[0]
@@ -43,10 +44,43 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
4344
''', 'Cannot assign value of type java.lang.String into array of type int[]'
4445
}
4546

47+
// GROOVY-9985, GROOVY-9994
4648
void testWrongComponentTypeInArrayInitializer() {
4749
shouldFailWithMessages '''
48-
int[] intArray = new int[]{'a'}
49-
''', 'Cannot assign value of type java.lang.String into array of type int[]'
50+
new int['a']
51+
''', 'Cannot convert from java.lang.String to int'
52+
shouldFailWithMessages '''
53+
new int[]{'a'}
54+
''', 'Cannot convert from java.lang.String to int'
55+
shouldFailWithMessages '''
56+
new Integer[]{new Object(),1}
57+
''', 'Cannot convert from java.lang.Object to java.lang.Integer'
58+
}
59+
60+
// GROOVY-10111
61+
void testBoundedComponentTypeInArrayInitializer() {
62+
assertScript '''
63+
class C<X, Y> {
64+
}
65+
def <X extends C<Number, String>> X[] m() {
66+
new X[]{new C<Number, String>()}
67+
}
68+
'''
69+
shouldFailWithMessages '''
70+
class C<X, Y> {
71+
}
72+
def <X extends C<Number, String>> X[] m() {
73+
new X[]{new C<Object, String>()}
74+
}
75+
''', 'Cannot convert from C<java.lang.Object, java.lang.String> to X'
76+
}
77+
78+
void testConvertibleTypesInArrayInitializer() {
79+
assertScript '''
80+
def strings = new String[]{1,(long)2,(short)3}
81+
assert strings.every { it.class == String }
82+
assert strings.toString() == '[1, 2, 3]'
83+
'''
5084
}
5185

5286
void testAssignValueInArrayWithCorrectType() {

0 commit comments

Comments
 (0)