This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY_3_0_X in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push: new c6bca930e3 GROOVY-11352: `this` or `super` ctor call: outer static method arguments c6bca930e3 is described below commit c6bca930e36c103334438fb90d6c44ceb8d8fa51 Author: Eric Milles <eric.mil...@thomsonreuters.com> AuthorDate: Tue Apr 23 13:02:46 2024 -0500 GROOVY-11352: `this` or `super` ctor call: outer static method arguments 3_0_X backport --- .../java/org/codehaus/groovy/classgen/Verifier.java | 15 ++++++++++----- .../groovy/classgen/asm/InvocationWriter.java | 15 ++++++++++++--- src/test/gls/innerClass/InnerClassTest.groovy | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java index 357856f2a1..f45b7a0893 100644 --- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java +++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java @@ -559,12 +559,17 @@ public class Verifier implements GroovyClassVisitor, Opcodes { @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); diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java index 74139c88f5..046cb37e8e 100644 --- a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java +++ b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java @@ -795,9 +795,18 @@ public class InvocationWriter { } 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) { diff --git a/src/test/gls/innerClass/InnerClassTest.groovy b/src/test/gls/innerClass/InnerClassTest.groovy index 7d2b2ee279..a3c209a0e0 100644 --- a/src/test/gls/innerClass/InnerClassTest.groovy +++ b/src/test/gls/innerClass/InnerClassTest.groovy @@ -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 '''