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/01 17:13:20 UTC

[groovy] branch GROOVY_4_0_X updated: sync with `master`

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new c3b5eaf0f3 sync with `master`
c3b5eaf0f3 is described below

commit c3b5eaf0f397ccae6e1391c9d14d6ddab62bcb94
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jul 1 11:59:16 2022 -0500

    sync with `master`
---
 .../ast/decompiled/AsmReferenceResolver.java       |  17 +-
 .../ast/decompiled/ClassSignatureParser.java       |  75 +++++----
 .../groovy/ast/decompiled/DecompiledClassNode.java | 184 ++++++++++-----------
 .../ast/decompiled/FormalParameterParser.java      |  38 +++--
 .../stc/ClosureParamTypeInferenceSTCTest.groovy    | 172 +++++++++++--------
 .../classgen/asm/BinaryOperationsTest.groovy       |  41 +++--
 6 files changed, 292 insertions(+), 235 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/AsmReferenceResolver.java b/src/main/java/org/codehaus/groovy/ast/decompiled/AsmReferenceResolver.java
index 64cf500630..70c35b30b7 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/AsmReferenceResolver.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/AsmReferenceResolver.java
@@ -35,12 +35,12 @@ public class AsmReferenceResolver {
     private final ClassNodeResolver resolver;
     private final CompilationUnit unit;
 
-    public AsmReferenceResolver(ClassNodeResolver resolver, CompilationUnit unit) {
+    public AsmReferenceResolver(final ClassNodeResolver resolver, final CompilationUnit unit) {
         this.resolver = resolver;
         this.unit = unit;
     }
 
-    public ClassNode resolveClass(String className) {
+    public ClassNode resolveClass(final String className) {
         ClassNode classNode = resolveClassNullable(className);
         if (classNode == null) {
             throw new NoClassDefFoundError(className);
@@ -48,20 +48,20 @@ public class AsmReferenceResolver {
         return classNode;
     }
 
-    public ClassNode resolveClassNullable(String className) {
+    public ClassNode resolveClassNullable(final String className) {
         ClassNode beingCompiled = unit.getAST().getClass(className);
         if (beingCompiled != null) {
             return beingCompiled;
         }
 
         ClassNodeResolver.LookupResult lookupResult = resolver.resolveName(className, unit);
-        return lookupResult == null ? null :lookupResult.getClassNode();
+        return lookupResult != null ? lookupResult.getClassNode() : null;
     }
 
-    public ClassNode resolveType(Type type) {
+    public ClassNode resolveType(final Type type) {
         if (type.getSort() == Type.ARRAY) {
             ClassNode result = resolveNonArrayType(type.getElementType());
-            for (int i = 0; i < type.getDimensions(); i++) {
+            for (int n = type.getDimensions(); n > 0; n -= 1) {
                 result = result.makeArray();
             }
             return result;
@@ -70,7 +70,7 @@ public class AsmReferenceResolver {
         return resolveNonArrayType(type);
     }
 
-    private ClassNode resolveNonArrayType(Type type) {
+    private ClassNode resolveNonArrayType(final Type type) {
         String className = type.getClassName();
         if (type.getSort() != Type.OBJECT) {
             return ClassHelper.make(className);
@@ -79,12 +79,11 @@ public class AsmReferenceResolver {
         return resolveClass(className);
     }
 
-    public Class resolveJvmClass(String name) {
+    public Class resolveJvmClass(final String name) {
         try {
             return unit.getClassLoader().loadClass(name, false, true);
         } catch (ClassNotFoundException e) {
             throw new GroovyBugError("JVM class can't be loaded for " + name, e);
         }
     }
-
 }
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/ClassSignatureParser.java b/src/main/java/org/codehaus/groovy/ast/decompiled/ClassSignatureParser.java
index ca7e090218..443a810dad 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/ClassSignatureParser.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/ClassSignatureParser.java
@@ -18,7 +18,6 @@
  */
 package org.codehaus.groovy.ast.decompiled;
 
-import org.apache.groovy.util.ObjectHolder;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.GenericsType;
 import org.codehaus.groovy.ast.RecordComponentNode;
@@ -31,81 +30,87 @@ import java.util.List;
 import java.util.stream.Collectors;
 
 class ClassSignatureParser {
-    static void configureClass(ClassNode classNode, ClassStub stub, AsmReferenceResolver resolver) {
+
+    static void configureClass(final ClassNode classNode, final ClassStub stub, final AsmReferenceResolver resolver) {
         if (stub.signature != null) {
             parseClassSignature(classNode, stub.signature, resolver);
             return;
         }
 
         if (stub.superName != null) {
-            classNode.setSuperClass(resolver.resolveClass(AsmDecompiler.fromInternalName(stub.superName)));
+            ClassNode sc = resolver.resolveClass(AsmDecompiler.fromInternalName(stub.superName));
+            classNode.setSuperClass(sc);
         }
 
-        ClassNode[] interfaces = new ClassNode[stub.interfaceNames.length];
-        for (int i = 0; i < stub.interfaceNames.length; i++) {
-            interfaces[i] = resolver.resolveClass(AsmDecompiler.fromInternalName(stub.interfaceNames[i]));
+        {
+            final int nInterfaces = stub.interfaceNames.length;
+            ClassNode[] interfaces = new ClassNode[nInterfaces];
+            for (int i = 0; i < nInterfaces; i += 1) { String name = stub.interfaceNames[i];
+                interfaces[i] = resolver.resolveClass(AsmDecompiler.fromInternalName(name));
+            }
+            classNode.setInterfaces(interfaces);
         }
-        classNode.setInterfaces(interfaces);
+
         if (!stub.permittedSubclasses.isEmpty()) {
-            List<ClassNode> permittedSubclasses = classNode.getPermittedSubclasses();
+            List<ClassNode> permitted = classNode.getPermittedSubclasses(); // collector
             for (String name : stub.permittedSubclasses) {
-                permittedSubclasses.add(resolver.resolveClass(AsmDecompiler.fromInternalName(name)));
+                ClassNode ps = resolver.resolveClass(AsmDecompiler.fromInternalName(name));
+                permitted.add(ps);
             }
         }
 
         if (!stub.recordComponents.isEmpty()) {
-            classNode.setRecordComponents(stub.recordComponents.stream().map(r -> {
-                ClassNode type = resolver.resolveType(Type.getType(r.descriptor));
-                ObjectHolder<ClassNode> typeHolder = new ObjectHolder<>(type);
-                if (null != r.signature) {
-                    new SignatureReader(r.signature).accept(new TypeSignatureParser(resolver) {
+            classNode.setRecordComponents(stub.recordComponents.stream().map(rc -> {
+                ClassNode[] type = {resolver.resolveType(Type.getType(rc.descriptor))};
+                if (rc.signature != null) {
+                    new SignatureReader(rc.signature).accept(new TypeSignatureParser(resolver) {
                         @Override
                         void finished(final ClassNode result) {
-                            typeHolder.setObject(applyErasure(result, typeHolder.getObject()));
+                            type[0] = applyErasure(result, type[0]);
                         }
                     });
                 }
-                ClassNode cn = typeHolder.getObject();
-                Annotations.addTypeAnnotations(r, cn, resolver);
-                RecordComponentNode recordComponentNode = new RecordComponentNode(classNode, r.name, cn);
-                Annotations.addAnnotations(r, recordComponentNode, resolver);
-                return recordComponentNode;
+                ClassNode rcType = type[0];
+                Annotations.addTypeAnnotations(rc, rcType, resolver);
+
+                RecordComponentNode recordComponent = new RecordComponentNode(classNode, rc.name, rcType);
+                Annotations.addAnnotations(rc, recordComponent, resolver);
+                return recordComponent;
             }).collect(Collectors.toList()));
         }
     }
 
-    private static void parseClassSignature(final ClassNode classNode, String signature, final AsmReferenceResolver resolver) {
-        final List<ClassNode> interfaces = new ArrayList<ClassNode>();
-        FormalParameterParser v = new FormalParameterParser(resolver) {
+    private static void parseClassSignature(final ClassNode classNode, final String signature, final AsmReferenceResolver resolver) {
+        List<ClassNode> interfaces = new ArrayList<>();
 
+        FormalParameterParser parser = new FormalParameterParser(resolver) {
             @Override
             public SignatureVisitor visitSuperclass() {
                 flushTypeParameter();
                 return new TypeSignatureParser(resolver) {
                     @Override
-                    void finished(ClassNode result) {
-                        classNode.setSuperClass(result);
+                    void finished(final ClassNode superClass) {
+                        classNode.setSuperClass(superClass);
                     }
                 };
             }
-
             @Override
             public SignatureVisitor visitInterface() {
                 flushTypeParameter();
                 return new TypeSignatureParser(resolver) {
                     @Override
-                    void finished(ClassNode result) {
-                        interfaces.add(result);
+                    void finished(final ClassNode superInterface) {
+                        interfaces.add(superInterface);
                     }
                 };
             }
-
         };
-        new SignatureReader(signature).accept(v);
-        GenericsType[] typeParameters = v.getTypeParameters();
-        if (typeParameters.length > 0) {
-            classNode.setGenericsTypes(typeParameters);
-        }
-        classNode.setInterfaces(interfaces.toArray(ClassNode.EMPTY_ARRAY));
+        new SignatureReader(signature).accept(parser);
+
+        classNode.setInterfaces(interfaces.isEmpty() ? ClassNode.EMPTY_ARRAY :
+                                    interfaces.toArray(ClassNode.EMPTY_ARRAY));
+
+        GenericsType[] typeParameters = parser.getTypeParameters();
+        if (typeParameters.length > 0) classNode.setGenericsTypes(typeParameters);
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/DecompiledClassNode.java b/src/main/java/org/codehaus/groovy/ast/decompiled/DecompiledClassNode.java
index a803be6915..52d32dc677 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/DecompiledClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/DecompiledClassNode.java
@@ -40,13 +40,12 @@ import java.util.function.Supplier;
  * @see AsmDecompiler
  */
 public class DecompiledClassNode extends ClassNode {
+
     private final ClassStub classData;
     private final AsmReferenceResolver resolver;
-    private volatile boolean supersInitialized;
-    private volatile boolean membersInitialized;
 
     public DecompiledClassNode(final ClassStub classData, final AsmReferenceResolver resolver) {
-        super(classData.className, getFullModifiers(classData), null, null, MixinNode.EMPTY_ARRAY);
+        super(classData.className, getModifiers(classData), null, null, MixinNode.EMPTY_ARRAY);
         this.classData = classData;
         this.resolver = resolver;
         isPrimaryNode = false;
@@ -57,11 +56,12 @@ public class DecompiledClassNode extends ClassNode {
      * the INNERCLASS reference since the top-level modifiers for inner classes
      * wont include static or private/protected.
      */
-    private static int getFullModifiers(ClassStub data) {
-        return (data.innerClassModifiers == -1)
-                ? data.accessModifiers : data.innerClassModifiers;
+    private static int getModifiers(ClassStub classData) {
+        return (classData.innerClassModifiers != -1 ? classData.innerClassModifiers : classData.accessModifiers);
     }
 
+    //
+
     public long getCompilationTimeStamp() {
         if (classData.fields != null) {
             for (FieldStub field : classData.fields) {
@@ -77,64 +77,59 @@ public class DecompiledClassNode extends ClassNode {
     }
 
     @Override
-    public GenericsType[] getGenericsTypes() {
-        lazyInitSupers();
-        return super.getGenericsTypes();
-    }
-
-    @Override
-    public boolean isUsingGenerics() {
-        lazyInitSupers();
-        return super.isUsingGenerics();
+    public Class getTypeClass() {
+        return resolver.resolveJvmClass(getName());
     }
 
-    @Override
-    public List<FieldNode> getFields() {
-        lazyInitMembers();
-        return super.getFields();
+    public boolean isParameterized() {
+        return (classData.signature != null && classData.signature.charAt(0) == '<');
     }
 
     @Override
-    public ClassNode[] getInterfaces() {
-        lazyInitSupers();
-        return super.getInterfaces();
+    public boolean isResolved() {
+        return true;
     }
 
     @Override
-    public List<MethodNode> getMethods() {
-        lazyInitMembers();
-        return super.getMethods();
+    public boolean isSealed() {
+        // check Groovy "sealed"
+        List<AnnotationStub> annotations = classData.annotations;
+        if (annotations != null) {
+            for (AnnotationStub stub : annotations) {
+                if (stub.className.equals("groovy.transform.Sealed")) {
+                    return true;
+                }
+            }
+        }
+        // check Java "sealed"
+        try {
+            return ReflectionUtils.isSealed(getTypeClass());
+        } catch (NoClassDefFoundError ignored) {
+        }
+        return false;
     }
 
     @Override
-    public List<ConstructorNode> getDeclaredConstructors() {
-        lazyInitMembers();
-        return super.getDeclaredConstructors();
+    public String setName(String name) {
+        throw new UnsupportedOperationException();
     }
 
     @Override
-    public FieldNode getDeclaredField(String name) {
-        lazyInitMembers();
-        return super.getDeclaredField(name);
+    public void setRedirect(ClassNode cn) {
+        throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<MethodNode> getDeclaredMethods(String name) {
-        lazyInitMembers();
-        return super.getDeclaredMethods(name);
+    public void setUsingGenerics(boolean b) {
+        throw new UnsupportedOperationException();
     }
 
     @Override
-    public ClassNode getUnresolvedSuperClass(boolean useRedirect) {
-        lazyInitSupers();
-        return super.getUnresolvedSuperClass(useRedirect);
+    public void setGenericsPlaceHolder(boolean b) {
+        throw new UnsupportedOperationException();
     }
 
-    @Override
-    public ClassNode[] getUnresolvedInterfaces(boolean useRedirect) {
-        lazyInitSupers();
-        return super.getUnresolvedInterfaces(useRedirect);
-    }
+    //--------------------------------------------------------------------------
 
     @Override
     public List<AnnotationNode> getAnnotations() {
@@ -149,70 +144,42 @@ public class DecompiledClassNode extends ClassNode {
     }
 
     @Override
-    public void setRedirect(ClassNode cn) {
-        throw new UnsupportedOperationException();
+    public GenericsType[] getGenericsTypes() {
+        lazyInitSupers();
+        return super.getGenericsTypes();
     }
 
     @Override
-    public void setGenericsPlaceHolder(boolean b) {
-        throw new UnsupportedOperationException();
+    public ClassNode[] getInterfaces() {
+        lazyInitSupers();
+        return super.getInterfaces();
     }
 
     @Override
-    public void setUsingGenerics(boolean b) {
-        throw new UnsupportedOperationException();
+    public List<RecordComponentNode> getRecordComponents() {
+        lazyInitSupers();
+        return super.getRecordComponents();
     }
 
     @Override
-    public String setName(String name) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isParameterized() {
-        return (classData.signature != null && classData.signature.charAt(0) == '<');
+    public ClassNode[] getUnresolvedInterfaces(boolean useRedirect) {
+        lazyInitSupers();
+        return super.getUnresolvedInterfaces(useRedirect);
     }
 
     @Override
-    public boolean isResolved() {
-        return true;
+    public ClassNode getUnresolvedSuperClass(boolean useRedirect) {
+        lazyInitSupers();
+        return super.getUnresolvedSuperClass(useRedirect);
     }
 
     @Override
-    public boolean isSealed() {
-        List<AnnotationStub> annotations = classData.annotations;
-        if (annotations != null) {
-            for (AnnotationStub stub : annotations) {
-                if (stub.className.equals("groovy.transform.Sealed")) {
-                    return true;
-                }
-            }
-        }
-        return isSealedSafe();
-    }
-
-    private boolean isSealedSafe() {
-        try {
-            return ReflectionUtils.isSealed(getTypeClass());
-        } catch (NoClassDefFoundError ignored) {
-        }
-        return false;
-    }
-
-    /**
-     * Get the record components of record types
-     *
-     * @return {@code RecordComponentNode} instances
-     * @since 4.0.0
-     */
-    public List<RecordComponentNode> getRecordComponents() {
+    public boolean isUsingGenerics() {
         lazyInitSupers();
-        return super.getRecordComponents();
+        return super.isUsingGenerics();
     }
 
-    @Override
-    public Class getTypeClass() {
-        return resolver.resolveJvmClass(getName());
-    }
+    private volatile boolean supersInitialized;
 
     private void lazyInitSupers() {
         if (supersInitialized) return;
@@ -226,6 +193,40 @@ public class DecompiledClassNode extends ClassNode {
         }
     }
 
+    //--------------------------------------------------------------------------
+
+    @Override
+    public List<ConstructorNode> getDeclaredConstructors() {
+        lazyInitMembers();
+        return super.getDeclaredConstructors();
+    }
+
+    @Override
+    public FieldNode getDeclaredField(final String name) {
+        lazyInitMembers();
+        return super.getDeclaredField(name);
+    }
+
+    @Override
+    public List<MethodNode> getDeclaredMethods(final String name) {
+        lazyInitMembers();
+        return super.getDeclaredMethods(name);
+    }
+
+    @Override
+    public List<FieldNode> getFields() {
+        lazyInitMembers();
+        return super.getFields();
+    }
+
+    @Override
+    public List<MethodNode> getMethods() {
+        lazyInitMembers();
+        return super.getMethods();
+    }
+
+    private volatile boolean membersInitialized;
+
     private void lazyInitMembers() {
         if (membersInitialized) return;
 
@@ -233,7 +234,7 @@ public class DecompiledClassNode extends ClassNode {
             if (!membersInitialized) {
                 if (classData.methods != null) {
                     for (MethodStub method : classData.methods) {
-                        if (isConstructor(method)) {
+                        if ("<init>".equals(method.methodName)) {
                             addConstructor(createConstructor(method));
                         } else {
                             addMethod(createMethodNode(method));
@@ -281,9 +282,4 @@ public class DecompiledClassNode extends ClassNode {
 
         return constructorNodeSupplier.get();
     }
-
-    private boolean isConstructor(MethodStub method) {
-        return "<init>".equals(method.methodName);
-    }
-
 }
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/FormalParameterParser.java b/src/main/java/org/codehaus/groovy/ast/decompiled/FormalParameterParser.java
index 2e7b1ebf0b..55de8532cb 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/FormalParameterParser.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/FormalParameterParser.java
@@ -29,33 +29,40 @@ import java.util.List;
 import static org.codehaus.groovy.control.CompilerConfiguration.ASM_API_VERSION;
 
 abstract class FormalParameterParser extends SignatureVisitor {
-    private final AsmReferenceResolver resolver;
+
     private String currentTypeParameter;
-    private final List<ClassNode> parameterBounds = new ArrayList<ClassNode>();
-    private final List<GenericsType> typeParameters = new ArrayList<GenericsType>();
+    private final List<ClassNode> parameterBounds = new ArrayList<>();
+    private final List<GenericsType> typeParameters = new ArrayList<>();
+
+    private final AsmReferenceResolver resolver;
 
-    public FormalParameterParser(AsmReferenceResolver resolver) {
+    public FormalParameterParser(final AsmReferenceResolver resolver) {
         super(ASM_API_VERSION);
         this.resolver = resolver;
     }
 
-    @Override
-    public void visitFormalTypeParameter(String name) {
-        flushTypeParameter();
-        currentTypeParameter = name;
-    }
-
     protected void flushTypeParameter() {
         if (currentTypeParameter != null) {
             ClassNode ref = Java8.configureTypeVariableReference(currentTypeParameter);
-            ClassNode[] boundNodes = parameterBounds.toArray(ClassNode.EMPTY_ARRAY);
-            typeParameters.add(Java8.configureTypeVariableDefinition(ref, boundNodes));
+            ClassNode[] theBoundTypes = parameterBounds.toArray(ClassNode.EMPTY_ARRAY);
+            typeParameters.add(Java8.configureTypeVariableDefinition(ref, theBoundTypes));
 
-            currentTypeParameter = null;
             parameterBounds.clear();
+            currentTypeParameter = null;
         }
     }
 
+    public GenericsType[] getTypeParameters() {
+        flushTypeParameter();
+        return typeParameters.toArray(GenericsType.EMPTY_ARRAY);
+    }
+
+    @Override
+    public void visitFormalTypeParameter(final String name) {
+        flushTypeParameter();
+        currentTypeParameter = name;
+    }
+
     @Override
     public SignatureVisitor visitClassBound() {
         return new TypeSignatureParser(resolver) {
@@ -70,9 +77,4 @@ abstract class FormalParameterParser extends SignatureVisitor {
     public SignatureVisitor visitInterfaceBound() {
         return visitClassBound();
     }
-
-    public GenericsType[] getTypeParameters() {
-        flushTypeParameter();
-        return typeParameters.toArray(GenericsType.EMPTY_ARRAY);
-    }
 }
diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
index 88a1e27744..8a74e3d12a 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -582,30 +582,30 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
 
     void testInferenceForDGM_dropWhileOnIterable() {
         assertScript '''
-        assert (0..10).dropWhile { it<5 } == (5..10)
-        assert (0..10).dropWhile { int i -> i<5 } == (5..10)
+            assert (0..10).dropWhile { it<5 } == (5..10)
+            assert (0..10).dropWhile { int i -> i<5 } == (5..10)
         '''
     }
 
     void testInferenceForDGM_dropWhileOnList() {
         assertScript '''
-        assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { it<5 } == [5,6,7,8,9,10]
-        assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { int i -> i<5 } == [5,6,7,8,9,10]
+            assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { it<5 } == [5,6,7,8,9,10]
+            assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { int i -> i<5 } == [5,6,7,8,9,10]
         '''
     }
 
     void testInferenceForDGM_dropWhileOnIterator() {
         assertScript '''
-        assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
-        assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
+            assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
+            assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
         '''
     }
 
     void testInferenceForDGM_dropWhileOnArray() {
         assertScript '''
-        Integer[] array = [0,1,2,3,4,5,6,7,8,9,10]
-        assert array.iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
-        assert array.iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
+            Integer[] array = [0,1,2,3,4,5,6,7,8,9,10]
+            assert array.iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
+            assert array.iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
         '''
     }
 
@@ -640,13 +640,15 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
     }
     @NotYetImplemented
     void testInferenceForDGM_eachWithIndexOnRecursiveIterable() { // GROOVY-10651
-        assertScript '''
-            void proc(groovy.transform.stc.TreeNode node) {
-                node.eachWithIndex { child, index ->
-                    proc(child) // recurse
+        ['', '<?>'].each { args ->
+            assertScript """
+                void proc(groovy.transform.stc.TreeNode$args node) {
+                    node.eachWithIndex { child, index ->
+                        proc(child) // recurse
+                    }
                 }
-            }
-        '''
+            """
+        }
     }
 
     void testInferenceForDGM_everyOnIterable() {
@@ -1052,18 +1054,16 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
 
     void testDGM_sortOnMap() {
         assertScript '''
-        def map = [a:5, b:3, c:6, d:4].sort { a, b -> a.value <=> b.value }
-        assert map == [b:3, d:4, a:5, c:6]
+            def map = [a:5, b:3, c:6, d:4].sort { a, b -> a.value <=> b.value }
+            assert map == [b:3, d:4, a:5, c:6]
         '''
-
         assertScript '''
-        def map = [a:5, b:3, c:6, d:4].sort { a -> a.value }
-        assert map == [b:3, d:4, a:5, c:6]
+            def map = [a:5, b:3, c:6, d:4].sort { a -> a.value }
+            assert map == [b:3, d:4, a:5, c:6]
         '''
-
         assertScript '''
-        def map = [a:5, b:3, c:6, d:4].sort { it.value }
-        assert map == [b:3, d:4, a:5, c:6]
+            def map = [a:5, b:3, c:6, d:4].sort { it.value }
+            assert map == [b:3, d:4, a:5, c:6]
         '''
     }
 
@@ -1075,42 +1075,45 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
 
     void testDGM_takeWhileOnIterable() {
         assertScript '''
-        class AbcIterable implements Iterable<String>  {
-           Iterator<String>  iterator() { "abc".iterator() }
-       }
-       def abc = new AbcIterable()
-       assert abc.takeWhile{ it < 'b' } == ['a']
-       assert abc.takeWhile{ it <= 'b' } == ['a', 'b']
-'''
+            class AbcIterable implements Iterable<String>  {
+                Iterator<String>  iterator() { "abc".iterator() }
+            }
+            def abc = new AbcIterable()
+            assert abc.takeWhile{ it < 'b' } == ['a']
+            assert abc.takeWhile{ it <= 'b' } == ['a', 'b']
+        '''
     }
     void testDGM_takeWhileOnIterator() {
         assertScript '''
-        class AbcIterable implements Iterable<String>  {
-           Iterator<String>  iterator() { "abc".iterator() }
-       }
-       def abc = new AbcIterable()
-       assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
-       assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
-'''
+            class AbcIterable implements Iterable<String>  {
+                Iterator<String>  iterator() { "abc".iterator() }
+            }
+            def abc = new AbcIterable()
+            assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
+            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+        '''
     }
     void testDGM_takeWhileOnList() {
         assertScript '''
-       def abc = ['a','b','c']
-       assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
-       assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']'''
+            def abc = ['a','b','c']
+            assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
+            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+        '''
     }
     void testDGM_takeWhileOnArray() {
         assertScript '''
             String[] abc = ['a','b','c']
             assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
-            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']'''
+            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+        '''
     }
     void testDGM_takeWhileOnMap() {
         assertScript '''
             def shopping = [milk:1, bread:2, chocolate:3]
             assert shopping.takeWhile{ it.key.size() < 6 } == [milk:1, bread:2]
             assert shopping.takeWhile{ it.value % 2 } == [milk:1]
-            assert shopping.takeWhile{ k, v -> k.size() + v <= 7 } == [milk:1, bread:2]'''
+            assert shopping.takeWhile{ k, v -> k.size() + v <= 7 } == [milk:1, bread:2]
+        '''
     }
 
     void testDGM_times() {
@@ -1124,35 +1127,41 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
 
     void testDGM_unique() {
         assertScript '''
-       def orig = [1, 3, 4, 5]
-       def uniq = orig.unique(false) { it % 2 }
-       assert orig == [1, 3, 4, 5]
-       assert uniq == [1, 4]'''
-
-       assertScript '''def orig = [2, 3, 3, 4]
-       def uniq = orig.unique(false) { a, b -> a <=> b }
-       assert orig == [2, 3, 3, 4]
-       assert uniq == [2, 3, 4]'''
+            def orig = [1, 3, 4, 5]
+            def uniq = orig.unique(false) { it % 2 }
+            assert orig == [1, 3, 4, 5]
+            assert uniq == [1, 4]
+        '''
+        assertScript '''
+            def orig = [2, 3, 3, 4]
+            def uniq = orig.unique(false) { a, b -> a <=> b }
+            assert orig == [2, 3, 3, 4]
+            assert uniq == [2, 3, 4]
+        '''
     }
     void testDGM_uniqueOnCollection() {
         assertScript '''
-       def orig = [1, 3, 4, 5]
-       def uniq = orig.unique { it % 2 }
-       assert uniq == [1, 4]'''
-
-       assertScript '''def orig = [2, 3, 3, 4]
-       def uniq = orig.unique { a, b -> a <=> b }
-       assert uniq == [2, 3, 4]'''
+            def orig = [1, 3, 4, 5]
+            def uniq = orig.unique { it % 2 }
+            assert uniq == [1, 4]
+        '''
+        assertScript '''
+            def orig = [2, 3, 3, 4]
+            def uniq = orig.unique { a, b -> a <=> b }
+            assert uniq == [2, 3, 4]
+        '''
     }
     void testDGM_uniqueOnIterator() {
         assertScript '''
-       def orig = [1, 3, 4, 5].iterator()
-       def uniq = orig.unique { it % 2 }.collect()
-       assert uniq == [1, 4]'''
-
-       assertScript '''def orig = [2, 3, 3, 4].iterator()
-       def uniq = orig.unique { a, b -> a <=> b }.collect()
-       assert uniq == [2, 3, 4]'''
+            def orig = [1, 3, 4, 5].iterator()
+            def uniq = orig.unique { it % 2 }.collect()
+            assert uniq == [1, 4]
+        '''
+        assertScript '''
+            def orig = [2, 3, 3, 4].iterator()
+            def uniq = orig.unique { a, b -> a <=> b }.collect()
+            assert uniq == [2, 3, 4]
+        '''
     }
 
     void testDGM_anyOnMap() {
@@ -1232,6 +1241,21 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    @NotYetImplemented
+    void testGroovy6022() {
+        assertScript '''import groovy.transform.stc.SimpleType
+            class Item {
+                int x
+            }
+
+            void m(Item item, @ClosureParams(value=SimpleType, options="Item") Closure... closures) {
+                closures*.call(item)
+            }
+
+            m(new Item(), { item -> item.x }, { it.x })
+        '''
+    }
+
     void testGroovy6602() {
         shouldFailWithMessages '''import groovy.transform.stc.SimpleType
             void foo(@ClosureParams(value=SimpleType, options="java.lang.Number") Closure c) {
@@ -1511,4 +1535,22 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
             m((text, item) -> { })
         '''
     }
+
+    void testGroovy10673() {
+        assertScript '''import java.util.function.Consumer
+
+            void proc(Consumer<Number> action) {
+                action.accept(1.2345)
+            }
+
+            int i = 0
+            proc { n ->
+                def c = {
+                    i = n.intValue()
+                }
+                c()
+            }
+            assert i == 1
+        '''
+    }
 }
diff --git a/src/test/org/codehaus/groovy/classgen/asm/BinaryOperationsTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/BinaryOperationsTest.groovy
index a7ce4820f7..6255532e6f 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/BinaryOperationsTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/BinaryOperationsTest.groovy
@@ -104,32 +104,45 @@ class BinaryOperationsTest extends AbstractBytecodeTestCase {
 
     void testCharXor() {
         if (config.indyEnabled) return;
-        assert compile("""
-            int i = ('a' as char) ^ ('b' as char) 
-        """).hasStrictSequence ([
-            "IXOR"
+        assert compile('''
+            int i = ('a' as char) ^ ('b' as char)
+        ''').hasStrictSequence ([
+            'IXOR'
         ])
     }
 
+    // GROOVY-10657
+    void testPutAtValue() {
+        def sequence = compile '''
+            class C {
+                void putAt(String key, Object value) {
+                }
+            }
+
+            def obj = new C()
+            obj['key'] = 'xx'
+        '''
+    }
+
     void testPrimitiveOrAssign() {
         ['byte','int','short','long'].each { type ->
             assertScript """
-            $type[] b = new $type[1]
-            b[0] = 16
-            b[0] |= 2
-            assert b[0] == 18:"Failure for type $type"
+                $type[] array = new $type[1]
+                array[0] = 16
+                array[0] |= 2
+                assert array[0] == 18 : "Failure for type $type"
             """
-            }
+        }
     }
 
     void testPrimitiveAndAssign() {
         ['byte','int','short','long'].each { type ->
             assertScript """
-            $type[] b = new $type[1]
-            b[0] = 18
-            b[0] &= 2
-            assert b[0] == 2:"Failure for type $type"
+                $type[] array = new $type[1]
+                array[0] = 18
+                array[0] &= 2
+                assert array[0] == 2 : "Failure for type $type"
             """
-            }
+        }
     }
 }