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 2023/03/25 02:10:36 UTC

[groovy] branch GROOVY_2_5_X updated: GROOVY-10981: try variable as property for field not from enclosing type

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


The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
     new 654f049f22 GROOVY-10981: try variable as property for field not from enclosing type
654f049f22 is described below

commit 654f049f22c0a2ca626d61bb2374edc4f970134c
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Mar 24 18:37:15 2023 -0500

    GROOVY-10981: try variable as property for field not from enclosing type
    
    2_5_X backport
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 34 +++++++++-------------
 .../typing/TypeCheckingExtensionSpecTest.groovy    |  2 +-
 .../stc/FieldsAndPropertiesSTCTest.groovy          | 27 ++++++++++++++++-
 3 files changed, 41 insertions(+), 22 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 9a0b6050a7..35cb4436ea 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -596,17 +596,14 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                     Expression leftExpression = enclosingBinaryExpression.getLeftExpression();
                     Expression rightExpression = enclosingBinaryExpression.getRightExpression();
                     SetterInfo setterInfo = removeSetterInfo(leftExpression);
-                    if (setterInfo != null) {
-                        if (!ensureValidSetter(vexp, leftExpression, rightExpression, setterInfo)) {
-                            return;
-                        }
-
+                    if (setterInfo != null && !ensureValidSetter(vexp, leftExpression, rightExpression, setterInfo)) {
+                        return;
                     }
                 }
             }
         } else if (accessedVariable instanceof FieldNode) {
             FieldNode fieldNode = (FieldNode) accessedVariable;
-
+            ClassNode inferredType = getInferredTypeFromTempInfo(vexp, null);
             if (enclosingClosure != null) {
                 // GROOVY-8562
                 // when vexp has the same name as a property of the owner,
@@ -617,9 +614,8 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                     if (vexp.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER) == null) {
                         ClassNode owner = (ClassNode) vexp.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER);
                         if (owner != null) {
-                            FieldNode veFieldNode = owner.getField(name);
-                            if (veFieldNode != null) {
-                                fieldNode = veFieldNode;
+                            fieldNode = owner.getField(name);
+                            if (fieldNode != null) {
                                 boolean lhsOfEnclosingAssignment = isLHSOfEnclosingAssignment(vexp);
                                 vexp.setAccessedVariable(fieldNode);
                                 checkOrMarkPrivateAccess(vexp, fieldNode, lhsOfEnclosingAssignment);
@@ -627,15 +623,12 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                         }
                     }
                 }
-            } else {
+            } else if (((FieldNode) accessedVariable).getDeclaringClass() == typeCheckingContext.getEnclosingClassNode() || !tryVariableExpressionAsProperty(vexp, name)) {
                 checkOrMarkPrivateAccess(vexp, fieldNode, isLHSOfEnclosingAssignment(vexp));
-
-                ClassNode inferredType = getInferredTypeFromTempInfo(vexp, null);
-                if (inferredType != null && !inferredType.getName().equals(ClassHelper.OBJECT) && !inferredType.equals(accessedVariable.getType())) {
-                    vexp.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, inferredType);
-                } else {
-                    storeType(vexp, getType(vexp));
-                }
+                if (inferredType == null) storeType(vexp, getType(vexp));
+            }
+            if (inferredType != null && !inferredType.getName().equals(ClassHelper.OBJECT)) {
+                vexp.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, inferredType);
             }
         }
 
@@ -703,9 +696,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 if (val != null) vexp.putNodeMetaData(key, val);
             }
             vexp.removeNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
-            ClassNode type = pexp.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
-            storeType(vexp, type != null ? type: pexp.getType());
-
+            if (!asBoolean(getTemporaryTypesForExpression(vexp))) {
+                ClassNode type = pexp.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
+                storeType(vexp, type != null ? type : pexp.getType());
+            }
             String receiver = vexp.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
             Boolean dynamic = pexp.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION);
             // GROOVY-7701, GROOVY-7996: correct false assumption made by VariableScopeVisitor
diff --git a/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy b/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy
index a1c2a968ed..5772deee36 100644
--- a/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy
+++ b/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy
@@ -600,7 +600,7 @@ new DelegateTest().delegate()
                     @Delegate
                     private Map<String, Object> delegate = [:]
                     void m(int c) {
-                        if (c > MAX_LINES) {
+                        if (c > A.MAX_LINES) {
                             return
                         }
                     }
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index 7a68af7343..56e218359f 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -262,13 +262,38 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
             class C {
                 String p
             }
+
             def x = new C().getP()
             x = x?.toUpperCase()
         '''
     }
 
-    // GROOVY-9973
+    // GROOVY-10981
     void testGetterForProperty2() {
+        for (mode in ['', 'public', 'private', 'protected', '@groovy.transform.PackageScope']) {
+            assertScript """
+                abstract class A {
+                    $mode Object p = 'field'
+                    CharSequence getP() { 'property' }
+                }
+                class C extends A {
+                    def m() {
+                        final int len = p.length()
+                        if (p instanceof String) {
+                            p.toLowerCase()
+                            p.toUpperCase()
+                        }
+                    }
+                }
+
+                String which = new C().m()
+                assert which == 'PROPERTY'
+            """
+        }
+    }
+
+    // GROOVY-9973
+    void testGetterForProperty3() {
         assertScript '''
             class C {
                 private int f