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

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


The following commit(s) were added to refs/heads/GROOVY_5_0_X by this push:
     new d36b199909 GROOVY-10687, GROOVY-11780: fix nest members for 
multi-level closures
d36b199909 is described below

commit d36b1999096f9d34464843a5294e6dee80f5fe29
Author: Eric Milles <[email protected]>
AuthorDate: Fri Oct 10 22:27:13 2025 -0500

    GROOVY-10687, GROOVY-11780: fix nest members for multi-level closures
---
 .../groovy/classgen/AsmClassGenerator.java         | 26 +++++++++----
 .../groovy/classgen/asm/NestHostTests.groovy       | 43 ++++++++++++++++++++++
 2 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java 
b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index c453f4dda7..4d31451a6b 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -473,15 +473,13 @@ public class AsmClassGenerator extends ClassGenerator {
         int[] n = {this.context.getClosureClassIndex()};
         for (ClassNode innerClass : getInnerClasses()) {
             if (innerClass instanceof InterfaceHelperClassNode) continue;
-            var doCall = innerClass.getMethods().get(0);
-            doCall.getCode().visit(new CodeVisitorSupport() {
+            var toVisit = new TreeMap<String, ClosureExpression>(); // 
GROOVY-11780
+            var visitor = new CodeVisitorSupport() {
                 private String name = 
BytecodeHelper.getClassInternalName(innerClass);
                 private void visitNested(final String kind, final 
ClosureExpression expr) {
-                    String save = name;
-                    name += "$_" + kind + n[0]++;
-                    classVisitor.visitNestMember(name);
-                    super.visitClosureExpression(expr);
-                    name = save;
+                    String nest = name + "$_" + kind + n[0]++;
+                    classVisitor.visitNestMember(nest);
+                    toVisit.put(nest, expr);
                 }
                 @Override
                 public  void visitClosureExpression(final ClosureExpression 
expression) {
@@ -496,7 +494,19 @@ public class AsmClassGenerator extends ClassGenerator {
                         super.visitLambdaExpression(expression);
                     }
                 }
-            });
+            };
+
+            MethodNode doCall = innerClass.getMethods().get(0);
+            doCall.getCode().visit(visitor);
+
+            while (!toVisit.isEmpty()) {
+                var iter = toVisit.entrySet().iterator(); // take first entry
+                var next = iter.next();
+                iter.remove();
+
+                visitor.name = next.getKey(); // traverse
+                next.getValue().getCode().visit(visitor);
+            }
         }
     }
 
diff --git 
a/src/test/groovy/org/codehaus/groovy/classgen/asm/NestHostTests.groovy 
b/src/test/groovy/org/codehaus/groovy/classgen/asm/NestHostTests.groovy
index 07ee8ea33f..797f6e950c 100644
--- a/src/test/groovy/org/codehaus/groovy/classgen/asm/NestHostTests.groovy
+++ b/src/test/groovy/org/codehaus/groovy/classgen/asm/NestHostTests.groovy
@@ -134,4 +134,47 @@ final class NestHostTests {
             assert type.nestMembers*.name.sort() == ['C', 'C$_closure1', 
'C$_closure1$_closure2', 'C$_closure1$_closure2$_lambda3']
         }
     }
+
+    // GROOVY-11780
+    @Test
+    void testNestHost7() {
+        def types = compileScript '''
+            class C {
+                def aaa() {
+                    { ->
+                        { ->
+                            { ->
+                                { ->
+                                }
+                            }
+                        }
+                        { ->
+                            { ->
+                            }
+                        }
+                    }
+                    { ->
+                        { ->
+                        }
+                    }
+                }
+                def bbb() {
+                    { ->
+                        { ->
+                        }
+                    }
+                }
+            }
+        '''
+
+        types.each { type ->
+            assert type.nestHost.name == 'C'
+            assert type.nestMembers*.name.sort() == ['C',
+                'C$_aaa_closure1', 'C$_aaa_closure1$_closure4', 
'C$_aaa_closure1$_closure4$_closure6', 
'C$_aaa_closure1$_closure4$_closure6$_closure7',
+                                   'C$_aaa_closure1$_closure5', 
'C$_aaa_closure1$_closure5$_closure8',
+                'C$_aaa_closure2', 'C$_aaa_closure2$_closure9',
+                'C$_bbb_closure3', 'C$_bbb_closure3$_closure10'
+            ]
+        }
+    }
 }

Reply via email to