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 '''