[ 
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)

Reply via email to