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 2022/02/01 17:55:52 UTC
[groovy] 09/11: GROOVY-10179: STC: for-in collection type: consider instanceof flow-type
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit b47886f3bb40db4698ba25d202c0d3180d56792f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jul 23 14:24:04 2021 -0500
GROOVY-10179: STC: for-in collection type: consider instanceof flow-type
Conflicts:
src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
---
.../transform/stc/StaticTypeCheckingVisitor.java | 7 ++-
src/test/groovy/transform/stc/LoopsSTCTest.groovy | 66 ++++++++++++++++++++-
.../classgen/asm/sc/bugs/Groovy6240Bug.groovy | 69 ----------------------
3 files changed, 69 insertions(+), 73 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 6fdcef8..013aea9 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1901,7 +1901,12 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
super.visitForLoop(forLoop);
} else {
collectionExpression.visit(this);
- final ClassNode collectionType = getType(collectionExpression);
+ ClassNode collectionType;
+ if (collectionExpression instanceof VariableExpression && hasInferredReturnType(collectionExpression)) {
+ collectionType = getInferredReturnType(collectionExpression);
+ } else {
+ collectionType = getType(collectionExpression);
+ }
ClassNode forLoopVariableType = forLoop.getVariableType();
ClassNode componentType;
if (Character_TYPE.equals(ClassHelper.getWrapper(forLoopVariableType)) && STRING_TYPE.equals(collectionType)) {
diff --git a/src/test/groovy/transform/stc/LoopsSTCTest.groovy b/src/test/groovy/transform/stc/LoopsSTCTest.groovy
index 6a9bff6..2798cfb 100644
--- a/src/test/groovy/transform/stc/LoopsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/LoopsSTCTest.groovy
@@ -128,9 +128,9 @@ class LoopsSTCTest extends StaticTypeCheckingTestCase {
}
// GROOVY-5587
- void testMapEntryInForInLoop() {
+ void testForInLoopOnMap1() {
assertScript '''
- @ASTTest(phase=INSTRUCTION_SELECTION, value= {
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
lookup('forLoop').each {
assert it instanceof org.codehaus.groovy.ast.stmt.ForStatement
def collection = it.collectionExpression // MethodCallExpression
@@ -157,6 +157,67 @@ class LoopsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-6240
+ void testForInLoopOnMap2() {
+ assertScript '''
+ Map<String, Integer> map = [foo: 123, bar: 456]
+ for (entry in map) {
+ assert entry.key.reverse() in ['oof','rab']
+ assert entry.value * 2 in [246, 912]
+ }
+ '''
+ }
+
+ void testForInLoopOnMap3() {
+ assertScript '''
+ class MyMap extends LinkedHashMap<String,Integer> {
+ }
+ def map = new MyMap([foo: 123, bar: 456])
+ for (entry in map) {
+ assert entry.key.reverse() in ['oof','rab']
+ assert entry.value * 2 in [246, 912]
+ }
+ '''
+ }
+
+ // GROOVY-10179
+ void testForInLoopOnMap4() {
+ assertScript '''
+ void test(args) {
+ if (args instanceof Map) {
+ for (e in args) {
+ print "$e.key $e.value"
+ }
+ }
+ }
+ test(a:1,b:2,c:3.14)
+ '''
+ }
+
+ // GROOVY-6123
+ void testForInLoopOnEnumeration() {
+ assertScript '''
+ Vector<String> v = new Vector<>()
+ v.add('ooo')
+ def en = v.elements()
+ for (e in en) {
+ assert e.toUpperCase() == 'OOO'
+ }
+ v.add('groovy')
+ en = v.elements()
+ for (e in en) {
+ assert e.toUpperCase() == 'OOO'
+ break
+ }
+
+ en = v.elements()
+ for (e in en) {
+ assert e.toUpperCase() in ['OOO','GROOVY']
+ if (e=='ooo') continue
+ }
+ '''
+ }
+
void testShouldNotInferSoftReferenceAsComponentType() {
assertScript '''import java.lang.reflect.Field
import org.codehaus.groovy.ast.stmt.ForStatement
@@ -233,4 +294,3 @@ class LoopsSTCTest extends StaticTypeCheckingTestCase {
'''
}
}
-
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6240Bug.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6240Bug.groovy
deleted file mode 100644
index f263a44..0000000
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6240Bug.groovy
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.codehaus.groovy.classgen.asm.sc.bugs
-
-import groovy.transform.stc.StaticTypeCheckingTestCase
-import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
-
-class Groovy6240Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
- void testGroovyAllowsIteratingOnMapDirectlyWithForEachLoop() {
- assertScript '''
- Map<String, Integer> map = [foo: 123, bar: 456]
- for (entry in map) {
- assert entry.key.reverse() in ['oof','rab']
- assert entry.value * 2 in [246, 912]
- }
- '''
- }
-
- void testGroovyAllowsIteratingOnMapDirectlyWithForEachLoopCustomMapType() {
- assertScript '''
- class MyMap extends LinkedHashMap<String,Integer>{}
- def map = new MyMap([foo: 123, bar: 456])
- for (entry in map) {
- assert entry.key.reverse() in ['oof','rab']
- assert entry.value * 2 in [246, 912]
- }
- '''
- }
-
- // GROOVY-6123
- void testGroovyAllowsIteratingOnEnumerationDirectlyWithForEachLoop() {
- assertScript '''
- Vector<String> v = new Vector<>()
- v.add('ooo')
- def en = v.elements()
- for (e in en) {
- assert e.toUpperCase() == 'OOO'
- }
- v.add('groovy')
- en = v.elements()
- for (e in en) {
- assert e.toUpperCase() == 'OOO'
- break
- }
-
- en = v.elements()
- for (e in en) {
- assert e.toUpperCase() in ['OOO','GROOVY']
- if (e=='ooo') continue
- }
- '''
- }
-}