Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
3.0.0-alpha-4, 2.5.6
-
None
-
None
Description
Follow up to GROOVY-9043. A combination of @CompileStatic and @PackageScope has a number of variants. Not all work as expected at the moment:
A package-private static class member should be accessible to:
- declaring class
- static inner classes
- non-static inner classes
- anonymous inner classes
- any other class within the same package
- closures and lambdas enclosed by any of the above
This should include direct references as well as indirect references. Some class C declared outside the package may extend and should not have access, but package members should retain access to the package-private member through C references. See "indirect static access" below.
A package-private static class member should not be accessible to – should be a STC error:
- any class in another package; this includes extends and implements, static and non-static scopes, direct and indirect references. Although if declaring class is a trait...
TODO: Are the rules any different for non-static package-private members? Except for the fact that they must be accessed from non-static scopes.
Should print "value" when compiled and executed:
import groovy.transform.* @CompileStatic class Main { @PackageScope static final String VALUE = 'value' static main(args) { print VALUE } }
Should print "value" when compiled and executed:
import groovy.transform.* @CompileStatic class Main { @PackageScope static final String VALUE = 'value' class Inner { void meth() { print VALUE } } static main(args) { new Inner(new Main()).meth() } }
Should print "value" when compiled and executed:
import groovy.transform.* @CompileStatic class Main { @PackageScope static final String VALUE = 'value' static class Inner { // Inner is static in this case void meth() { print VALUE } } static main(args) { new Inner(new Main()).meth() } }
Should print "value" when compiled and executed:
import groovy.transform.* @CompileStatic class Main { @PackageScope static final String VALUE = 'value' static main(args) { new Peer().meth() } } @CompileStatic class Peer { void meth() { print Main.VALUE } }
Should print "value" when compiled and executed:
package p import groovy.transform.* class Main { @PackageScope static final String VALUE = 'value' static main(args) { new Peer().meth() } } package q class More extends p.Main {} package p import groovy.transform.* @CompileStatic class Peer { void meth() { print q.More.VALUE // indirect static access } }
TODO: add cases for closures/lambdas
Other should have STC error at compile time:
package p class Main { @groovy.transform.PackageScope static final String VALUE = 'value' } package q @groovy.transform.CompileStatic class Other extends p.Main { static void meth() { print VALUE } }
Other should have STC error at compile time (see GROOVY-9093):
package p class Main { @groovy.transform.PackageScope static final String VALUE = 'value' } package q @groovy.transform.CompileStatic class Other extends p.Main { void meth() { // non-static print VALUE } }
Test should have STC error at compile time:
package p class Main { @groovy.transform.PackageScope static final String VALUE = 'value' } package p class Other extends Main {} package q @groovy.transform.CompileStatic class Test { void meth() { p.Other.VALUE // Main and Other are in same package, Test is not } }
Attachments
Issue Links
- links to