This is an automated email from the ASF dual-hosted git repository. paulk pushed a commit to branch GROOVY_2_5_X in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push: new c51fffa GROOVY-9517: use inferred right expression type for array checks (port to 2_5_X) c51fffa is described below commit c51fffacecb719ac378143cbd7d0d4e9df4f454f Author: Eric Milles <eric.mil...@thomsonreuters.com> AuthorDate: Wed Apr 22 10:41:01 2020 -0500 GROOVY-9517: use inferred right expression type for array checks (port to 2_5_X) --- .../transform/stc/StaticTypeCheckingVisitor.java | 35 ++++++++--------- .../stc/ArraysAndCollectionsSTCTest.groovy | 45 +++++++++++++++------- 2 files changed, 48 insertions(+), 32 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 5738530..a7c68fd 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -1141,30 +1141,29 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { return true; } - private void addPrecisionErrors(ClassNode leftRedirect, ClassNode lhsType, ClassNode inferredrhsType, Expression rightExpression) { - if (isNumberType(leftRedirect) && isNumberType(inferredrhsType)) { - if (checkPossibleLossOfPrecision(leftRedirect, inferredrhsType, rightExpression)) { - addStaticTypeError("Possible loss of precision from " + inferredrhsType + " to " + leftRedirect, rightExpression); + private void addPrecisionErrors(ClassNode leftRedirect, ClassNode lhsType, ClassNode rhsType, Expression rightExpression) { + if (isNumberType(leftRedirect)) { + if (isNumberType(rhsType) && checkPossibleLossOfPrecision(leftRedirect, rhsType, rightExpression)) { + addStaticTypeError("Possible loss of precision from " + rhsType.toString(false) + " to " + lhsType.toString(false), rightExpression); return; } } - // if left type is array, we should check the right component types - if (!lhsType.isArray()) return; - ClassNode leftComponentType = lhsType.getComponentType(); - ClassNode rightRedirect = rightExpression.getType().redirect(); - if (rightRedirect.isArray()) { - ClassNode rightComponentType = rightRedirect.getComponentType(); - if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType)) { - addStaticTypeError("Cannot assign value of type " + rightComponentType.toString(false) + " into array of type " + lhsType.toString(false), rightExpression); - } - } else if (rightExpression instanceof ListExpression) { - for (Expression element : ((ListExpression) rightExpression).getExpressions()) { - ClassNode rightComponentType = this.getType(element); - if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType) - && !(isNullConstant(element) && !isPrimitiveType(leftComponentType))) { + if (!leftRedirect.isArray()) return; + // left type is array, check the right component types + if (rightExpression instanceof ListExpression) { + ClassNode leftComponentType = leftRedirect.getComponentType(); + for (Expression expression : ((ListExpression) rightExpression).getExpressions()) { + ClassNode rightComponentType = getType(expression); + if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType) && !(isNullConstant(expression) && !isPrimitiveType(leftComponentType))) { addStaticTypeError("Cannot assign value of type " + rightComponentType.toString(false) + " into array of type " + lhsType.toString(false), rightExpression); } } + } else if (rhsType.redirect().isArray()) { + ClassNode leftComponentType = leftRedirect.getComponentType(); + ClassNode rightComponentType = rhsType.redirect().getComponentType(); + if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType)) { + addStaticTypeError("Cannot assign value of type " + rightComponentType.toString(false) + " into array of type " + lhsType.toString(false), rightExpression); + } } } diff --git a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy index e248442..5db186b 100644 --- a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy +++ b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy @@ -91,6 +91,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase { for (int i in arr) { } ''', 'Cannot loop with element of type int with collection of type java.lang.String[]' } + void testJava5StyleForLoopWithArray() { assertScript ''' String[] arr = ['1','2','3'] @@ -321,6 +322,20 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase { ''', 'Cannot assign value of type Foo[] to variable of type FooAnother' } + // GROOVY-9517 + void testShouldAllowArrayAssignment() { + assertScript ''' + void test(File directory) { + File[] files = directory.listFiles() + files = files?.sort { it.name } + for (file in files) { + // ... + } + } + println 'works' + ''' + } + void testListPlusEquals() { assertScript ''' List<String> list = ['a','b'] @@ -334,7 +349,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase { assert list == ['a','b','c'] ''' } - + void testObjectArrayGet() { assertScript ''' Object[] arr = [new Object()] @@ -478,18 +493,21 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase { // GROOVY-5793 void testShouldNotForceAsTypeWhenListOfNullAssignedToArray() { assertScript ''' - Integer[] m() { - Integer[] arr = [ null, null ] - } - assert m().length == 2 + Integer[] m() { + Integer[] array = [ null, null ] + return array + } + assert m().length == 2 ''' } + void testShouldNotForceAsTypeWhenListOfNullAssignedToArrayUnlessPrimitive() { shouldFailWithMessages ''' - int[] m() { - int[] arr = [ null, null ] - } - ''', 'into array of type' + int[] m() { + int[] array = [ null, null ] + return array + } + ''', 'Cannot assign value of type java.lang.Object into array of type int[]' } // GROOVY-6131 @@ -512,7 +530,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase { assert AR.'key'[0] == ['val1'] """ } - + // GROOVY-6311 void testSetSpread() { assertScript """ @@ -525,7 +543,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase { assert res[0].contains('def') """ } - + // GROOVY-6241 void testAsImmutable() { assertScript """ @@ -535,7 +553,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase { Map<String, Integer> immutableMap = [foo: 123, bar: 456].asImmutable() """ } - + // GROOVY-6350 void testListPlusList() { assertScript """ @@ -566,8 +584,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase { Set<Foo> foos = [new Foo(name: 'pls'), new Foo(name: 'bar')].toSet() foos*.name } - assert meth().toSet() == ['pls', 'bar'].toSet() + assert meth().toSet() == ['pls', 'bar'].toSet() ''' } } -