@@ -1217,7 +1217,29 @@ public Object invokeMethod(final Class sender, final Object object, final String
12171217 return transformedMetaMethod .doMethodInvoke (object , arguments );
12181218 }
12191219
1220- return invokePropertyOrMissing (sender , object , methodName , originalArguments , fromInsideClass , isCallToSuper );
1220+ try {
1221+ return invokePropertyOrMissing (sender , object , methodName , originalArguments , fromInsideClass , isCallToSuper );
1222+ } catch (MissingMethodException mme ) {
1223+ if (!isCallToSuper ) {
1224+ return invokeOuterMethod (sender , object , methodName , originalArguments , mme ); // GROOVY-11823
1225+ }
1226+ throw mme ;
1227+ }
1228+ }
1229+
1230+ private Object invokeOuterMethod (final Class <?> sender , final Object object , final String methodName , final Object [] arguments , final MissingMethodException mme ) {
1231+ if (sender == theClass ? isGroovyObject () : GroovyObject .class .isAssignableFrom (sender )) {
1232+ var outerClass = sender .getEnclosingClass (); // check outer class nesting of call site
1233+ if (outerClass != null && (sender == theClass || sender .isAssignableFrom (theClass ))) {
1234+ MetaClass omc = registry .getMetaClass (outerClass );
1235+ try {
1236+ return omc .invokeMethod (outerClass , outerClass , methodName , arguments , false , false );
1237+ } catch (MissingMethodException e ) {
1238+ mme .addSuppressed (e );
1239+ }
1240+ }
1241+ }
1242+ throw mme ;
12211243 }
12221244
12231245 private MetaMethod getMetaMethod (final Class <?> sender , final Object object , final String methodName , final boolean isCallToSuper , final Object [] arguments ) {
@@ -1894,28 +1916,7 @@ public Object getProperty(final Class sender, final Object object, final String
18941916 try {
18951917 return invokeMissingProperty (object , name , null , true );
18961918 } catch (MissingPropertyException mpe ) {
1897- if (false && sender == theClass ) {
1898- Class <?> outerClass = theClass .getEnclosingClass ();
1899- if (outerClass != null ) {
1900- MetaClass omc = registry .getMetaClass (outerClass );
1901- try {
1902- Object outer = outerClass ;
1903- if ((theClass .getModifiers () & Opcodes .ACC_STATIC ) == 0 ) {
1904- try {
1905- theClass .getDeclaredField ("this$0" );
1906- outer = getAttribute (object , "this$0" );
1907- } catch (NoSuchFieldException e ) {
1908- }
1909- }
1910- return omc .getProperty (outerClass , outer , name , false , false );
1911- } catch (MissingPropertyException suppressed ) {
1912- mpe .addSuppressed (suppressed );
1913- } catch (Throwable t ) {
1914- t .printStackTrace ();
1915- }
1916- }
1917- }
1918- throw mpe ;
1919+ return getOuterProperty (sender , object , name , mpe );
19191920 }
19201921 }
19211922
@@ -1945,6 +1946,21 @@ private Object getClassProperty(final Class<?> sender, final Class<?> receiver,
19451946 }
19461947 }
19471948
1949+ private Object getOuterProperty (final Class <?> sender , final Object object , final String name , final MissingPropertyException mpe ) {
1950+ if (sender == theClass ? isGroovyObject () : GroovyObject .class .isAssignableFrom (sender )) {
1951+ var outerClass = sender .getEnclosingClass (); // check outer class nesting of call site
1952+ if (outerClass != null && (sender == theClass || sender .isAssignableFrom (theClass ))) {
1953+ MetaClass omc = registry .getMetaClass (outerClass );
1954+ try {
1955+ return omc .getProperty (outerClass , outerClass , name , false , false );
1956+ } catch (MissingPropertyException e ) {
1957+ mpe .addSuppressed (e );
1958+ }
1959+ }
1960+ }
1961+ throw mpe ;
1962+ }
1963+
19481964 public MetaProperty getEffectiveGetMetaProperty (final Class sender , final Object object , final String name , final boolean useSuper ) {
19491965
19501966 //----------------------------------------------------------------------
@@ -2073,28 +2089,7 @@ public Object getProperty(final Object receiver) {
20732089 try {
20742090 return invokeMissingProperty (receiver , getName (), null , true );
20752091 } catch (MissingPropertyException mpe ) {
2076- if (false && sender == theClass ) {
2077- Class <?> outerClass = theClass .getEnclosingClass ();
2078- if (outerClass != null ) {
2079- MetaClass omc = registry .getMetaClass (outerClass );
2080- try {
2081- Object outer = outerClass ;
2082- if ((theClass .getModifiers () & Opcodes .ACC_STATIC ) == 0 ) {
2083- try {
2084- theClass .getDeclaredField ("this$0" );
2085- outer = getAttribute (receiver , "this$0" );
2086- } catch (NoSuchFieldException e ) {
2087- }
2088- }
2089- return omc .getProperty (outerClass , outer , getName (), false , false );
2090- } catch (MissingPropertyException suppressed ) {
2091- mpe .addSuppressed (suppressed );
2092- } catch (Throwable t ) {
2093- t .printStackTrace ();
2094- }
2095- }
2096- }
2097- throw mpe ;
2092+ return getOuterProperty (sender , receiver , getName (), mpe );
20982093 }
20992094 }
21002095 };
@@ -2835,27 +2830,32 @@ public void setProperty(final Class sender, final Object object, final String na
28352830 if (mp != null ) {
28362831 throw new ReadOnlyPropertyException (name , theClass );
28372832 }
2838- if (! isStatic ) {
2839- invokeMissingProperty ( object , name , newValue , false );
2840- } else {
2841- try {
2833+ try {
2834+ if (! isStatic ) {
2835+ invokeMissingProperty ( object , name , newValue , false );
2836+ } else {
28422837 invokeStaticMissingProperty (object , name , newValue , false );
2843- } catch (MissingPropertyException missing ) {
2844- if (isGroovyObject ()) { // GROOVY-11823, et al.
2845- var outerClass = theClass .getEnclosingClass ();
2846- if (outerClass != null && sender .isNestmateOf (outerClass )) {
2847- try {
2848- MetaClass omc = registry .getMetaClass (outerClass );
2849- omc .setProperty (sender , outerClass , name , newValue , false , false );
2850- return ;
2851- } catch (MissingPropertyException mpe ) {
2852- missing .addSuppressed (mpe );
2853- }
2854- }
2838+ }
2839+ } catch (MissingPropertyException e ) {
2840+ if (!useSuper ) setOuterProperty (sender , object , name , newValue , e ); else throw e ; // GROOVY-11823
2841+ }
2842+ }
2843+
2844+ private void setOuterProperty (Class <?> sender , final Object object , final String name , final Object newValue , final MissingPropertyException mpe ) {
2845+ if (sender == null ) sender = theClass ; // GROOVY-11745
2846+ if (sender == theClass ? isGroovyObject () : GroovyObject .class .isAssignableFrom (sender )) {
2847+ var outerClass = sender .getEnclosingClass (); // check outer class nesting of call site
2848+ if (outerClass != null && (sender == theClass || sender .isAssignableFrom (theClass ))) {
2849+ MetaClass omc = registry .getMetaClass (outerClass );
2850+ try {
2851+ omc .setProperty (outerClass , outerClass , name , newValue , false , false );
2852+ return ;
2853+ } catch (MissingPropertyException e ) {
2854+ mpe .addSuppressed (e );
28552855 }
2856- throw missing ;
28572856 }
28582857 }
2858+ throw mpe ;
28592859 }
28602860
28612861 private MetaProperty getMetaProperty (final Class <?> clazz , final String name , final boolean useSuper , final boolean useStatic ) {
0 commit comments