Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8056066

JEP 216: Process Import Statements Correctly

    Details

    • Author:
      Jan Lahoda
    • JEP Type:
      Feature
    • Exposure:
      Open
    • Subcomponent:
    • Scope:
      Implementation
    • Discussion:
      compiler dash dev at openjdk dot java dot net
    • Effort:
      S
    • Duration:
      M
    • Alert Status:
       Green
    • JEP Number:
      216

      Description

      Summary

      Fix javac to properly accept and reject programs regardless of the order of import statements and extends and implements clauses.

      Motivation

      In some cases javac will accept source code with a certain order of imports and reject the same source code with just the imports reordered (e.g., JDK-7177813). That is wrong and confusing.

      Description

      javac uses several stages when compiling classes. Considering import handling, the two important stages are:

      • Type resolution, which looks through the provided AST looking for class and interface declaration, and

      • Member resolution, which includes:

        • (1a) If T is toplevel, imports in the source file defining T are processed and imported members added in T's scope
        • (1b) If T is nested, resolution of the class directly enclosing T (if any)
        • (2) extends/implements clauses of T are type-checked
        • (3) Type variables of T are type-checked

      The above stages are part of javac's process of resolution of classes, which includes determining a class's supertypes, type variables, and members.

      To see this in process in action, consider this code:

      package P;
      
      import static P.Outer.Nested.*;
      import P.Q.*;
      
      public class Outer {
          public static class Nested implements I {
          }
      }
      
      package P.Q;
      public interface I {
      }

      During the type-resolution phase it is recognized that there exist types P.Outer, P.Outer.Nested, and P.Q.I. Then, if the P.Outer class is to be analyzed, the member resolution phase works like this:

      1.Resolution of P.Outer starts
      2.Processing of the import static P.Outer.Nested.*; starts, per 1a, which means the members of P.Outer.Nestedand its transitive supertypes are looked up.
      3.Resolution of the P.Outer.Nested class starts (the static imports can also import inherited types)
      4.Triggers resolution of P.Outer, which is skipped as it is already in progress
      5.Type checking of I(the implements clause) runs, but Icannot be resolved since it is not in the scope yet.
      6.Resolution of import P.Q.*starts, which takes all member types of P.Q(including the interface I) and imports them into the current file's scope
      7.Resolution of P.Outerand other classes continues

      If the imports are swapped then step 6 happens before step 5 and so I is found during step 5.

      The above is not the only problem related to import handling. The other known problem is that the bounds of a class's type parameters may validly refer to possible inner classes of their declaring class. In some cases, this currently causes unresolvable cycles, for example:

      package P;
      
      import static P.Outer.Nested.*;
      
      public class Outer {
          public static class Nested<T extends I> {
              static class I { }
          }
      }

      The envisioned solution to this problem is to split the existing first phase of javac's member resolution into three: The first will analyze the enclosing file's imports, the second will only build the class/interface hierarchy, without any type parameters, annotations, etc., and the third will properly analyze the class headers, including type parameters.

      It is expected that this change will allow javac to accept programs that are currently rejected but not reject ones that are currently accepted.

        Issue Links

          Activity

          Hide
          dnsimon Douglas Simon added a comment -
          Is there any particular reason this bug report is confidential?
          Show
          dnsimon Douglas Simon added a comment - Is there any particular reason this bug report is confidential?
          Hide
          dnsimon Douglas Simon added a comment -
          Ok, thanks for the clarification.
          Show
          dnsimon Douglas Simon added a comment - Ok, thanks for the clarification.
          Hide
          jjg Jonathan Gibbons added a comment -
          The phrasing of this is a little clumsy: "It is expected that this change will allow javac to accept programs that are currently not rejected, not reject ones that are currently accepted."

          At a minimum, an "and" in the middle would help. But then, we're left with "It is expected that this change will allow javac to accept programs that are currently not rejected" What is the difference between "accept" and "currently not rejected"?

          I think you are trying to say that the change will allow javac to accept more programs then before, not less, so maybe "not" is a typo for "now", as in "It is expected that this change will allow javac to accept programs that are currently now rejected, not reject ones that are currently accepted."
          Show
          jjg Jonathan Gibbons added a comment - The phrasing of this is a little clumsy: "It is expected that this change will allow javac to accept programs that are currently not rejected, not reject ones that are currently accepted." At a minimum, an "and" in the middle would help. But then, we're left with "It is expected that this change will allow javac to accept programs that are currently not rejected" What is the difference between "accept" and "currently not rejected"? I think you are trying to say that the change will allow javac to accept more programs then before, not less, so maybe "not" is a typo for "now", as in "It is expected that this change will allow javac to accept programs that are currently now rejected, not reject ones that are currently accepted."
          Hide
          dnsimon Douglas Simon added a comment -
          in the goals section, instead of "accepts and rejects" I think you just want "accepts".
          Show
          dnsimon Douglas Simon added a comment - in the goals section, instead of "accepts and rejects" I think you just want "accepts".
          Hide
          skannan Sowmya Kannan (Inactive) added a comment -
          No documentation impact.
          Show
          skannan Sowmya Kannan (Inactive) added a comment - No documentation impact.

            People

            • Assignee:
              jlahoda Jan Lahoda
              Reporter:
              jlahoda Jan Lahoda
              Owner:
              Jan Lahoda
              Reviewed By:
              Alex Buckley, Brian Goetz, Jonathan Gibbons, Maurizio Cimadamore
              Endorsed By:
              Brian Goetz
            • Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

              • Due:
                Created:
                Updated:
                Resolved:
                Integration Due: