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/07/11 17:27:23 UTC

[groovy] branch master updated: GROOVY-8145: static import field must be accessible

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 3785147d2f GROOVY-8145: static import field must be accessible
3785147d2f is described below

commit 3785147d2f7ae43a994f6949eb4a7fd96b79c66c
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Jul 11 12:01:06 2023 -0500

    GROOVY-8145: static import field must be accessible
---
 .../groovy/control/StaticImportVisitor.java        | 40 +++++++++++----
 src/test/groovy/StaticImportTest.groovy            | 59 +++++++++++++++++-----
 2 files changed, 76 insertions(+), 23 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index ef71676a2a..99bfaf6a83 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -53,6 +53,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
 
+import static java.lang.reflect.Modifier.isPrivate;
+import static java.lang.reflect.Modifier.isProtected;
+import static java.lang.reflect.Modifier.isPublic;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.getField;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.getPropNameForAccessor;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticMethod;
@@ -60,6 +63,7 @@ import static org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticProper
 import static org.apache.groovy.ast.tools.ClassNodeUtils.hasStaticProperty;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.isInnerClass;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.isValidAccessorName;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.samePackageName;
 import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression;
 import static org.apache.groovy.ast.tools.ExpressionUtils.isThisOrSuper;
 import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants;
@@ -511,14 +515,6 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
         return null;
     }
 
-    private static String prefix(String name) {
-        return name.startsWith("is") ? "is" : name.substring(0, 3);
-    }
-
-    private String getAccessorName(String name) {
-        return inLeftExpression ? getSetterName(name) : getGetterName(name);
-    }
-
     private Expression findStaticPropertyAccessorByFullName(ClassNode staticImportType, String accessorName) {
         Expression argumentList = inLeftExpression ? new ArgumentListExpression(EmptyExpression.INSTANCE) : ArgumentListExpression.EMPTY_ARGUMENTS;
         Expression accessorExpr = findStaticMethod(staticImportType, accessorName, argumentList);
@@ -557,9 +553,10 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
         Expression expression = findStaticPropertyAccessor(staticImportType, variableName);
         if (expression == null) {
             if (staticImportType.isPrimaryClassNode() || staticImportType.isResolved()) {
-                FieldNode field = getField(staticImportType, variableName);
-                if (field != null && field.isStatic())
+                FieldNode field = getField(staticImportType, variableName, FieldNode::isStatic);
+                if (field != null && isMemberAccessible(field.getDeclaringClass(), field.getModifiers())) { // GROOVY-8145
                     expression = newStaticPropertyX(staticImportType, variableName);
+                }
             }
         }
         return expression;
@@ -602,6 +599,29 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
         return new PropertyExpression(new ClassExpression(type.getPlainNodeReference()), name);
     }
 
+    private boolean isMemberAccessible(ClassNode declaringClass, int modifiers) {
+        if (isPublic(modifiers)
+                || currentClass.equals(declaringClass)
+                || currentClass.getOuterClasses().contains(declaringClass)) {
+            return true;
+        }
+        if (isProtected(modifiers) && currentClass.isDerivedFrom(declaringClass)) {
+            return true;
+        }
+        if (!isPrivate(modifiers) && samePackageName(currentClass, declaringClass)) {
+            return true;
+        }
+        return false;
+    }
+
+    private String getAccessorName(String name) {
+        return inLeftExpression ? getSetterName(name) : getGetterName(name);
+    }
+
+    private static String prefix(String name) {
+        return name.startsWith("is") ? "is" : name.substring(0, 3);
+    }
+
     @Override
     protected SourceUnit getSourceUnit() {
         return sourceUnit;
diff --git a/src/test/groovy/StaticImportTest.groovy b/src/test/groovy/StaticImportTest.groovy
index 9529dcd29b..d0465911e0 100644
--- a/src/test/groovy/StaticImportTest.groovy
+++ b/src/test/groovy/StaticImportTest.groovy
@@ -18,25 +18,24 @@
  */
 package groovy
 
-import static java.lang.Boolean.FALSE as F
-import static java.text.DateFormat.MEDIUM as M
-import static java.util.regex.Pattern.*
-import static java.text.DateFormat.MEDIUM
-import static junit.framework.Assert.format
-import static junit.framework.Assert.assertEquals
-import static groovy.StaticImportTarget.x
-import static groovy.StaticImportTarget.z // do not remove
-import static java.lang.Math.*
-import static java.util.Calendar.getInstance as now
 import static groovy.API.*
-import static groovy.StaticImportChild.*
+import static groovy.Container5087.*
+import static groovy.Foo4964.*
 import static groovy.Outer1.*
 import static groovy.Outer2.Inner2
 import static groovy.Outer2.Inner2 as InnerAlias2
+import static groovy.StaticImportChild.*
+import static groovy.StaticImportTarget.x
+import static groovy.StaticImportTarget.z
+import static java.lang.Boolean.FALSE as F
+import static java.lang.Math.*
+import static java.text.DateFormat.MEDIUM
+import static java.text.DateFormat.MEDIUM as M
+import static java.util.Calendar.getInstance as now
 import static java.util.jar.Attributes.*
 import static java.util.jar.Attributes.Name as AttrName
-import static groovy.Container5087.*
-import static Foo4964.*
+import static java.util.regex.Pattern.*
+import static junit.framework.Assert.format
 
 import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM
 
@@ -452,6 +451,40 @@ final class StaticImportTest extends groovy.test.GroovyTestCase {
         '''
     }
 
+    // GROOVY-8145
+    void testStaticImportAnyVsGeneratedField() {
+        for (what in ['*','log']) {
+            assertScript """
+                import static Foo.$what
+                class Foo {
+                    private static log = [info: Closure.IDENTITY]
+                }
+                @groovy.util.logging.Log
+                class Bar {
+                    def test() {
+                        log.info('bar')
+                    }
+                }
+                assert new Bar().test() == null // return from logger
+            """
+        }
+        for (which in ['public','protected'/*,'@groovy.transform.PackageScope'*/]) {
+            assertScript """
+                import static Foo.*
+                class Foo {
+                    $which static log = [info: Closure.IDENTITY]
+                }
+                @groovy.util.logging.Log
+                class Bar {
+                    def test() {
+                        log.info('bar')
+                    }
+                }
+                assert new Bar().test() == 'bar'
+            """
+        }
+    }
+
     void testConstructorArgsAliasing() {
         // not recommended style to use statics in constructors but supported
         assertScript '''