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 2024/05/08 16:23:40 UTC

(groovy) branch master updated: GROOVY-11223: STC: create setter access error

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 8ba8e8264f GROOVY-11223: STC: create setter access error
8ba8e8264f is described below

commit 8ba8e8264fc3edeb9c70b52937edb97b0246a5d5
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed May 8 11:05:31 2024 -0500

    GROOVY-11223: STC: create setter access error
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 17 +++++++++++++--
 .../stc/FieldsAndPropertiesSTCTest.groovy          | 23 +++++++++++++++++++++
 .../sc/FieldsAndPropertiesStaticCompileTest.groovy | 24 ++++++++++++++++++++++
 3 files changed, 62 insertions(+), 2 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 698d9bcd26..9e03d1e15b 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1143,8 +1143,21 @@ out:    if ((samParameterTypes.length == 1 && isOrImplements(samParameterTypes[0
             }
             return false;
         } else {
-            ClassNode firstSetterType = setterType.apply(setterInfo.setters.get(0));
-            addAssignmentError(firstSetterType, getType(valueExpression), expression);
+            List<MethodNode> visibleSetters = filterMethodsByVisibility(setterInfo.setters, typeCheckingContext.getEnclosingClassNode());
+            if (visibleSetters.isEmpty()) {
+                String message; // GROOVY-11223
+                if (setterInfo.setters.size() == 1) {
+                    message = String.format("Cannot access method: %2$s of class: %1$s",
+                        prettyPrintTypeName(setterInfo.setters.get(0).getDeclaringClass()),
+                        toMethodParametersString(setterInfo.name, extractTypesFromParameters(setterInfo.setters.get(0).getParameters())));
+                } else {
+                    message = "Cannot access methods: " + prettyPrintMethodList(setterInfo.setters);
+                }
+                addStaticTypeError(message, leftExpression);
+            } else {
+                ClassNode[] tergetTypes = visibleSetters.stream().map(setterType).toArray(ClassNode[]::new);
+                addAssignmentError(tergetTypes.length == 1 ? tergetTypes[0] : new UnionTypeClassNode(tergetTypes), getType(valueExpression), expression);
+            }
             return true;
         }
     }
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index 92df8ba54a..8a53bb662b 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -822,6 +822,29 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-11223
+    void testMapPropertyAccess10() {
+        assertScript """
+            def map = new ${MapType.name}()
+            map.foo = 11 // public setter
+            assert map.foo == 11
+            assert map.getFoo() == 11
+            assert map.get('foo') == null
+        """
+        assertScript """
+            def map = new ${MapType.name}()
+            map.bar = 22 // protected setter
+            assert map.bar == null
+            assert map.@bar == 2
+        """
+        assertScript """
+            def map = new ${MapType.name}()
+            map.baz = 33 // package-private setter
+            assert map.baz == null
+            assert map.@baz == 3
+        """
+    }
+
     void testTypeCheckerDoesNotThinkPropertyIsReadOnly() {
         assertScript '''
             // a base class defining a read-only property
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 3b50ef7948..3b6236cf77 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -934,4 +934,28 @@ final class FieldsAndPropertiesStaticCompileTest extends FieldsAndPropertiesSTCT
             test(new C())
         '''
     }
+
+    // GROOVY-11223
+    @Override
+    void testMapPropertyAccess10() {
+        assertScript """
+            def map = new ${MapType.name}()
+            map.foo = 11 // public setter
+            assert map.foo == 11
+            assert map.getFoo() == 11
+            assert map.get('foo') == null
+        """
+        shouldFailWithMessages """
+            def map = new ${MapType.name}()
+            map.bar = 22 // protected setter
+        """,
+        "Method setBar is protected in ${MapType.name}"
+        /*
+        shouldFailWithMessages """
+            def map = new ${MapType.name}()
+            map.baz = 33 // package-private setter
+        """,
+        "Method setBaz is package-private in ${MapType.name}"
+        */
+    }
 }