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 3015f5e5cc GROOVY-11854: enclosing method is `run()` for anon. inner 
in a script
3015f5e5cc is described below

commit 3015f5e5cc7b2e27ed581ccfa7a88b23ba03c83c
Author: Eric Milles <[email protected]>
AuthorDate: Wed Feb 4 11:15:30 2026 -0600

    GROOVY-11854: enclosing method is `run()` for anon. inner in a script
---
 .../java/org/codehaus/groovy/ast/ModuleNode.java   |  12 +
 .../groovy/classgen/AsmClassGenerator.java         |   8 +-
 src/test/groovy/bugs/Groovy10840.groovy            |  39 ++
 src/test/groovy/bugs/Groovy7785.groovy             |   5 -
 src/test/groovy/bugs/Groovy7938Bug.groovy          |  70 ----
 .../groovy/gls/innerClass/InnerClassTest.groovy    | 450 +++++++++++++++------
 src/test/groovy/groovy/ClosureTest.groovy          |  69 +---
 src/test/groovy/groovy/PropertyTest.groovy         |  18 -
 8 files changed, 392 insertions(+), 279 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/ModuleNode.java 
b/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
index 8c7edf3bf2..576d1dabc9 100644
--- a/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.ast;
 
 import org.apache.groovy.ast.tools.ClassNodeUtils;
+import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
 import org.codehaus.groovy.ast.expr.DeclarationExpression;
 import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.expr.ListExpression;
@@ -454,6 +455,17 @@ public class ModuleNode extends ASTNode {
                 methodNode.addAnnotations(existingMain.getAnnotations());
             }
             ClassNodeUtils.addGeneratedMethod(classNode, methodNode, true);
+
+            new CodeVisitorSupport() {
+                @Override
+                public void visitConstructorCallExpression(final 
ConstructorCallExpression cce) {
+                    if (cce.isUsingAnonymousInnerClass()) { // GROOVY-11854
+                        cce.getType().setEnclosingMethod(methodNode);
+                    }
+                    super.visitConstructorCallExpression(cce);
+                }
+            }
+            .visit(statementBlock);
         } else {
             fields.forEach(classNode::addField);
             classNode.addAnnotations(existingRun.getAnnotations());
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java 
b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 8f2b726614..a724628667 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -345,7 +345,7 @@ public class AsmClassGenerator extends ClassGenerator {
                 MethodNode enclosingMethod = classNode.getEnclosingMethod();
                 if (enclosingMethod != null) {
                     classVisitor.visitOuterClass(
-                            
BytecodeHelper.getClassInternalName(classNode.getOuterClass()),
+                            
BytecodeHelper.getClassInternalName(enclosingMethod.getDeclaringClass()),
                             enclosingMethod.getName(), 
BytecodeHelper.getMethodDescriptor(enclosingMethod));
                 }
             }
@@ -441,9 +441,6 @@ public class AsmClassGenerator extends ClassGenerator {
     }
 
     private void makeInnerClassEntry(final ClassNode innerClass) {
-        ClassNode outerClass = innerClass.getOuterClass();
-        maybeInnerClassEntry(outerClass); // GROOVY-9842
-
         String innerClassName = innerClass.getName();
         String innerClassInternalName = 
BytecodeHelper.getClassInternalName(innerClassName);
         {
@@ -452,7 +449,8 @@ public class AsmClassGenerator extends ClassGenerator {
         }
         String outerClassInternalName;
         if (innerClass.getEnclosingMethod() == null) {
-            outerClassInternalName = 
BytecodeHelper.getClassInternalName(outerClass.getName());
+            maybeInnerClassEntry(innerClass.getOuterClass()); // GROOVY-9842
+            outerClassInternalName = 
BytecodeHelper.getClassInternalName(innerClass.getOuterClass().getName());
         } else {
             outerClassInternalName = null; // local inner classes don't 
specify the outer class name
             if (innerClass instanceof InnerClassNode && ((InnerClassNode) 
innerClass).isAnonymous()) innerClassName = null;
diff --git a/src/test/groovy/bugs/Groovy10840.groovy 
b/src/test/groovy/bugs/Groovy10840.groovy
new file mode 100644
index 0000000000..d7079200b4
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy10840.groovy
@@ -0,0 +1,39 @@
+/*
+ *  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 bugs
+
+import org.junit.jupiter.api.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy10840 {
+
+    @Test
+    void testSpecialConstructorCallWithArray() {
+        assertScript '''
+            class BAIS extends ByteArrayInputStream {
+                BAIS(String input) {
+                    super(input.bytes)
+                }
+            }
+
+            assert new BAIS('input').available() >= 5
+        '''
+    }
+}
diff --git a/src/test/groovy/bugs/Groovy7785.groovy 
b/src/test/groovy/bugs/Groovy7785.groovy
index ea9d60d59c..1f98995820 100644
--- a/src/test/groovy/bugs/Groovy7785.groovy
+++ b/src/test/groovy/bugs/Groovy7785.groovy
@@ -18,14 +18,9 @@
  */
 package bugs
 
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable
-
 import static groovy.test.GroovyAssert.assertScript
 
-@DisabledIfEnvironmentVariable(named = "CI", matches = ".*") // runs locally 
but fails in CI, more investigation needed
 final class Groovy7785 {
-    @Test
     void testManyChainedMethodCalls() {
         assertScript '''
             def r = new 
StringBuilder().append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("a").append("
 [...]
diff --git a/src/test/groovy/bugs/Groovy7938Bug.groovy 
b/src/test/groovy/bugs/Groovy7938Bug.groovy
deleted file mode 100644
index a7476f4f60..0000000000
--- a/src/test/groovy/bugs/Groovy7938Bug.groovy
+++ /dev/null
@@ -1,70 +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 bugs
-
-import groovy.test.GroovyTestCase
-
-class Groovy7938Bug extends GroovyTestCase {
-    void testClassUsageInInterfaceDef() {
-        assertScript """
-            class Outer {
-                static Integer fooCount = 0
-                Integer barCount = 0
-                static void incFoo() { fooCount++ }
-                void incBar() { barCount++ }
-                static class Nested {
-                    static void nestedIncFoo() { incFoo() }
-                    static class NestedNested {
-                        static void nestedNestedIncFoo() { incFoo() }
-                    }
-                }
-                Inner innerFactory() { new Inner() }
-                class Inner {
-                    InnerInner innerInnerFactory() { new InnerInner() }
-                    void innerIncFoo() { incFoo() }
-                    static void staticInnerIncFoo() { incFoo() }
-                    class InnerInner {
-                        void innerInnerIncFoo() { incFoo() }
-                        static void staticInnerInnerIncFoo() { incFoo() }
-                    }
-                }
-            }
-            Outer.incFoo()
-            Outer.Nested.nestedIncFoo()
-            Outer.Nested.NestedNested.nestedNestedIncFoo()
-            assert Outer.fooCount == 3
-            new Outer().with {
-                incBar()
-                incFoo()
-                innerFactory().with {
-                    incBar()
-                    innerIncFoo()
-                    staticInnerIncFoo()
-                    innerInnerFactory().with {
-                        incBar()
-                        innerInnerIncFoo()
-                        staticInnerInnerIncFoo()
-                    }
-                }
-                assert barCount == 3
-                assert fooCount == 8
-            }
-        """
-    }
-}
diff --git a/src/test/groovy/gls/innerClass/InnerClassTest.groovy 
b/src/test/groovy/gls/innerClass/InnerClassTest.groovy
index 3006f7798b..d0d546c4cd 100644
--- a/src/test/groovy/gls/innerClass/InnerClassTest.groovy
+++ b/src/test/groovy/gls/innerClass/InnerClassTest.groovy
@@ -50,10 +50,10 @@ final class InnerClassTest {
         assertScript '''import Foo as Bar
             class Foo {}
 
-            def regular = new Bar()
-            def anonymous = new Bar() {}
-            assert regular.class.name == 'Foo'
-            assert anonymous.class.superclass.name == 'Foo'
+            def obj = new Bar()
+            def aic = new Bar() {}
+            assert obj.class.name == 'Foo'
+            assert aic.class.superclass.name == 'Foo'
         '''
 
         assertScript '''import static Baz.Foo as Bar
@@ -61,24 +61,43 @@ final class InnerClassTest {
                 static class Foo {}
             }
 
-            def regular = new Bar()
-            def anonymous = new Bar() {}
-            assert regular.class.name == 'Baz$Foo'
-            assert anonymous.class.superclass.name == 'Baz$Foo'
+            def obj = new Bar()
+            def aic = new Bar() {}
+            assert obj.class.name == 'Baz$Foo'
+            assert aic.class.superclass.name == 'Baz$Foo'
         '''
     }
 
-    // GROOVY-10840
+    // GROOVY-11846
     @Test
-    void testArrayAIC() {
+    void testInnerAIC() {
         assertScript '''
-            class BAIS extends ByteArrayInputStream {
-                BAIS(String input) {
-                    super(input.bytes)
+            class C {
+                def m() {
+                    return { ->
+                        new Object() {
+                        }
+                    }
                 }
             }
 
-            assert new BAIS('input').available() >= 5
+            def obj = new C().m() ()
+            def aic = obj.getClass()
+            assert aic.getName() == 'C$1'
+            assert aic.getEnclosingClass().getName() == 'C' // C$_m_closure1?
+            assert aic.getEnclosingMethod().getName() == 'm' // doCall?
+        '''
+    }
+
+    // GROOVY-11854
+    @Test
+    void testScriptAIC() {
+        assertScript '''
+            def obj = new Object(){}
+            def aic = obj.getClass()
+            assert aic.getName().endsWith('$1')
+            assert aic.getEnclosingClass().getName().startsWith('TestScript')
+            assert aic.getEnclosingMethod()?.getName() == 'run'
         '''
     }
 
@@ -141,6 +160,35 @@ final class InnerClassTest {
         '''
     }
 
+    @Test
+    void testAccessLocalVariableInAIC() {
+        assertScript '''
+            final String objName = 'My name is Guillaume'
+
+            assert new Object() {
+                String toString() { objName }
+            }.toString() == objName
+        '''
+    }
+
+    // GROOVY-5041
+    @Test
+    void testAccessLocalVariableInAIC2() {
+        assertScript '''
+            abstract class A {
+                abstract call()
+            }
+
+            def x = 1
+            def a = new A() {
+                def call() { x }
+            }
+            assert a.call() == 1
+            x = 2
+            assert a.call() == 2
+        '''
+    }
+
     // GROOVY-8448
     @Test
     void testAccessLocalVariableVsGetterInAIC() {
@@ -186,17 +234,6 @@ final class InnerClassTest {
         '''
     }
 
-    @Test
-    void testAccessFinalLocalVariableFromMethodInAIC() {
-        assertScript '''
-            final String objName = "My name is Guillaume"
-
-            assert new Object() {
-                String toString() { objName }
-            }.toString() == objName
-        '''
-    }
-
     // GROOVY-9825
     @Test
     void testAccessSuperInterfaceConstantWithInnerClass() {
@@ -234,14 +271,14 @@ final class InnerClassTest {
             }
 
             class Two extends One {
-              Two() {
-                super(new Object() { // AIC before special ctor call completes
-                  int hashCode() {
-                    hash() // should be able to call static method safely
-                  }
-                })
-              }
-              static int hash() { 42 }
+                Two() {
+                    super(new Object() { // AIC before special ctor call 
completes
+                        int hashCode() {
+                            hash() // should be able to call static method 
safely
+                        }
+                    })
+                }
+                static int hash() { 42 }
             }
 
             def obj = new Two()
@@ -388,8 +425,10 @@ final class InnerClassTest {
     void testStaticInnerClass2() {
         assertScript '''
             class A {
-                static class B {}
+                static class B {
+                }
             }
+
             assert A.declaredClasses.length == 1
             assert A.declaredClasses[0] == A.B
         '''
@@ -401,11 +440,12 @@ final class InnerClassTest {
             class A {
                 static class B {
                     String p
+                    String getQ() { WHY }
                 }
                 B m() {
                     return [p:'x'] // calls 
ScriptBytecodeAdapter.castToType([p:'x'], A$B.class)
                 }
-                static final String q = 'y'
+                private static final String WHY = 'y'
             }
 
             o = new A().m()
@@ -422,6 +462,7 @@ final class InnerClassTest {
                     final String foo = 'foo'
                 }
             }
+
             def b = new A.B(new A())
             assert b.foo == 'foo'
         '''
@@ -465,6 +506,7 @@ final class InnerClassTest {
             class A {
                 class B {}
             }
+
             def x = new A.B() // requires reference to A
         '''
     }
@@ -573,14 +615,14 @@ final class InnerClassTest {
     @Test
     void testUsageOfOuterField() {
         assertScript '''
-            interface Run {
+            interface A {
                 def run()
             }
-            class Foo {
+            class C {
                 private x = 1
 
                 def foo() {
-                    def runner = new Run() {
+                    def runner = new A() {
                         def run() { return x }
                     }
                     runner.run()
@@ -588,24 +630,25 @@ final class InnerClassTest {
 
                 void x(y) { x = y }
             }
-            def foo = new Foo()
-            assert foo.foo() == 1
-            foo.x(2)
-            assert foo.foo() == 2
+
+            def c = new C()
+            assert c.foo() == 1
+            c.x(2)
+            assert c.foo() == 2
         '''
     }
 
     @Test
     void testUsageOfOuterField2() {
         assertScript '''
-            interface Run {
+            interface A {
                 def run()
             }
-            class Foo {
+            class C {
                 private static x = 1
 
                 static foo() {
-                    def runner = new Run() {
+                    def runner = new A() {
                         def run() { return x }
                     }
                     runner.run()
@@ -613,39 +656,16 @@ final class InnerClassTest {
 
                 static x(y) { x = y }
             }
-            assert Foo.foo() == 1
-            Foo.x(2)
-            assert Foo.foo() == 2
-        '''
-    }
 
-    @Test
-    void testUsageOfOuterField3() {
-        assertScript '''
-            interface X {
-                def m()
-            }
-
-            class A {
-                def pm = "pm"
-
-                def bar(x) {x().m()}
-                def foo() {
-                    bar { ->
-                        return new X() {
-                            def m() { pm }
-                        }
-                    }
-                }
-            }
-            def a = new A()
-            assert "pm" == a.foo()
+            assert C.foo() == 1
+            C.x(2)
+            assert C.foo() == 2
         '''
     }
 
     // GROOVY-6141
     @Test
-    void testUsageOfOuterField4() {
+    void testUsageOfOuterField3() {
         assertScript '''
             class A {
                 def x = 1
@@ -676,7 +696,7 @@ final class InnerClassTest {
 
     // GROOVY-9189
     @Test
-    void testUsageOfOuterField5() {
+    void testUsageOfOuterField4() {
         assertScript '''
             interface Run {
                 def run()
@@ -692,6 +712,7 @@ final class InnerClassTest {
 
                 static x(y) { x = y }
             }
+
             assert Foo.foo() == 1
             Foo.x(2)
             assert Foo.foo() == 2
@@ -700,7 +721,7 @@ final class InnerClassTest {
 
     // GROOVY-9168
     @Test
-    void testUsageOfOuterField6() {
+    void testUsageOfOuterField5() {
         assertScript '''
             class A {
                 //                  AIC in this position can use static 
properties:
@@ -719,7 +740,7 @@ final class InnerClassTest {
 
     // GROOVY-9501
     @Test
-    void testUsageOfOuterField7() {
+    void testUsageOfOuterField6() {
         assertScript '''
             class Main extends Outer {
                 static main(args) {
@@ -755,7 +776,7 @@ final class InnerClassTest {
     }
 
     @Test // inner class is static instead of final
-    void testUsageOfOuterField8() {
+    void testUsageOfOuterField7() {
         assertScript '''
             class Main extends Outer {
                 static main(args) {
@@ -792,7 +813,7 @@ final class InnerClassTest {
 
     // GROOVY-9569
     @Test
-    void testUsageOfOuterField9() {
+    void testUsageOfOuterField8() {
         assertScript '''
             class Main extends Outer {
                 static main(args) {
@@ -829,7 +850,7 @@ final class InnerClassTest {
     }
 
     @Test
-    void testUsageOfOuterField10() {
+    void testUsageOfOuterField9() {
         assertScript '''
             class Outer {
                 static final String OUTER_CONSTANT = 'Constant Value'
@@ -853,7 +874,7 @@ final class InnerClassTest {
 
     // GROOVY-5259
     @Test
-    void testUsageOfOuterField11() {
+    void testUsageOfOuterField10() {
         assertScript '''
             class Base {
                 Base(String string) {
@@ -885,7 +906,7 @@ final class InnerClassTest {
     }
 
     @Test
-    void testUsageOfOuterField12() {
+    void testUsageOfOuterField11() {
         def err = shouldFail '''
             class C {
                 int count
@@ -906,18 +927,35 @@ final class InnerClassTest {
 
     // GROOVY-8050
     @Test
-    void testUsageOfOuterField13() {
+    void testUsageOfOuterField12() {
         assertScript '''
             class Outer {
                 class Inner {
                 }
                 def p = 1
             }
+
             def i = new Outer.Inner(new Outer())
             assert i.p == 1
         '''
     }
 
+    @NotYetImplemented @Test
+    void testUsageOfOuterField13() {
+        assertScript '''
+            class Outer {
+                interface Inner {
+                    default i() {
+                        'i' + o
+                    }
+                }
+                private static o = 'o'
+            }
+
+            assert (new Outer.Inner() {}).i() == 'io'
+        '''
+    }
+
     @Test
     void testUsageOfOuterSuperField() {
         assertScript '''
@@ -1026,28 +1064,27 @@ final class InnerClassTest {
     @Test
     void testUsageOfOuterFieldOverridden() {
         assertScript '''
-            interface Run {
+            interface A {
                 def run()
             }
-            class Foo {
-                private x = 1
-
-                def foo() {
-                    def runner = new Run() {
+            class B {
+                def test() {
+                    def runner = new A() {
                         def run() { return x } // <-- dynamic variable
                     }
                     runner.run()
                 }
-
+                private x = 1
                 void setX(val) { x = val }
             }
-            class Bar extends Foo {
-                def x = 'string' // hides 'foo.@x' and overrides 
'foo.setX(val)'
+            class C extends B {
+                def x = 'string' // hides 'B.@x' and overrides 'B.setX(val)'
             }
-            def bar = new Bar()
-            assert bar.foo() == 'string'
-            bar.x = 'new string'
-            assert bar.foo() == 'new string'
+
+            def c = new C()
+            assert c.test() == 'string'
+            c.x = 'new string'
+            assert c.test() == 'new string'
         '''
     }
 
@@ -1067,6 +1104,7 @@ final class InnerClassTest {
                     runner.run()
                 }
             }
+
             def foo = new Foo()
             assert foo.foo() == 1
         '''
@@ -1088,6 +1126,7 @@ final class InnerClassTest {
                     runner.run()
                 }
             }
+
             def foo = new Foo()
             assert foo.foo() == 1
         '''
@@ -1108,6 +1147,7 @@ final class InnerClassTest {
                     runner.run()
                 }
             }
+
             def foo = new Foo()
             assert foo.foo() == 1
         '''
@@ -1129,6 +1169,7 @@ final class InnerClassTest {
                     runner.run()
                 }
             }
+
             def foo = new Foo()
             assert foo.foo() == 1
         '''
@@ -1226,6 +1267,75 @@ final class InnerClassTest {
         '''
     }
 
+    // GROOVY-7938
+    @Test
+    void testUsageOfOuterMethod9() {
+        assertScript '''
+            class Outer {
+                Integer barCount = 0
+                static Integer fooCount = 0
+                void incBar() { barCount++ }
+                static void incFoo() { fooCount++ }
+                Inner innerFactory() { new Inner() }
+
+                static class Nested {
+                    static void nestedIncFoo() { incFoo() }
+                    static class NestedNested {
+                        static void nestedNestedIncFoo() { incFoo() }
+                    }
+                }
+                class Inner {
+                    void innerIncFoo() { incFoo() }
+                    static void staticInnerIncFoo() { incFoo() }
+                    InnerInner innerInnerFactory() { new InnerInner() }
+
+                    class InnerInner {
+                        void innerInnerIncFoo() { incFoo() }
+                        static void staticInnerInnerIncFoo() { incFoo() }
+                    }
+                }
+            }
+
+            Outer.incFoo()
+            Outer.Nested.nestedIncFoo()
+            Outer.Nested.NestedNested.nestedNestedIncFoo()
+            assert Outer.fooCount == 3
+
+            new Outer().with {
+                incBar()
+                incFoo()
+                innerFactory().with {
+                    incBar()
+                    innerIncFoo()
+                    staticInnerIncFoo()
+                    innerInnerFactory().with {
+                        incBar()
+                        innerInnerIncFoo()
+                        staticInnerInnerIncFoo()
+                    }
+                }
+                assert barCount == 3
+                assert fooCount == 8
+            }
+        '''
+    }
+
+    @NotYetImplemented @Test
+    void testUsageOfOuterMethod10() {
+        assertScript '''
+            class Outer {
+                interface Inner {
+                    default i() {
+                        'i' + o()
+                    }
+                }
+                private static o() { 'o' }
+            }
+
+            assert (new Outer.Inner() {}).i() == 'io'
+        '''
+    }
+
     @Test
     void testUsageOfOuterMethodOverridden() {
         assertScript '''
@@ -1446,23 +1556,27 @@ final class InnerClassTest {
     @Test
     void testInnerClassDotThisUsage2() {
         assertScript '''
-            interface X {
+            interface A {
                 def m()
             }
-
-            class A {
+            class B {
                 def foo() {
-                    def c = {
-                        return new X(){def m(){
-                            A.this
-                         } }
+                    def x = { ->
+                        return new A() {
+                            @Override
+                            def m() {
+                                B.this
+                            }
+                        }
                     }
-                    return c().m()
+                    return x().m()
                 }
             }
-            class B extends A {}
-            def b = new B()
-            assert b.foo() instanceof B
+            class C extends B {
+            }
+
+            def c = new C()
+            assert c.foo() instanceof C
         '''
     }
 
@@ -1558,17 +1672,13 @@ final class InnerClassTest {
     void testReferencedVariableInAIC3() {
         assertScript '''
             abstract class A {
-                A() {
-                    m()
-                }
-                abstract void m();
+                abstract void m()
             }
             void test() {
                 def v = false
                 def a = new A() {
-                    // run by super ctor
                     @Override void m() {
-                        assert v != null
+                        assert v == true
                     }
                 }
                 v = true
@@ -2117,6 +2227,7 @@ final class InnerClassTest {
                     inner.inner()
                 }
             }
+
             assert new Outer().test() == 1
         '''
     }
@@ -2138,17 +2249,18 @@ final class InnerClassTest {
                     }
                 }
             }
+
             new Outer().obj.toString()
         '''
     }
 
     // GROOVY-8274
     @Test
-    void testMissingMethodHandling() {
+    void testMethodMissing1() {
         assertScript '''
             class Outer {
                 class Inner {
-                    def methodMissing(String name, args) {
+                    def methodMissing(String name, Object args) {
                         return name
                     }
                 }
@@ -2167,6 +2279,64 @@ final class InnerClassTest {
         '''
     }
 
+    @Test
+    void testMethodMissing2() {
+        assertScript '''
+            class Outer {
+                class Inner {
+                    def methodMissing(String name, Object args) {
+                        return 42
+                    }
+                    def propertyMissing(String name) {
+                        return 42
+                    }
+                }
+            }
+
+            def i = new Outer.Inner(new Outer())
+            assert i.foo()  == 42
+            assert i.foobar == 42
+        '''
+    }
+
+    @Test
+    void testMethodMissing3() {
+        def err = shouldFail '''
+            class Outer {
+                static class Inner {
+                    def methodMissing(String name, Object args) {
+                        return 42
+                    }
+                    def propertyMissing(String name) {
+                        return 42
+                    }
+                }
+            }
+        '''
+        assert err =~ /"methodMissing" implementations are not supported on 
static inner classes as a synthetic version of "methodMissing" is added during 
compilation for the purpose of outer class delegation./
+        assert err =~ /"propertyMissing" implementations are not supported on 
static inner classes as a synthetic version of "propertyMissing" is added 
during compilation for the purpose of outer class delegation./
+    }
+
+    @Test
+    void testMethodMissing4() {
+        def err = shouldFail '''
+            class Outer {
+                static class Inner {
+                    def methodMissing(String name, Object args) {
+                        return 42
+                    }
+                    def propertyMissing(String name) {
+                        return 42
+                    }
+                }
+                static class Other extends Inner {
+                }
+            }
+        '''
+        assert err =~ /"methodMissing" implementations are not supported on 
static inner classes as a synthetic version of "methodMissing" is added during 
compilation for the purpose of outer class delegation./
+        assert err =~ /"propertyMissing" implementations are not supported on 
static inner classes as a synthetic version of "propertyMissing" is added 
during compilation for the purpose of outer class delegation./
+    }
+
     // GROOVY-6831
     @Test
     void testNestedPropertyHandling() {
@@ -2228,6 +2398,7 @@ final class InnerClassTest {
         def err = shouldFail """
             class Upper {
                 $returnType propertyMissing(String name, Object value) {
+                    throw new MissingPropertyException(name, getClass())
                 }
             }
             class Outer {
@@ -2239,6 +2410,59 @@ final class InnerClassTest {
         assert err =~ /No such property: missing for class: Outer.Inner/
     }
 
+    // GROOVY-11823
+    @NotYetImplemented @Test
+    void testNestedPropertyHandling5() {
+        assertScript '''
+            class Upper {
+                Object propertyMissing(String name) {
+                    if (name == 'fizz') return 'buzz'
+                    throw new MissingPropertyException(name, getClass())
+                }
+            }
+            class Outer {
+                static class Inner extends Upper {
+                }
+            }
+            def inner = new Outer.Inner()
+            assert inner.fizz == 'buzz'
+        '''
+    }
+
+    // GROOVY-9618
+    @Test
+    void testNestedPropertyHandling6() {
+        assertScript '''
+            class Super {
+                public static X = 1
+                static getX() { 2 }
+            }
+            class Outer extends Super {
+                static class Inner {
+                    def m() { X }
+                }
+            }
+
+            assert new Outer.Inner().m() == 2
+        '''
+
+        assertScript '''
+            class Outer {
+                public static X = 1
+                static getX() { 2 }
+                static class Inner {
+                }
+            }
+            class Other extends Outer.Inner {
+                def m() {
+                    X // shouldn't read super outer this way
+                }
+            }
+
+            new Other().m()
+        '''
+    }
+
     // GROOVY-7312
     @Test
     void testInnerClassOfInterfaceIsStatic() {
diff --git a/src/test/groovy/groovy/ClosureTest.groovy 
b/src/test/groovy/groovy/ClosureTest.groovy
index 829645151d..52cfc60b35 100644
--- a/src/test/groovy/groovy/ClosureTest.groovy
+++ b/src/test/groovy/groovy/ClosureTest.groovy
@@ -18,8 +18,7 @@
  */
 package groovy
 
-import org.codehaus.groovy.control.MultipleCompilationErrorsException
-import org.junit.Test
+import org.junit.jupiter.api.Test
 
 import static groovy.test.GroovyAssert.assertScript
 import static groovy.test.GroovyAssert.shouldFail
@@ -484,72 +483,6 @@ final class ClosureTest {
         '''
     }
 
-    @Test
-    void testStaticInnerClassOwnerWithPropertyMissingImplementation() {
-        def err = shouldFail MultipleCompilationErrorsException, '''
-            class ClosureTestA {
-                static class ClosureTestB {
-                    def propertyMissing(String myName, Object myValue) {
-                        return myValue
-                    }
-
-                    def propertyMissing(String myName) {
-                        return 42
-                    }
-
-                    def methodMissing(String myName, Object myArgs) {
-                        return 42
-                    }
-                }
-            }
-        '''
-
-        assert err.message.contains('"methodMissing" implementations are not 
supported on static inner classes as a synthetic version of "methodMissing" is 
added during compilation for the purpose of outer class delegation.')
-        assert err.message.contains('"propertyMissing" implementations are not 
supported on static inner classes as a synthetic version of "propertyMissing" 
is added during compilation for the purpose of outer class delegation.')
-    }
-
-    @Test
-    void testInnerClassOwnerWithPropertyMissingImplementation() {
-        assertScript '''
-            class ClosureTestA {
-                class ClosureTestB {
-                    def propertyMissing(String myName, Object myValue) {
-                        return myValue
-                    }
-
-                    def propertyMissing(String myName) {
-                        return 42
-                    }
-
-                    def methodMissing(String myName, Object myArgs) {
-                        return 42
-                    }
-                }
-            }
-
-            def a = new ClosureTestA()
-            def b = new ClosureTestA.ClosureTestB(a)
-        '''
-    }
-
-    @Test
-    void testStaticInnerClassHierarchyWithMethodMissing() {
-        def err = shouldFail MultipleCompilationErrorsException, '''
-            class ClosureTestA {
-                static class ClosureTestB {
-                    def methodMissing(String myName, Object myArgs) {
-                        return 42
-                    }
-                }
-
-                static class ClosureTestB1 extends ClosureTestB {
-                }
-            }
-        '''
-
-        assert err.message.contains('"methodMissing" implementations are not 
supported on static inner classes as a synthetic version of "methodMissing" is 
added during compilation for the purpose of outer class delegation.')
-    }
-
     // GROOVY-10943
     @Test
     void testClosureUnderscorePlaceholder() {
diff --git a/src/test/groovy/groovy/PropertyTest.groovy 
b/src/test/groovy/groovy/PropertyTest.groovy
index 761fcde041..2b2547912e 100644
--- a/src/test/groovy/groovy/PropertyTest.groovy
+++ b/src/test/groovy/groovy/PropertyTest.groovy
@@ -831,24 +831,6 @@ final class PropertyTest {
         '''
     }
 
-    // GROOVY-9618
-    @Test
-    void testPropertyAndStaticUppercaseFieldPriority() {
-        assertScript '''
-            class A {
-                public static X = 1
-                static getX() { 2 }
-                static class B { }
-            }
-            class C extends A.B {
-                def test() {
-                    X
-                }
-            }
-            assert new C().test() == 2
-        '''
-    }
-
     
//--------------------------------------------------------------------------
 
     static class Base {


Reply via email to