Repository: groovy
Updated Branches:
  refs/heads/master 43c75a23f -> 95f692dc4


GROOVY-8882: CS: Loop over elements of String has different element type 
(closes #827)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/5d4a951b
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/5d4a951b
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/5d4a951b

Branch: refs/heads/master
Commit: 5d4a951bb653bb1a7c8570d28246396eaa3e0713
Parents: 43c75a2
Author: Paul King <pa...@asert.com.au>
Authored: Wed Nov 21 14:35:36 2018 +1000
Committer: Paul King <pa...@asert.com.au>
Committed: Sat Nov 24 14:41:18 2018 +1000

----------------------------------------------------------------------
 .../transform/sc/StaticCompilationVisitor.java    | 11 ++++++++++-
 .../transform/stc/StaticTypeCheckingVisitor.java  | 10 ++++++++--
 src/test/groovy/transform/stc/LoopsSTCTest.groovy | 18 ++++++++++++++++++
 3 files changed, 36 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/5d4a951b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java 
b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
index f66b24a..036dbe5 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
@@ -72,6 +72,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static org.codehaus.groovy.ast.ClassHelper.Character_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics;
 import static 
org.codehaus.groovy.ast.tools.GenericsUtils.applyGenericsContextToPlaceHolders;
 import static 
org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
@@ -440,7 +442,14 @@ public class StaticCompilationVisitor extends 
StaticTypeCheckingVisitor {
         Expression collectionExpression = forLoop.getCollectionExpression();
         if (!(collectionExpression instanceof ClosureListExpression)) {
             final ClassNode collectionType = 
getType(forLoop.getCollectionExpression());
-            ClassNode componentType = inferLoopElementType(collectionType);
+            ClassNode forLoopVariableType = forLoop.getVariableType();
+            ClassNode componentType;
+            if 
(Character_TYPE.equals(ClassHelper.getWrapper(forLoopVariableType)) && 
STRING_TYPE.equals(collectionType)) {
+                // we allow auto-coercion here
+                componentType = forLoopVariableType;
+            } else {
+                componentType = inferLoopElementType(collectionType);
+            }
             forLoop.getVariable().setType(componentType);
             forLoop.getVariable().setOriginType(componentType);
         }

http://git-wip-us.apache.org/repos/asf/groovy/blob/5d4a951b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
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 de2abff..12a48d3 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1886,8 +1886,14 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         } else {
             collectionExpression.visit(this);
             final ClassNode collectionType = getType(collectionExpression);
-            ClassNode componentType = inferLoopElementType(collectionType);
             ClassNode forLoopVariableType = forLoop.getVariableType();
+            ClassNode componentType;
+            if 
(Character_TYPE.equals(ClassHelper.getWrapper(forLoopVariableType)) && 
STRING_TYPE.equals(collectionType)) {
+                // we allow auto-coercion here
+                componentType = forLoopVariableType;
+            } else {
+                componentType = inferLoopElementType(collectionType);
+            }
             if (ClassHelper.getUnwrapper(componentType) == 
forLoopVariableType) {
                 // prefer primitive type over boxed type
                 componentType = forLoopVariableType;
@@ -1931,7 +1937,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                 componentType = MAP_ENTRY_TYPE.getPlainNodeReference();
                 componentType.setGenericsTypes(genericsTypes);
             } else if (STRING_TYPE.equals(collectionType)) {
-                componentType = ClassHelper.Character_TYPE;
+                componentType = ClassHelper.STRING_TYPE;
             } else if (ENUMERATION_TYPE.equals(collectionType)) {
                 // GROOVY-6123
                 ClassNode intf = 
GenericsUtils.parameterizeType(collectionType, ENUMERATION_TYPE);

http://git-wip-us.apache.org/repos/asf/groovy/blob/5d4a951b/src/test/groovy/transform/stc/LoopsSTCTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/transform/stc/LoopsSTCTest.groovy 
b/src/test/groovy/transform/stc/LoopsSTCTest.groovy
index cdb07ab..0bf2e1f 100644
--- a/src/test/groovy/transform/stc/LoopsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/LoopsSTCTest.groovy
@@ -18,6 +18,8 @@
  */
 package groovy.transform.stc
 
+import groovy.transform.CompileStatic
+
 /**
  * Unit tests for static type checking : loops.
  *
@@ -45,6 +47,22 @@ class LoopsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-8882
+    void testStringCollectionLoop() {
+        for (char c in 'abc') assert c instanceof Character
+        for (Character c in 'abc') assert c instanceof Character
+        for (String s in 'abc') assert s instanceof String
+        for (s in 'abc') assert s instanceof String
+    }
+
+    // GROOVY-8882
+    @CompileStatic
+    void testStringCollectionLoopCS() {
+        for (char c in 'abc') assert c instanceof Character
+        for (Character c in 'abc') assert c instanceof Character
+        for (String s in 'abc') assert s instanceof String
+        for (s in 'abc') assert s instanceof String
+    }
 
     void testMethodCallWithEachAndDefAndTwoFooMethods() {
         shouldFailWithMessages '''

Reply via email to