Skip to content

feat: expose leading comments via getLeadingComments() - #2779

Draft
fudianchn wants to merge 4 commits into
JSQLParser:masterfrom
fudianchn:feat/statement-leading-comments
Draft

fudianchn wants to merge 4 commits into
JSQLParser:masterfrom
fudianchn:feat/statement-leading-comments

Conversation

@fudianchn

@fudianchn fudianchn commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

AI disclosure: this change was prepared with AI coding agents.

What

ASTNodeAccessImpl.getLeadingComments() returns the comments preceding the node's first token, in source order, with the original token images.

Why

PageHelper recovers statement-leading comments from the JavaCC special-token chain when rewriting SQL, using select.getASTNode().jjtGetFirstToken().specialToken (DefaultCountSqlParser and the CountJSqlParser51 adapter). This accessor provides a public entry point for that use case without exposing the token traversal to callers. The getASTNode() return-type change discussed in pagehelper-org/Mybatis-PageHelper#887 illustrates the cost of relying on parser internals; adopting this accessor requires downstream changes.

Discussion #2018, converted from #2017, explains the ambiguity of assigning arbitrary comments to AST nodes. This accessor only reads existing comment tokens before a node's first token; it does not change SQL rendering.

How

One lazy accessor on ASTNodeAccessImpl: walk the first token's specialToken chain, collect the images, reverse to source order; nodes without an AST (built programmatically) return an empty list. No grammar, interface, deparser or toString() changes.

Testing

New LeadingCommentsTest: block comments in source order (the exact shape PageHelper recovers, /* keep orderby */ /*+ FULL(t) */), line comments, mid-statement comments excluded, none, programmatic nodes, toString() unchanged, per-statement attribution under parseStatements. SerializationTest uses the existing in-memory round-trip helper to check SQL preservation and the empty leading-comment list after deserialization, when the transient AST is absent.

Behavior notes

  • toString() and the deparsers keep dropping comments as before.
  • Line-comment images exclude their line terminator, as scanned; callers must add a line break when prepending them to SQL.
  • Trailing comments of the previous statement are not exposed.
  • ASTNodeAccessImpl uses a computed serial UID, as before this PR. Adding the accessor changes that UID, so objects serialized with the previous class definition can fail to deserialize with InvalidClassException. Rebuild affected persisted AST caches after upgrading. Same-version round trips remain covered.

Downstream SQL rewriters currently recover statement-leading comments
from the JavaCC special-token chain via getASTNode(), whose erasure
changed within 5.x and broke compiled downstream adapters.

Signed-off-by: 付典 <fudianchn@gmail.com>
@fudianchn
fudianchn marked this pull request as draft October 12, 2026 07:19
Keep the serial UID from 066f581 so existing serialized models remain readable. Return the original comment token images without line terminators.

Signed-off-by: 付典 <fudianchn@gmail.com>
@fudianchn
fudianchn force-pushed the feat/statement-leading-comments branch from 0998415 to 7b08430 Compare October 12, 2026 07:39
@fudianchn
fudianchn marked this pull request as ready for review October 12, 2026 08:01

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this one please?!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fixture was intended to verify that adding the accessor did not break deserialization of existing objects. I have removed the binary fixture.

public class SerializationTest {
@Test
void deserializeSelectFromBeforeLeadingCommentsAccessor() throws Exception {
try (InputStream serialized = getClass().getResourceAsStream(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, just no!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the fixture-based test with the existing in-memory round-trip helper, checking that the SQL is preserved and the deserialized node has no leading comments.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this change needs to pin the base class's serialVersionUID. Fixing that value alone does not guarantee cross-version deserialization of the AST. I'll remove it and keep the test focused on same-version round trips.

Signed-off-by: 付典 <fudianchn@gmail.com>
@fudianchn
fudianchn marked this pull request as draft October 13, 2026 02:28
@fudianchn
fudianchn marked this pull request as ready for review October 13, 2026 02:32
@fudianchn
fudianchn marked this pull request as draft October 13, 2026 03:09
Adding getLeadingComments changes the computed UID; previously serialized AST objects may no longer be readable.

Signed-off-by: 付典 <fudianchn@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants