You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/08/25 18:51:34 UTC

[groovy] branch GROOVY_2_5_X updated (d8359c2764 -> 91b22b877e)

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

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


    from d8359c2764 add test cases
     new 7910206f94 GROOVY-8050, GROOVY-10414: STC: non-static outer class property setter
     new 91b22b877e GROOVY-9893: STC: `findSetters` must look in super types

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../transform/stc/StaticTypeCheckingSupport.java   | 29 ++++-----
 .../transform/stc/StaticTypeCheckingVisitor.java   | 71 ++++++++++------------
 .../stc/FieldsAndPropertiesSTCTest.groovy          |  2 +-
 .../sc/FieldsAndPropertiesStaticCompileTest.groovy | 11 ----
 4 files changed, 47 insertions(+), 66 deletions(-)


[groovy] 02/02: GROOVY-9893: STC: `findSetters` must look in super types

Posted by em...@apache.org.
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 91b22b877e1ec9864d06089f56290484871e4604
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jan 18 11:14:05 2021 -0600

    GROOVY-9893: STC: `findSetters` must look in super types
---
 .../transform/stc/StaticTypeCheckingSupport.java   | 29 ++++++++++------------
 .../sc/FieldsAndPropertiesStaticCompileTest.groovy | 11 --------
 2 files changed, 13 insertions(+), 27 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index f1428f3aea..a9d1182547 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -2329,29 +2329,26 @@ public abstract class StaticTypeCheckingSupport {
                 && !genericsTypes[0].isWildcard();
     }
 
-    public static List<MethodNode> findSetters(ClassNode cn, String setterName, boolean voidOnly) {
-        List<MethodNode> result = null;
-        for (MethodNode method : cn.getDeclaredMethods(setterName)) {
-            if (setterName.equals(method.getName())
-                    && (!voidOnly || VOID_TYPE == method.getReturnType())
-                    && method.getParameters().length == 1) {
-                if (result == null) {
-                    result = new LinkedList<MethodNode>();
-                }
-                result.add(method);
+    public static List<MethodNode> findSetters(final ClassNode cn, final String setterName, final boolean voidOnly) {
+        List<MethodNode> result = new ArrayList<MethodNode>();
+        if (!cn.isInterface()) {
+            for (MethodNode method : cn.getMethods(setterName)) {
+                if (isSetter(method, voidOnly)) result.add(method);
             }
         }
-        if (result == null) {
-            ClassNode parent = cn.getSuperClass();
-            if (parent != null) {
-                return findSetters(parent, setterName, voidOnly);
+        for (ClassNode in : cn.getAllInterfaces()) {
+            for (MethodNode method : in.getDeclaredMethods(setterName)) {
+                if (isSetter(method, voidOnly)) result.add(method);
             }
-            return Collections.emptyList();
         }
         return result;
     }
 
-    public static ClassNode isTraitSelf(VariableExpression vexp) {
+    private static boolean isSetter(final MethodNode mn, final boolean voidOnly) {
+        return (!voidOnly || mn.isVoidMethod()) && mn.getParameters().length == 1;
+    }
+
+    public static ClassNode isTraitSelf(final VariableExpression vexp) {
         if (Traits.THIS_OBJECT.equals(vexp.getName())) {
             Variable accessedVariable = vexp.getAccessedVariable();
             ClassNode type = accessedVariable != null ? accessedVariable.getType() : null;
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
index 1fc5c60ed3..afef3d75e4 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -18,7 +18,6 @@
  */
 package org.codehaus.groovy.classgen.asm.sc
 
-import groovy.transform.NotYetImplemented
 import groovy.transform.stc.FieldsAndPropertiesSTCTest
 
 final class FieldsAndPropertiesStaticCompileTest extends FieldsAndPropertiesSTCTest implements StaticCompilationTestSupport {
@@ -42,16 +41,6 @@ final class FieldsAndPropertiesStaticCompileTest extends FieldsAndPropertiesSTCT
         '''
     }
 
-    @NotYetImplemented
-    void testPropertyWithMultipleSetters2() {
-        super.testPropertyWithMultipleSetters2()
-    }
-
-    @NotYetImplemented
-    void testPropertyWithMultipleSetters3() {
-        super.testPropertyWithMultipleSetters3()
-    }
-
     // GROOVY-5561
     void testShouldNotThrowAccessForbidden() {
         assertScript '''


[groovy] 01/02: GROOVY-8050, GROOVY-10414: STC: non-static outer class property setter

Posted by em...@apache.org.
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 <er...@thomsonreuters.com>
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 {