Scala Programming Language
  1. Scala Programming Language
  2. SI-4983

Missing entries in InnerClasses attribute of class files

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: Scala 2.9.2
    • Fix Version/s: Scala 2.10.0
    • Component/s: Misc Compiler
    • Labels:
      None

      Description

      Compile following code:

      class X {
        class Y {
          class Z {
            class Z2
          }
        }
      }
      

      and check InnerClasses attribute for Z2, it'll print:

        InnerClass: 
         public #32= #29 of #31; //Z=class X$Y$Z of class X$Y
         public #33= #10 of #29; //Z2=class X$Y$Z$Z2 of class X$Y$Z
      

      which is incomplete because entry for Y (being inner class of X) is missing.

      For definition of InnerClass attribute check JVM spec. 4.8.5.

      Also, checked that Java compiler generates complete table in corresponding case.

        Activity

        Hide
        Commit Message Bot added a comment -

        (grek in r25639) Fix various InnerClasses bugs.

        This commit fixes two major problems:

        1. InnerClasses table missed entries
        that would close the chain between
        nested and top-level class.

        2. In some situations, classes
        corresponding to objects would be
        not be reported in the InnerClasses
        table.

        For details it's the best to check SI-4819, SI-4820 and
        SI-4983.

        First problem mentioned above was straightforward to
        fix so I won't be going into details.

        The second one deserves more attention. From now, classes
        corresponding to objects are properly reported as inner
        classes. Also, members (classes, objects) of objects are
        reported as inner classes of classes corresponding to
        objects.

        There's one caveat though: top level objects get two
        classes (regular and mirror). Members of top-level
        objects are declared as inner classes of mirror class
        and not regular one. The reason for that is to allow
        importing them from Java. For example:

        object A

        { class B }

        will be compiled into following classes: A, A$, A$B.
        If we declared A$B as inner class of A$ (regular class
        for objects) then it would be impossible to import
        B using "import A.B" or "import A$.B" constructs. The
        reason for that is that Java compiler seems to blindly
        put dollars instead of looking at InnerClasses attribute.

        Since non-top-level objects don't have a mirror class
        it's impossible to use the same solution. Thus, in case
        like this:

        object A { object B

        { class C }

        }

        it's impossible to import C from Java. That's the tradeoff
        for fixing other (more serious) problems. It's never been
        possible to do that in a clean way so we are not making
        situation worse.

        As a nice consequence of this change, we get better way to
        refer to inner members of top-level objects. It's been
        reflected in one of test-cases that is updated by this
        change.

        Fixes SI-4789 SI-4819 SI-4820 SI-4983 and possibly some
        other tickets related to reflection.

        Review by extempore, dragos.

        Show
        Commit Message Bot added a comment - (grek in r25639 ) Fix various InnerClasses bugs. This commit fixes two major problems: 1. InnerClasses table missed entries that would close the chain between nested and top-level class. 2. In some situations, classes corresponding to objects would be not be reported in the InnerClasses table. For details it's the best to check SI-4819 , SI-4820 and SI-4983 . First problem mentioned above was straightforward to fix so I won't be going into details. The second one deserves more attention. From now, classes corresponding to objects are properly reported as inner classes. Also, members (classes, objects) of objects are reported as inner classes of classes corresponding to objects. There's one caveat though: top level objects get two classes (regular and mirror). Members of top-level objects are declared as inner classes of mirror class and not regular one. The reason for that is to allow importing them from Java. For example: object A { class B } will be compiled into following classes: A, A$, A$B. If we declared A$B as inner class of A$ (regular class for objects) then it would be impossible to import B using "import A.B" or "import A$.B" constructs. The reason for that is that Java compiler seems to blindly put dollars instead of looking at InnerClasses attribute. Since non-top-level objects don't have a mirror class it's impossible to use the same solution. Thus, in case like this: object A { object B { class C } } it's impossible to import C from Java. That's the tradeoff for fixing other (more serious) problems. It's never been possible to do that in a clean way so we are not making situation worse. As a nice consequence of this change, we get better way to refer to inner members of top-level objects. It's been reflected in one of test-cases that is updated by this change. Fixes SI-4789 SI-4819 SI-4820 SI-4983 and possibly some other tickets related to reflection. Review by extempore, dragos.
        Hide
        Grzegorz Kossakowski added a comment -

        Fixed in r25639.

        Show
        Grzegorz Kossakowski added a comment - Fixed in r25639.

          People

          • Assignee:
            Grzegorz Kossakowski
            Reporter:
            Grzegorz Kossakowski
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development