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