Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-9106

@CompileStatic and @PackageScope support for inner classes and package peers

Attach filesAttach ScreenshotVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 3.0.0-alpha-4, 2.5.6
    • 3.0.0-beta-3, 2.5.13
    • 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

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            daniel_sun Daniel Sun
            emilles Eric Milles
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 0.5h
                0.5h

                Slack

                  Issue deployment