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'
+ ]
+ }
+ }
}