RFR: 8358604: Trees for `var` do not have end positions

Archie Cobbs acobbs at openjdk.org
Mon Jun 9 23:01:35 UTC 2025


The compiler replaces `var` nodes with synthetic tree nodes representing the inferred type. Previously, these new synthetic nodes were not being assigned either starting or ending source code positions.

[JDK-8329951](https://bugs.openjdk.org/browse/JDK-8329951) added starting positions, but not ending positions. This PR adds ending positions, and fixes some related bugs discovered in the research process:

* For a declaration like `final var x`, the fix for [JDK-8329951](https://bugs.openjdk.org/browse/JDK-8329951) was returning a starting position incorrectly pointing to `final` instead of `var`.
* A declaration like `final var x` was correctly starting at `final` for normal declarations, but incorrectly starting at `var` for a lambda parameter declarations.
* `JCVariableDecl.declaredUsingVar()` was incorrectly returning `false` for `var` variable declarations in record deconstruction patterns (thanks to @cushon for reporting this)

Background: When a `var`is parsed or a variable is implicitly typed such as a lambda parameter, `JCVariableDecl.vartype` is set to null until the type can be inferred. This causes various problems when trying to determine the starting position of (a) the declaration's type, when `var` is used, because the source position of the `var` has been lost forever (especially if there are also modifiers); and (b) the starting position of the declaration itself, when there are no modifiers, because normally that's computed from the start position of `JCVariableDecl.vartype`, which is (sometimes) null. Previously there was a field `JCVariableDecl.startPos` which was put there to workaround problem (b), but that workaround was being applied even when there _were_ modifiers, which is wrong. Etc.

This patch attempts to clarify things and includes the following changes:

* Make a `var`'s starting source position properly recoverable from a `JCVariableDecl` even while `vartype` is null.
* Fix the three bugs mentioned above.
* Make `TreeMaker.at()` capable of configuring both the starting and ending position; do some minor cleanup/refactoring.
* Set ending positions for the synthetic tree nodes that replace `var`
* Pretty print `var` as `var` instead of `/*missing*/` (drive-by improvement)
* Add more regression test coverage

-------------

Commit messages:
 - Unbreak two regression tests (one jshell, one javadoc).
 - Refactor to fix more bugs and increase regression test coverage.
 - Fix declaredUsingVar() bug with record patterns like "R(var x)".
 - Merge branch 'master' into JDK-8358604 to fix conflict.
 - Fix bug where "var" end position was off by one.
 - Add a regression test for the glitch leftover by JDK-8329951.
 - Set an ending position for the synthetic tree node that replaces "var".
 - Make TreeMaker.at() also capable of handling ending positions.
 - Make "var" starting source positions recoverable.
 - Pretty print "var" as "var" instead of "/*missing*/".

Changes: https://git.openjdk.org/jdk/pull/25664/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=25664&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8358604
  Stats: 443 lines in 13 files changed: 149 ins; 153 del; 141 mod
  Patch: https://git.openjdk.org/jdk/pull/25664.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/25664/head:pull/25664

PR: https://git.openjdk.org/jdk/pull/25664


More information about the compiler-dev mailing list