This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY-4737 in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 4549d8e9dfbf4baf78f04f86f2eaf9106e24fb47 Author: Eric Milles <[email protected]> AuthorDate: Sat Jan 24 11:08:04 2026 -0600 4737, 4862, 5875, 6580, 6581 --- src/main/java/groovy/lang/MetaClassImpl.java | 86 +++++++++++++++++++++- .../classgen/InnerClassCompletionVisitor.java | 20 ----- 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java index 94c972b72e..0cafef6b4e 100644 --- a/src/main/java/groovy/lang/MetaClassImpl.java +++ b/src/main/java/groovy/lang/MetaClassImpl.java @@ -1899,16 +1899,55 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass { //---------------------------------------------------------------------- // missing property protocol //---------------------------------------------------------------------- - return invokeMissingProperty(object, name, null, true); + try { + return invokeMissingProperty(object, name, null, true); + } catch (MissingPropertyException mpe) { + if (false && sender == theClass) { + Class<?> outerClass = theClass.getEnclosingClass(); + if (outerClass != null) { + MetaClass omc = registry.getMetaClass(outerClass); + try { + Object outer = outerClass; + if ((theClass.getModifiers() & Opcodes.ACC_STATIC) == 0) { + try { + theClass.getDeclaredField("this$0"); + outer = getAttribute(object, "this$0"); + } catch (NoSuchFieldException e) { + } + } + return omc.getProperty(outerClass, outer, name, false, false); + } catch (MissingPropertyException suppressed) { + mpe.addSuppressed(suppressed); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + throw mpe; + } } private Object getClassProperty(final Class<?> sender, final Class<?> receiver, final String name) throws MissingPropertyException { try { MetaClass cmc = registry.getMetaClass(Class.class); return cmc.getProperty(Class.class, receiver, name, false, false); - } catch (MissingPropertyException ignore) { + } catch (MissingPropertyException ignored) { + } + + try { // try $static_propertyMissing / throw MissingPropertyException return invokeStaticMissingProperty(receiver, name, null, true); + } catch (MissingPropertyException missing) { + Class<?> outerClass = theClass.getEnclosingClass(); + if (outerClass != null && sender.isNestmateOf(outerClass)) { + try { + MetaClass omc = registry.getMetaClass(outerClass); + return omc.getProperty(sender, outerClass, name, false, false); + } catch (MissingPropertyException mpe) { + missing.addSuppressed(mpe); + } + } + throw missing; } } @@ -2037,7 +2076,32 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass { return new ReadOnlyMetaProperty(name) { @Override public Object getProperty(final Object receiver) { - return invokeMissingProperty(receiver, getName(), null, true); + try { + return invokeMissingProperty(receiver, getName(), null, true); + } catch (MissingPropertyException mpe) { + if (false && sender == theClass) { + Class<?> outerClass = theClass.getEnclosingClass(); + if (outerClass != null) { + MetaClass omc = registry.getMetaClass(outerClass); + try { + Object outer = outerClass; + if ((theClass.getModifiers() & Opcodes.ACC_STATIC) == 0) { + try { + theClass.getDeclaredField("this$0"); + outer = getAttribute(receiver, "this$0"); + } catch (NoSuchFieldException e) { + } + } + return omc.getProperty(outerClass, outer, name, false, false); + } catch (MissingPropertyException suppressed) { + mpe.addSuppressed(suppressed); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + throw mpe; + } } }; } @@ -2780,7 +2844,21 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass { if (!isStatic) { invokeMissingProperty(object, name, newValue, false); } else { - invokeStaticMissingProperty(object, name, newValue, false); + try { + invokeStaticMissingProperty(object, name, newValue, false); + } catch (MissingPropertyException missing) { + Class<?> outerClass = theClass.getEnclosingClass(); + if (outerClass != null && sender.isNestmateOf(outerClass)) { + try { + MetaClass omc = registry.getMetaClass(outerClass); + omc.setProperty(sender, outerClass, name, newValue, false, false); + return; + } catch (MissingPropertyException mpe) { + missing.addSuppressed(mpe); + } + } + throw missing; + } } } diff --git a/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java b/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java index fb70379836..b1366768f1 100644 --- a/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java +++ b/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java @@ -292,16 +292,6 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper { } ); - addMissingHandler(node, - "$static_propertyMissing", - ACC_PUBLIC | ACC_STATIC, - VOID_TYPE, - params(param(STRING_TYPE, "name"), param(OBJECT_TYPE, "value")), - (methodBody, parameters) -> { - setPropertySetterDispatcher(methodBody, classX(outerClass), parameters); - } - ); - addMissingHandler(node, "propertyMissing", ACC_PUBLIC, @@ -325,16 +315,6 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper { } } ); - - addMissingHandler(node, - "$static_propertyMissing", - ACC_PUBLIC | ACC_STATIC, - OBJECT_TYPE, - params(param(STRING_TYPE, "name")), - (methodBody, parameters) -> { - setPropertyGetterDispatcher(methodBody, classX(outerClass), parameters); - } - ); } /* */ void addMissingHandler(final InnerClassNode innerClass, final String methodName, final int modifiers,
