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/07/28 21:55:37 UTC
[groovy] branch master updated: GROOVY-8487: SC: for-in loop over iterator
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 09b5c7c3e4 GROOVY-8487: SC: for-in loop over iterator
09b5c7c3e4 is described below
commit 09b5c7c3e44b6d17cb4f8d2a5e74244e34f19646
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Jul 28 16:35:49 2022 -0500
GROOVY-8487: SC: for-in loop over iterator
---
.../asm/sc/StaticTypesStatementWriter.java | 36 ++++++++++++----------
.../groovy/runtime/DefaultGroovyMethods.java | 3 +-
src/test/groovy/transform/stc/LoopsSTCTest.groovy | 22 +++++++++++++
.../groovy/transform/stc/MethodCallsSTCTest.groovy | 11 -------
4 files changed, 44 insertions(+), 28 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
index 0e7db374a1..b05c90dffc 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
@@ -219,23 +219,27 @@ public class StaticTypesStatementWriter extends StatementWriter {
}
private void writeIteratorBasedForEachLoop(final ForStatement loop, final Expression collectionExpression, final ClassNode collectionType) {
- // GROOVY-10476: BaseStream provides an iterator() but does not implement Iterable
- MethodNode iterator = collectionType.getMethod("iterator", Parameter.EMPTY_ARRAY);
- if (iterator == null) {
- iterator = GeneralUtils.getInterfacesAndSuperInterfaces(collectionType).stream()
- .map(in -> in.getMethod("iterator", Parameter.EMPTY_ARRAY))
- .filter(Objects::nonNull).findFirst().orElse(null);
- }
- if (iterator != null && GeneralUtils.isOrImplements(iterator.getReturnType(), ClassHelper.Iterator_TYPE)) {
- MethodCallExpression call = GeneralUtils.callX(collectionExpression, "iterator");
- call.setImplicitThis(false);
- call.setMethodTarget(iterator);
- call.setSafe(true);//GROOVY-8643
- call.visit(controller.getAcg());
+ if (GeneralUtils.isOrImplements(collectionType, ClassHelper.Iterator_TYPE)) {
+ collectionExpression.visit(controller.getAcg()); // GROOVY-8487: iterator supplied
} else {
- collectionExpression.visit(controller.getAcg());
- controller.getMethodVisitor().visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "iterator", "(Ljava/lang/Object;)Ljava/util/Iterator;", false);
- controller.getOperandStack().replace(ClassHelper.Iterator_TYPE);
+ // GROOVY-10476: BaseStream provides an iterator() but does not implement Iterable
+ MethodNode iterator = collectionType.getMethod("iterator", Parameter.EMPTY_ARRAY);
+ if (iterator == null) {
+ iterator = GeneralUtils.getInterfacesAndSuperInterfaces(collectionType).stream()
+ .map(in -> in.getMethod("iterator", Parameter.EMPTY_ARRAY))
+ .filter(Objects::nonNull).findFirst().orElse(null);
+ }
+ if (iterator != null && GeneralUtils.isOrImplements(iterator.getReturnType(), ClassHelper.Iterator_TYPE)) {
+ MethodCallExpression call = GeneralUtils.callX(collectionExpression, "iterator");
+ call.setImplicitThis(false);
+ call.setMethodTarget(iterator);
+ call.setSafe(true);//GROOVY-8643
+ call.visit(controller.getAcg());
+ } else {
+ collectionExpression.visit(controller.getAcg());
+ controller.getMethodVisitor().visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "iterator", "(Ljava/lang/Object;)Ljava/util/Iterator;", false);
+ controller.getOperandStack().replace(ClassHelper.Iterator_TYPE);
+ }
}
writeForInLoopControlAndBlock(loop);
}
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 0133358fa3..f1b4bfb3de 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -18115,7 +18115,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @see org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation#asCollection(java.lang.Object)
* @since 1.0
*/
- public static Iterator iterator(Object o) {
+ public static Iterator iterator(final Object o) {
+ if (o instanceof Iterator) return (Iterator)o;
return DefaultTypeTransformation.asCollection(o).iterator();
}
diff --git a/src/test/groovy/transform/stc/LoopsSTCTest.groovy b/src/test/groovy/transform/stc/LoopsSTCTest.groovy
index 792466212c..ceab418ec3 100644
--- a/src/test/groovy/transform/stc/LoopsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/LoopsSTCTest.groovy
@@ -213,6 +213,17 @@ class LoopsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-10476
+ void testForInLoopOnStream() {
+ assertScript '''
+ def list = []
+ for (item in ['a','b','c'].stream()) {
+ list.add(item.toUpperCase())
+ }
+ assert list == ['A','B','C']
+ '''
+ }
+
// GROOVY-8882
void testForInLoopOnString() {
assertScript '''
@@ -225,6 +236,17 @@ class LoopsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-8487
+ void testForInLoopOnIterator() {
+ assertScript '''
+ def list = []
+ for (item in ['a','b','c'].iterator()) {
+ list.add(item)
+ }
+ assert list.join('') == 'abc'
+ '''
+ }
+
// GROOVY-6123
void testForInLoopOnEnumeration() {
assertScript '''
diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
index 78219b7644..dde7baa599 100644
--- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -1268,17 +1268,6 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
'Cannot call closure that accepts [java.lang.String, java.lang.String, java.lang.String] with '
}
- // GROOVY-10476
- void testForInLoop() {
- assertScript '''
- def list = []
- for (item in ['a','b','c'].stream()) {
- list.add(item.toUpperCase())
- }
- assert list == ['A', 'B', 'C']
- '''
- }
-
void testBoxingShouldCostMore() {
assertScript '''
int foo(int x) { 1 }