[
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 class within the same package
- closure 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 @PS member through {{C}}.
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}
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
- closure 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 @PS member through {{C}}.
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
}
}
{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}
{code:java}
@Test // https://issues.apache.org/jira/browse/GROOVY-9093
public void testCompileStatic9043_subToPackage2() {
//@formatter:off
String[] sources = {
"p/Main.groovy",
"package p\n" +
"class Main {\n" +
" @groovy.transform.PackageScope static final String VALUE =
'value'\n" +
"}\n",
"q/More.groovy",
"package q\n" +
"@groovy.transform.CompileStatic\n" +
"class More extends p.Main {\n" +
" void meth() {\n" + // non-static
" print VALUE\n" +
" }\n" +
"}\n",
};
//@formatter:on
runNegativeTest(sources,
"----------\n" +
"1. ERROR in q\\More.groovy (at line 5)\n" +
"\tprint VALUE\n" +
"\t ^^^^^\n" +
"Groovy:Access to q.More#VALUE is forbidden @ line 5, column 11.\n"
+
"----------\n");
}
@Test
public void testCompileStatic9043_subToPackage3() {
//@formatter:off
String[] sources = {
"p/Main.groovy",
"package p\n" +
"class Main {\n" +
" @groovy.transform.PackageScope static final String VALUE =
'value'\n" +
"}\n",
"p/More.groovy",
"package p\n" +
"class More extends Main {}\n",
"q/Test.groovy",
"package q\n" +
"@groovy.transform.CompileStatic\n" +
"class Test {\n" +
" void meth() {\n" +
" p.More.VALUE\n" +
" }\n" +
"}\n",
};
//@formatter:on
runNegativeTest(sources,
"----------\n" +
"1. ERROR in q\\Test.groovy (at line 5)\n" +
"\tp.More.VALUE\n" +
"\t^^^^^^\n" +
"Groovy:Access to p.More#VALUE is forbidden @ line 5, column 5.\n" +
"----------\n");
}
{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 class within the same package
> - closure 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 @PS member through
> {{C}}.
> 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}
> 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)