Skip to content

Commit

Permalink
GROOVY-11352: this or super ctor call: outer static method arguments
Browse files Browse the repository at this point in the history
3_0_X backport
  • Loading branch information
eric-milles committed Apr 23, 2024
1 parent fbfdb6c commit c6bca93
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 8 deletions.
15 changes: 10 additions & 5 deletions src/main/java/org/codehaus/groovy/classgen/Verifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -559,12 +559,17 @@ public void visitConstructorCallExpression(final ConstructorCallExpression cce)
@Override
public void visitMethodCallExpression(final MethodCallExpression mce) {
if (inSpecialConstructorCall && isThisObjectExpression(mce)) {
MethodNode methodTarget = mce.getMethodTarget();
if (methodTarget == null || !(methodTarget.isStatic() || classNode.getOuterClasses().contains(methodTarget.getDeclaringClass()))) {
if (!mce.isImplicitThis()) {
throw newVariableError(mce.getObjectExpression().getText(), mce.getObjectExpression());
} else {
boolean outerOrStaticMember = false;
if (mce.getMethodTarget() != null) {
outerOrStaticMember = mce.getMethodTarget().isStatic() || classNode.getOuterClasses().contains(mce.getMethodTarget().getDeclaringClass());
} else if (mce.isImplicitThis()) { // GROOVY-11352
outerOrStaticMember = classNode.getOuterClasses().stream().anyMatch(oc -> oc.hasPossibleStaticMethod(mce.getMethodAsString(), mce.getArguments()));
}
if (!outerOrStaticMember) {
if (mce.isImplicitThis()) {
throw newVariableError(mce.getMethodAsString(), mce.getMethod());
} else {
throw newVariableError(mce.getObjectExpression().getText(), mce.getObjectExpression());
}
}
mce.getMethod().visit(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -795,9 +795,18 @@ private void invokeClosure(final Expression arguments, final String methodName)
}

private boolean isStaticInvocation(final MethodCallExpression call) {
if (!isThisExpression(call.getObjectExpression())) return false;
if (controller.isStaticMethod()) return true;
return controller.isStaticContext() && !call.isImplicitThis();
if (isThisExpression(call.getObjectExpression())) {
if (controller.getCompileStack().isInSpecialConstructorCall()) {
return true;
}
if (controller.isStaticContext() && !call.isImplicitThis()) {
return true;
}
if (controller.isStaticMethod()) {
return true;
}
}
return false;
}

public void writeInvokeStaticMethod(final StaticMethodCallExpression call) {
Expand Down
20 changes: 20 additions & 0 deletions src/test/gls/innerClass/InnerClassTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,26 @@ final class InnerClassTest {
'''
}

@Test // GROOVY-11352
void testUsageOfOuterMethod7() {
assertScript '''
class Super {
protected final String s
Super(String s) { this.s = s }
}
class Outer {
static String initValue() { 'ok' }
static class Inner extends Super {
Inner() {
super(initValue()) // here
}
}
String test() { new Inner().s }
}
assert new Outer().test() == 'ok'
'''
}

@Test
void testUsageOfOuterMethodOverridden() {
assertScript '''
Expand Down

0 comments on commit c6bca93

Please sign in to comment.