This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 7910206f94b07b202003e534cabd937edc2d23a5
Author: Eric Milles <[email protected]>
AuthorDate: Thu Aug 25 13:19:19 2022 -0500

    GROOVY-8050, GROOVY-10414: STC: non-static outer class property setter
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 71 ++++++++++------------
 .../stc/FieldsAndPropertiesSTCTest.groovy          |  2 +-
 2 files changed, 34 insertions(+), 39 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 220cb0e053..954d8c06ba 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4666,13 +4666,14 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
 
     protected List<MethodNode> findMethod(ClassNode receiver, final String 
name, final ClassNode... args) {
         if (isPrimitiveType(receiver)) receiver = getWrapper(receiver);
+
         List<MethodNode> methods;
-        if (!receiver.isInterface() && "<init>".equals(name)) {
+        if ("<init>".equals(name) && !receiver.isInterface()) {
             methods = addGeneratedMethods(receiver, new 
ArrayList<MethodNode>(receiver.getDeclaredConstructors()));
             if (methods.isEmpty()) {
                 MethodNode node = new ConstructorNode(Opcodes.ACC_PUBLIC, 
Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
                 node.setDeclaringClass(receiver);
-                methods = Collections.singletonList(node);
+                methods.add(node);
                 if (receiver.isArray()) {
                     // No need to check the arguments against an array 
constructor: it just needs to exist. The array is
                     // created through coercion or by specifying its 
dimension(s), anyway, and would not match an
@@ -4682,16 +4683,12 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
             }
         } else {
             methods = findMethodsWithGenerated(receiver, name);
-            // TODO: investigate the trait exclusion a bit further, needed 
otherwise
-            // CallMethodOfTraitInsideClosureAndClosureParamTypeInference 
fails saying
-            // not static method can't be called from a static context
-            if (typeCheckingContext.getEnclosingClosure() == null || (receiver 
instanceof InnerClassNode && !receiver.getName().endsWith("$Trait$Helper"))) {
-                // not in a closure or within an inner class
-                ClassNode parent = receiver;
-                while (parent instanceof InnerClassNode && 
!parent.isStaticClass()) {
-                    parent = parent.getOuterClass();
-                    methods.addAll(findMethodsWithGenerated(parent, name));
-                }
+            if (!receiver.isStaticClass() && receiver.getOuterClass() != null
+                    && !receiver.getName().endsWith("$Trait$Helper") // 
GROOVY-7242
+                    && 
typeCheckingContext.getEnclosingClassNodes().contains(receiver)) {
+                ClassNode outer = receiver.getOuterClass();
+                do { methods.addAll(findMethodsWithGenerated(outer, name));
+                } while (!outer.isStaticClass() && (outer = 
outer.getOuterClass()) != null);
             }
             if (methods.isEmpty()) {
                 addArrayMethods(methods, receiver, name, args);
@@ -4703,22 +4700,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                     pname = extractPropertyNameFromMethodName("is", name);
                 }
                 if (pname != null) {
-                    // we don't use property exists there because findMethod 
is called on super clases recursively
-                    PropertyNode property = null;
-                    ClassNode curNode = receiver;
-                    while (property == null && curNode != null) {
-                        property = curNode.getProperty(pname);
-                        ClassNode svCur = curNode;
-                        while (property == null && svCur instanceof 
InnerClassNode && !svCur.isStaticClass()) {
-                            svCur = svCur.getOuterClass();
-                            property = svCur.getProperty(pname);
-                            if (property != null) {
-                                receiver = svCur;
-                                break;
-                            }
-                        }
-                        curNode = curNode.getSuperClass();
-                    }
+                    PropertyNode property = findProperty(receiver, pname);
                     if (property != null) {
                         int mods = Opcodes.ACC_PUBLIC | (property.isStatic() ? 
Opcodes.ACC_STATIC : 0);
                         MethodNode node = new MethodNode(name, mods, 
property.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, 
GENERATED_EMPTY_STATEMENT);
@@ -4730,13 +4712,8 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                 // maybe we are looking for a setter ?
                 String pname = extractPropertyNameFromMethodName("set", name);
                 if (pname != null) {
-                    ClassNode curNode = receiver;
-                    PropertyNode property = null;
-                    while (property == null && curNode != null) {
-                        property = curNode.getProperty(pname);
-                        curNode = curNode.getSuperClass();
-                    }
-                    if (property != null) {
+                    PropertyNode property = findProperty(receiver, pname);
+                    if (property != null && 
!Modifier.isFinal(property.getModifiers())) {
                         ClassNode type = property.getOriginType();
                         if 
(implementsInterfaceOrIsSubclassOf(wrapTypeIfNecessary(args[0]), 
wrapTypeIfNecessary(type))) {
                             int mods = Opcodes.ACC_PUBLIC | 
(property.isStatic() ? Opcodes.ACC_STATIC : 0);
@@ -4765,10 +4742,11 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
             }
         }
 
-        if (isClassClassNodeWrappingConcreteType(receiver)) {
-            chosen = findMethod(receiver.getGenericsTypes()[0].getType(), 
name, args);
-            if (!chosen.isEmpty()) return chosen;
+        if (isClassClassNodeWrappingConcreteType(receiver)) { // GROOVY-6802, 
GROOVY-6803
+            List<MethodNode> result = 
findMethod(receiver.getGenericsTypes()[0].getType(), name, args);
+            if (!result.isEmpty()) return result;
         }
+
         if (receiver.equals(GSTRING_TYPE)) {
             return findMethod(STRING_TYPE, name, args);
         }
@@ -4779,6 +4757,23 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         return EMPTY_METHODNODE_LIST;
     }
 
+    private PropertyNode findProperty(final ClassNode receiver, final String 
name) {
+        for (ClassNode cn = receiver; cn != null; cn = cn.getSuperClass()) {
+            PropertyNode property = cn.getProperty(name);
+            if (property != null) return property;
+
+            if (!cn.isStaticClass() && cn.getOuterClass() != null
+                    && 
typeCheckingContext.getEnclosingClassNodes().contains(cn)) {
+                ClassNode outer = cn.getOuterClass();
+                do {
+                    property = outer.getProperty(name);
+                    if (property != null) return property;
+                } while (!outer.isStaticClass() && (outer = 
outer.getOuterClass()) != null);
+            }
+        }
+        return null;
+    }
+
     private List<MethodNode> filterMethodsByVisibility(List<MethodNode> 
methods) {
         if (!asBoolean(methods)) {
             return EMPTY_METHODNODE_LIST;
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy 
b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index 09c0b05b42..f0688df44e 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -576,7 +576,7 @@ class FieldsAndPropertiesSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
-    @NotYetImplemented // GROOVY-10414
+    // GROOVY-10414
     void testOuterPropertyAccess3() {
         assertScript '''
             class Outer {

Reply via email to