RFR: 8358604: Trees for `var` do not have end positions
Jan Lahoda
jlahoda at openjdk.org
Tue Jun 10 06:46:27 UTC 2025
On Thu, 5 Jun 2025 21:14:03 GMT, Archie Cobbs <acobbs at openjdk.org> wrote:
> 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
I guess I would like to understand the rationale for adding the end position for the type. Generally, when javac synthesizes trees, the new trees don't have an end position (like for the synthetic constructor, and several other cases). So, I think there's a question why this specific synthetic tree should have an end position, while the other shouldn't.
Also, currently the missing end position is used as a "marker" for synthetic trees. Not particularly nice, but given the synthetic trees are/were (I think) considered a workaround. When the tree has an end position, how will the Trees API clients find out this tree is synthetic?
-------------
PR Comment: https://git.openjdk.org/jdk/pull/25664#issuecomment-2957865902
More information about the compiler-dev
mailing list