Skip to content

Commit a36ae26

Browse files
committed
next step
1 parent 02a8b0e commit a36ae26

File tree

7 files changed

+318
-315
lines changed

7 files changed

+318
-315
lines changed

src/main/java/groovy/lang/MetaClassImpl.java

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {

src/main/java/org/codehaus/groovy/classgen/EnumCompletionVisitor.java

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.codehaus.groovy.ast.ClassNode;
2424
import org.codehaus.groovy.ast.CodeVisitorSupport;
2525
import org.codehaus.groovy.ast.ConstructorNode;
26-
import org.codehaus.groovy.ast.InnerClassNode;
2726
import org.codehaus.groovy.ast.Parameter;
2827
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
2928
import org.codehaus.groovy.ast.expr.CastExpression;
@@ -44,15 +43,7 @@
4443

4544
import static java.util.stream.Collectors.toList;
4645
import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedConstructor;
47-
import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE;
48-
import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE;
49-
import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE;
50-
import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
51-
import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
52-
import static org.codehaus.groovy.ast.tools.GeneralUtils.params;
53-
import static org.codehaus.groovy.transform.sc.StaticCompilationVisitor.isStaticallyCompiled;
5446
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
55-
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
5647
import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
5748

5849
/**
@@ -93,11 +84,6 @@ private void completeEnum(final ClassNode enumClass) {
9384
for (ConstructorNode ctor : nonSyntheticConstructors(enumClass)) {
9485
transformConstructor(ctor);
9586
}
96-
97-
var outerClass = enumClass.getOuterClass(); // GROOVY-7024
98-
if (outerClass != null && !isStaticallyCompiled(enumClass)) {
99-
addOuterClassDispatch((InnerClassNode) enumClass, outerClass);
100-
}
10187
}
10288

10389
/**
@@ -206,41 +192,4 @@ private static void makeBridgeConstructor(final ClassNode e, final Parameter[] p
206192
private static List<ConstructorNode> nonSyntheticConstructors(final ClassNode cn) {
207193
return cn.getDeclaredConstructors().stream().filter(c -> !c.isSynthetic()).collect(toList());
208194
}
209-
210-
private void addOuterClassDispatch(final InnerClassNode innerClass, final ClassNode outerClass) {
211-
var visitor = new InnerClassCompletionVisitor(null, sourceUnit);
212-
213-
visitor.addMissingHandler(
214-
innerClass,
215-
"methodMissing",
216-
ACC_PUBLIC,
217-
OBJECT_TYPE,
218-
params(param(STRING_TYPE, "name"), param(OBJECT_TYPE, "args")),
219-
(methodBody, parameters) -> {
220-
InnerClassVisitorHelper.setMethodDispatcherCode(methodBody, classX(outerClass), parameters);
221-
}
222-
);
223-
224-
visitor.addMissingHandler(
225-
innerClass,
226-
"propertyMissing",
227-
ACC_PUBLIC,
228-
OBJECT_TYPE,
229-
params(param(STRING_TYPE, "name")),
230-
(methodBody, parameters) -> {
231-
InnerClassVisitorHelper.setPropertyGetterDispatcher(methodBody, classX(outerClass), parameters);
232-
}
233-
);
234-
235-
visitor.addMissingHandler(
236-
innerClass,
237-
"propertyMissing",
238-
ACC_PUBLIC,
239-
VOID_TYPE,
240-
params(param(STRING_TYPE, "name"), param(OBJECT_TYPE, "value")),
241-
(methodBody, parameters) -> {
242-
InnerClassVisitorHelper.setPropertySetterDispatcher(methodBody, classX(outerClass), parameters);
243-
}
244-
);
245-
}
246195
}

src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public void visitClass(final ClassNode node) {
120120

121121
boolean innerPojo = hasAnnotation(node, new ClassNode(POJO.class))
122122
&& hasAnnotation(node, new ClassNode(CompileStatic.class));
123-
if (!innerPojo) {
123+
if (!innerPojo && !isStatic(innerClass)) {
124124
addMopMethods(innerClass);
125125
}
126126
}
@@ -307,7 +307,7 @@ public void visit(final MethodVisitor mv) {
307307
);
308308
}
309309

310-
/* */ void addMissingHandler(final InnerClassNode innerClass, final String methodName, final int modifiers,
310+
private void addMissingHandler(final InnerClassNode innerClass, final String methodName, final int modifiers,
311311
final ClassNode returnType, final Parameter[] parameters, final BiConsumer<BlockStatement, Parameter[]> consumer) {
312312
MethodNode method = innerClass.getDeclaredMethod(methodName, parameters);
313313
if (method == null) {

0 commit comments

Comments
 (0)