[ 
https://issues.apache.org/jira/browse/GROOVY-12537?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18132733#comment-18132733
 ] 

ASF GitHub Bot commented on GROOVY-12537:
-----------------------------------------

paulk-asert opened a new pull request, #3052:
URL: https://github.com/apache/groovy/pull/3052

   …private member type is wrongly rejected as inaccessible
   
   hasAccessToClass applied the member-access rule with the enclosing type as 
the receiver. For a precompiled member type the enclosing type is not known, so 
a protected member type was checked against itself, and no subclass derives 
from it. Protected access was also checked against the accessing class alone 
rather than the whole body of the subclass, and private access stopped at one 
level of nesting.
   
   A member type is now accessible from anywhere in the same nest when private, 
and from the same package or anywhere in the body of a subclass of its 
enclosing type when protected. For a precompiled member type only 
package-private access is enforced.




> STC: field access through a protected or doubly-nested private member type is 
> wrongly rejected as inaccessible
> --------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12537
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12537
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static Type Checker
>    Affects Versions: 6.0.0
>            Reporter: Paul King
>            Assignee: Paul King
>            Priority: Major
>
> Description:
> Since GROOVY-12314, the type checker rejects a field access when the type 
> that qualifies it is not accessible from the calling class. The accessibility 
> check gets member types wrong in two cases, so valid code that compiled 
> before now fails under @CompileStatic and @TypeChecked:
> 1. A protected member type of a class compiled in an earlier step, used from 
> a subclass in another package:
> {code:groovy}
> // p/Base.groovy, compiled first
> package p
> class Base {
>     protected static class Prot { public static String F = 'f' }
> }
> {code}
> {code:groovy}
> // q/Sub.groovy, compiled with p.Base on the classpath
> package q
> @groovy.transform.CompileStatic
> class Sub extends p.Base {
>     static String run() { p.Base.Prot.F }
> }
> {code}
> {noformat}
> [Static type checking] - Cannot access field: F of class: p.Base$Prot from 
> class: q.Sub
> {noformat}
> 2. A private member type nested inside another member type, used from the 
> top-level class:
> {code:groovy}
> package q
> @groovy.transform.CompileStatic
> class Outer {
>     private static class A {
>         private static class B { public static String F = 'f' }
>     }
>     static String run() { A.B.F }
> }
> {code}
> {noformat}
> [Static type checking] - Cannot access field: F of class: q.Outer$A$B from 
> class: q.Outer
> {noformat}
> Java accepts both (JLS 6.6.1, 6.6.2), and both compiled and ran before 
> GROOVY-12314.
> Cause: StaticTypeCheckingVisitor#hasAccessToClass checks a member type's 
> modifiers with the rule used for members, using the enclosing type as the 
> receiver:
> * For a type compiled in an earlier step, ClassNode#getOuterClass() is null, 
> so the enclosing type is unknown. A protected member type is then checked 
> against itself, and no subclass derives from it.
> * Protected access is checked against the calling class alone. JLS 6.6.2 
> allows it anywhere in the body of the subclass, including its nested classes, 
> closures and anonymous classes.
> * Private access only allows the immediately enclosing type and classes 
> nested inside the private type. It should allow anything in the same nest, as 
> the existing inSameNest check does.
> Proposed fix: when the enclosing type is unknown, enforce only 
> package-private access, so the check rejects only what it can actually 
> decide. Otherwise, check the enclosing type's accessibility first, then: 
> public => accessible; private => same nest; same package as the enclosing 
> type => accessible; protected => the calling class or one of its enclosing 
> classes derives from the enclosing type. Every change here makes the rule 
> more permissive, so nothing the check accepts today will be rejected. The 
> GROOVY-12310 case (a package-private nested enum in a Java class) is still 
> rejected.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to