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 '''

Reply via email to