You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2019/04/23 10:19:14 UTC

[groovy] branch master updated: GROOVY-9043: Access to package-scoped static field is forbidden for inner class in static compilation mode

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

paulk 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 d8731a7  GROOVY-9043: Access to package-scoped static field is forbidden for inner class in static compilation mode
d8731a7 is described below

commit d8731a7f9ed0f6d9e6c123f371ef0aca1f5a231f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Apr 23 20:19:03 2019 +1000

    GROOVY-9043: Access to package-scoped static field is forbidden for inner class in static compilation mode
---
 .../classgen/asm/sc/StaticTypesCallSiteWriter.java | 22 +++++++++++++---------
 .../transform/PackageScopeTransformTest.groovy     | 21 +++++++++++++++++++++
 2 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
index 1bd6449..23707ef 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
@@ -630,21 +630,25 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
         return false;
     }
 
-    private static boolean isDirectAccessAllowed(FieldNode a, ClassNode receiver, boolean isSamePackage) {
-        ClassNode declaringClass = a.getDeclaringClass().redirect();
+    private static boolean isDirectAccessAllowed(FieldNode field, ClassNode receiver, boolean isSamePackage) {
+        ClassNode declaringClass = field.getDeclaringClass().redirect();
         ClassNode receiverType = receiver.redirect();
 
-        // first, direct access from within the class or inner class nodes
+        // first, direct access from within the class
         if (declaringClass.equals(receiverType)) return true;
-        if (receiverType instanceof InnerClassNode) {
-            while (receiverType instanceof InnerClassNode) {
-                if (declaringClass.equals(receiverType)) return true;
-                receiverType = receiverType.getOuterClass();
+        if (field.isPrivate()) return false;
+
+        // now, inner class node access to outer class fields
+        receiverType = receiverType.getOuterClass();
+        while (receiverType != null) {
+            if (declaringClass.equals(receiverType)) {
+                return true;
             }
+            receiverType = receiverType.getOuterClass();
         }
 
-        // no getter
-        return a.isPublic() || (a.isProtected() && isSamePackage);
+        // finally public and inherited
+        return field.isPublic() || isSamePackage;
     }
 
     @Override
diff --git a/src/test/org/codehaus/groovy/transform/PackageScopeTransformTest.groovy b/src/test/org/codehaus/groovy/transform/PackageScopeTransformTest.groovy
index 4e4350e..37f8f4f 100644
--- a/src/test/org/codehaus/groovy/transform/PackageScopeTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/PackageScopeTransformTest.groovy
@@ -21,6 +21,27 @@ package org.codehaus.groovy.transform
 import java.lang.reflect.Modifier
 
 class PackageScopeTransformTest extends GroovyShellTestCase {
+    // GROOVY-9043
+    void testPackagePrivateAccessFromInnerClassCS() {
+        assertScript '''
+            import groovy.transform.CompileStatic
+            import groovy.transform.PackageScope
+            @CompileStatic
+            class Test {
+                @PackageScope
+                static final String S = 'S'
+                static private final String T = 'T'
+                static protected final String U = 'U'
+                static class Inner {
+                    String method() {
+                        S + T + U
+                    }
+                }
+            }
+
+            assert new Test.Inner().method() == 'STU'
+        '''
+    }
 
     void testImmutable() {
         def objects = evaluate("""