AST model for 'var' variables should more closely adhere to the source code

XMLWordPrintable

    • Type: CSR
    • Resolution: Unresolved
    • Priority: P4
    • tbd
    • Component/s: tools
    • None
    • behavioral
    • low
    • Hide
      This change is incompatible for the API clients: the variable's type can be `null` or the newly-introduce `VarTypeTree` after this change. Relevant clients will need to be updated.

      A trial update of a large(r) client, NetBeans, has been done, and the amount of changes was in line with usual AST shape adjustments.
      Show
      This change is incompatible for the API clients: the variable's type can be `null` or the newly-introduce `VarTypeTree` after this change. Relevant clients will need to be updated. A trial update of a large(r) client, NetBeans, has been done, and the amount of changes was in line with usual AST shape adjustments.
    • Java API
    • JDK

      Summary

      Currently the javac's AST for a variable with inferred type (i.e. a variable whose type in the source code is var or elided completely) is weird. This is a proposal to make the AST model more closely adhere to what is written in the source code.

      Problem

      Having variable v declared with an inferred type, e.g. using one of these cases:

      var v = List.of("");
      for (var v : List.of("")) {}
      Consumer<String> c = v -> {}
      

      the javac's AST model is weird: after parsing, the variable's type is null, and later, it is changed to a full AST corresponding to the inferred type - e.g. List<String>. I.e. the type is filled in the AST as a synthetic tree.

      This is problematic for two groups of reasons: it is difficult to work with the AST for the API clients; the observable compiler behavior is unorthogonal in some rare cases.

      Working with the AST

      At least two problem when working with the AST:

      • the code analyzing the AST using the Trees API does not have good means to detect the synthetic tree, except possibly checking positions of the trees
      • the positions (esp. the end position) of the synthetic tree is missing

      Observable compiler behavior

      Consider:

      package p1;
      
      public class API {
          public static PackagePrivate get() { return null; }
          public static Iterable<PackagePrivate> getIterable() { return null; }
      }
      package p1;
      
      class PackagePrivate {}
      

      And then:

      $ cat VarUse.java 
      import p1.API;
      
      void main() {
          var v = API.get();
      }
      $ javac -d out p1/API.java p1/PackagePrivate.java VarUse.java 
      $ cat ForEachUse.java 
      import p1.API;
      
      void main() {
          for (var v : API.getIterable()) {}
      }
      $ javac -d out p1/API.java p1/PackagePrivate.java ForEachUse.java
      ForEachUse.java:4: error: PackagePrivate is not public in p1; cannot be accessed from outside package
          for (var v : API.getIterable()) {}
               ^
      1 error
      

      I.e. when the inferred type is the same in both cases, and it is inaccessible at the point where var is used. But the compile-time error is reported in one case, but not in the other.

      Solution

      The AST will be made more stable and will more closely adhere to what is written in the source code. Namely:

      • if there is no type in the source code, the variable's type in the AST will be null at all points visible from the API,
      • if the variable is declared using var, the variable's type in the AST will be a newly-introduced VarTypeTree, with proper start and end positions
      • otherwise, the variable's type will be the type what is in the source code, as is currently.

      The compiler's behavior w.r.t. inferred types will be made consistent. In the current prototype, no errors are produced for the inaccessible types, but that can be changed to always produce the errors if desired.

      Specification

      Preliminary apidiff is attached as vartype_ast.preliminary.00.zip and is also available here: https://cr.openjdk.org/~jlahoda/8268850/vartype_ast.preliminary.00/

            Assignee:
            Jan Lahoda
            Reporter:
            Liam Miller-Cushon
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated: