[ https://issues.apache.org/jira/browse/GROOVY-9106?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Eric Milles updated GROOVY-9106: -------------------------------- 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, implements, etc. 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: {code:groovy} import groovy.transform.* @CompileStatic class Main { @PackageScope static final String VALUE = 'value' static main(args) { print VALUE } } {code} Should print "value" when compiled and executed: {code:groovy} 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() } } {code} Should print "value" when compiled and executed: {code:groovy} 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() } } {code} Should print "value" when compiled and executed: {code:groovy} 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 } } {code} Should print "value" when compiled and executed: {code:groovy} 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 } } {code} Other should have STC error at compile time: {code:groovy} 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 } } {code} TODO: add cases for closures/lambdas Other should have STC error at compile time: {code:groovy} 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 } } {code} Test should have STC error at compile time: {code:groovy} 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 } } {code} was: 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 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, implements, etc. 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: {code:groovy} import groovy.transform.* @CompileStatic class Main { @PackageScope static final String VALUE = 'value' static main(args) { print VALUE } } {code} Should print "value" when compiled and executed: {code:groovy} 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() } } {code} Should print "value" when compiled and executed: {code:groovy} 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() } } {code} Should print "value" when compiled and executed: {code:groovy} 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 } } {code} Should print "value" when compiled and executed: {code:groovy} 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 } } {code} Other should have STC error at compile time: {code:groovy} 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 } } {code} TODO: add cases for closures/lambdas Other should have STC error at compile time: {code:groovy} 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 } } {code} Test should have STC error at compile time: {code:groovy} 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 } } {code} > @CompileStatic and @PackageScope support for inner classes and package peers > ---------------------------------------------------------------------------- > > Key: GROOVY-9106 > URL: https://issues.apache.org/jira/browse/GROOVY-9106 > Project: Groovy > Issue Type: Bug > Affects Versions: 3.0.0-alpha-4, 2.5.6 > Reporter: Eric Milles > Priority: Minor > > 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, implements, etc. > 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: > {code:groovy} > import groovy.transform.* > @CompileStatic class Main { > @PackageScope static final String VALUE = 'value' > static main(args) { > print VALUE > } > } > {code} > Should print "value" when compiled and executed: > {code:groovy} > 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() > } > } > {code} > Should print "value" when compiled and executed: > {code:groovy} > 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() > } > } > {code} > Should print "value" when compiled and executed: > {code:groovy} > 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 > } > } > {code} > Should print "value" when compiled and executed: > {code:groovy} > 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 > } > } > {code} > Other should have STC error at compile time: > {code:groovy} > 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 > } > } > {code} > TODO: add cases for closures/lambdas > Other should have STC error at compile time: > {code:groovy} > 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 > } > } > {code} > Test should have STC error at compile time: > {code:groovy} > 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 > } > } > {code} -- This message was sent by Atlassian JIRA (v7.6.3#76005)