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 ab79a69007 GROOVY-11822: allow override `Object 
propertyMissing(String, Object)`
ab79a69007 is described below

commit ab79a6900762c58867743d2ecf2c502bd7c68144
Author: Eric Milles <[email protected]>
AuthorDate: Sun Dec 28 15:41:32 2025 -0600

    GROOVY-11822: allow override `Object propertyMissing(String, Object)`
    
    4_0_X backport
---
 .../groovy/classgen/InnerClassCompletionVisitor.java     | 13 ++++++++++---
 src/test/groovy/gls/innerClass/InnerClassTest.groovy     | 16 ++++++++++++++++
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java 
b/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
index 37ea270490..e8d89633e9 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
@@ -40,6 +40,7 @@ import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.SourceUnit;
 import org.objectweb.asm.MethodVisitor;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.function.BiConsumer;
 
@@ -71,12 +72,12 @@ import static 
org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
 import static org.objectweb.asm.Opcodes.ACC_STATIC;
 import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
+import static org.objectweb.asm.Opcodes.ACONST_NULL;
 import static org.objectweb.asm.Opcodes.ALOAD;
 import static org.objectweb.asm.Opcodes.ARETURN;
 import static org.objectweb.asm.Opcodes.CHECKCAST;
 import static org.objectweb.asm.Opcodes.GETFIELD;
 import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
-import static org.objectweb.asm.Opcodes.RETURN;
 
 public class InnerClassCompletionVisitor extends InnerClassVisitorHelper {
 
@@ -257,10 +258,15 @@ public class InnerClassCompletionVisitor extends 
InnerClassVisitorHelper {
                 }
         );
 
+        ClassNode[] nameValueTypes = {STRING_TYPE, OBJECT_TYPE}; // 
GROOVY-11822: "def propertyMissing(String,Object)"
+        ClassNode returnType = 
node.getMethods("propertyMissing").stream().filter(m -> !m.isStatic() && 
!m.isPrivate()
+                 && 
Arrays.equals(Arrays.stream(m.getParameters()).map(Parameter::getType).toArray(),
 nameValueTypes))
+                .findFirst().map(MethodNode::getReturnType).orElse(VOID_TYPE);
+
         addMissingHandler(node,
                 "propertyMissing",
                 ACC_PUBLIC,
-                VOID_TYPE,
+                returnType,
                 params(param(STRING_TYPE, "name"), param(OBJECT_TYPE, 
"value")),
                 (methodBody, parameters) -> {
                     if (isStatic) {
@@ -274,7 +280,8 @@ public class InnerClassCompletionVisitor extends 
InnerClassVisitorHelper {
                                         mv.visitVarInsn(ALOAD, 1);
                                         mv.visitVarInsn(ALOAD, 2);
                                         mv.visitMethodInsn(INVOKEVIRTUAL, 
outerClassInternalName, "this$dist$set$" + outerClassDistance, 
"(Ljava/lang/String;Ljava/lang/Object;)V", false);
-                                        mv.visitInsn(RETURN);
+                                        if 
(!ClassHelper.isPrimitiveVoid(returnType)) mv.visitInsn(ACONST_NULL);
+                                        BytecodeHelper.doReturn(mv, 
returnType);
                                     }
                                 })
                         );
diff --git a/src/test/groovy/gls/innerClass/InnerClassTest.groovy 
b/src/test/groovy/gls/innerClass/InnerClassTest.groovy
index 4378c49efa..1f1b6259c9 100644
--- a/src/test/groovy/gls/innerClass/InnerClassTest.groovy
+++ b/src/test/groovy/gls/innerClass/InnerClassTest.groovy
@@ -2078,6 +2078,22 @@ final class InnerClassTest {
         '''
     }
 
+    @Test // GROOVY-11822
+    void testNestedPropertyHandling4() {
+        def err = shouldFail '''
+            class Upper {
+                def propertyMissing(String name, Object value) {
+                }
+            }
+            class Outer {
+                static class Inner extends Upper {
+                }
+            }
+            new Outer.Inner().missing = 42
+        '''
+        assert err =~ /No such property: missing for class: Outer.Inner/
+    }
+
     @Test // GROOVY-7312
     void testInnerClassOfInterfaceIsStatic() {
         assertScript '''

Reply via email to