Skip to content

[kotlin] Fix kotlin grammar for parsing multidollar interpolation#6497

Merged
adangel merged 17 commits into
pmd:mainfrom
stokpop:fix-kotlin-grammar-minimal
Apr 23, 2026
Merged

[kotlin] Fix kotlin grammar for parsing multidollar interpolation#6497
adangel merged 17 commits into
pmd:mainfrom
stokpop:fix-kotlin-grammar-minimal

Conversation

@stokpop
Copy link
Copy Markdown
Contributor

@stokpop stokpop commented Mar 10, 2026

Fix kotlin grammar for parsing multidollar interpolation

Newer syntax in Kotlin fails to parse with messages being written to standard err.

As reported: the multi dollar syntax gives errors during parsing. Example:

val productName = "carrot"
val requestedData =
    $$$"""{
      "currency": "$",
      "enteredAmount": "42.45 $$",
      "$${serviceField.length()}": "none",
      "product": "$$${productName + "-fixed-postfix"}"
    }
    """

Related issues

Ready?

  • Added unit tests for fixed bug/feature
  • Passing all unit tests
  • Complete build ./mvnw clean verify passes (checked automatically by github actions)
  • Added (in-code) documentation (if needed)

Background and discussion

  • This is a fix with intention to minimal changes to the current Kotlin grammar
  • [update: this is fixed, see below] This fix does not distinguish between the number of dollars, both the $${ and $$${ in example are turned into expressions now, so it is up to the rules to check the number of $$$.
  • The current Kotlin version is still 1.8, but now with a fix for a syntax introduced in version 2.1
  • To aid in debugging, Kotlin nodes display a human readable toString() now: needed code update in pmd-core/BaseAntlrInnerNode.java to make that possible
  • A couple of unit tests with specific Kotlin syntax are added for future regression testing
  • Helper methods for testing Kotlin parsing have been added to KotlinParsingHelper.
    • These can maybe also be moved to more generic test helper code (in pmd-test module?)
  • In another branch we tried to upgrade to a newer Kotlin grammar as found here: https://github.com/antlr/grammars-v4
    • that works but it changes the generated Antlr4 code in a non-compatible way
    • this newer grammar does not solve the multi dollar issue!
    • should we create PR to see if that is way forward?
    • also see if a new Kotlin version can/should be added next to 1.8?

@pmd-actions-helper
Copy link
Copy Markdown
Contributor

pmd-actions-helper Bot commented Mar 10, 2026

Documentation Preview

No relevant source code has been changed, pmdtester skipped.

(comment created at 2026-04-23 19:00:24+00:00 for 1328d18)

@stokpop
Copy link
Copy Markdown
Contributor Author

stokpop commented Mar 11, 2026

Went down the number of dollars rabbit hole: now the grammar takes into consideration the number of dollars to match actual refs and expressions in the multi line templates. Added unit tests for regular and "split" dollar cases.

Copy link
Copy Markdown
Member

@adangel adangel left a comment

Choose a reason for hiding this comment

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

Thanks for the PR and sorry for the late response.

I think, there are a couple of things, we need to fix, see my comments.

Apart from that:

Comment thread pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/KotlinInnerNode.java Outdated
@adangel adangel changed the title [kotlin] Fix kotlin grammar for parsing multiline multi dollar [kotlin] Fix kotlin grammar for parsing multidollar interpolation Mar 21, 2026
@stokpop
Copy link
Copy Markdown
Contributor Author

stokpop commented Mar 25, 2026

@adangel thanks for your review! Will start working on the improvements.

@stokpop
Copy link
Copy Markdown
Contributor Author

stokpop commented Mar 25, 2026

Thanks for asking jetbrains youtrack! Hopefully they are able to sync.

Did you also have a look at the two alternative grammars here: https://github.com/antlr/grammars-v4/tree/master/kotlin?
My experiment shows they are a bit different and have missing and added "features". So not sure we can switch/extend these.

@adangel
Copy link
Copy Markdown
Member

adangel commented Mar 27, 2026

Did you also have a look at the two alternative grammars here: https://github.com/antlr/grammars-v4/tree/master/kotlin?
My experiment shows they are a bit different and have missing and added "features". So not sure we can switch/extend these.

I didn't have a detailed look. But I guess, we should stick to the grammar we have - if we switch the entire grammar, there might be a risk that all custom rules need to be rewritten, if the parser outputs a different parse tree.

What I would suggest is this:

  1. make sure, we use the latest official grammar from https://github.com/Kotlin/kotlin-spec/tree/release/grammar/src/main/antlr . Hopefully, we did this already and there is nothing to be changed. That would be the starting point.
  2. Keep on working adding one feature at a time, like in this PR, which only adds multidollar interpolation.
    I'll update [kotlin] Support multidollar interpolation (Kotlin 2.2) #6003 to be only about the multidollar interpolation feature and not Kotlin 2.2 in general anymore.
  3. When adding another feature (different PR!), you might want to look at these alternative grammars to see, how/if they solved it and you can reimplement it in PMD's own grammar.

In general, I wouldn't expect an updated, official upstream grammar from Jetbrains soon. AFAIK, they've rewritten their parser/compiler (see K2) and it looks like, there is no formal grammar used anywhere anymore. If it comes, we need to see, whether we are still able to use it, since we are now implementing our own grammar.

@stokpop stokpop requested a review from adangel March 30, 2026 21:32
stokpop added 2 commits March 31, 2026 09:01
…keep behaviour same. Use custom parser that throws ParserException for running tests and getting notified for parse issues.
@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented Apr 3, 2026

Not up to standards ⛔

🔴 Issues 6 medium

Alerts:
⚠ 6 issues (≤ 0 issues of at least minor severity)

Results:
6 new issues

Category Results
BestPractice 6 medium

View in Codacy

🟢 Metrics 11 complexity · 1 duplication

Metric Results
Complexity 11
Duplication 1

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@stokpop
Copy link
Copy Markdown
Contributor Author

stokpop commented Apr 3, 2026

Hi @adangel, I requested a new review of this PR via the button on top.

Can you have another look please and I think the process is that you close the conversations that are ok?

@stokpop
Copy link
Copy Markdown
Contributor Author

stokpop commented Apr 16, 2026

Hello @adangel, can you please have a look at the updates on your review comments? (Or should I maybe turn it to "resolved" myself?)

Copy link
Copy Markdown
Member

@adangel adangel left a comment

Choose a reason for hiding this comment

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

Thanks, looks good. You can fix the minor things I mentioned, otherwise I'll do it myself.

I won't have time to merge it before next week though.

Comment thread docs/pages/pmd/languages/kotlin.md
stokpop and others added 3 commits April 17, 2026 18:25
@stokpop stokpop requested a review from adangel April 20, 2026 10:43
@stokpop
Copy link
Copy Markdown
Contributor Author

stokpop commented Apr 20, 2026

@adangel please have another look at the requested changes above, there is a remaining question about the toString(): leave it as is in this PR or revert back to Object.toString()?

@adangel
Copy link
Copy Markdown
Member

adangel commented Apr 23, 2026

remaining question about the toString(): leave it as is in this PR or revert back to Object.toString()?

I've looked at it and yes, seems we need it. I'll add it to AntlrTerminalPmdAdapter as well, as there we are missing the delegation to pmdNode - then we get also a nice reminder "!debug only!" for terminals.

Had to make change to getTextRegion() to avoid NullPointException.

FYI: This might be caused by parse errors (then there might be no stop token).

Actually, some nodes are created by the parser, even if there are no tokens/terminals. E.g. we always get a "packageHeader" node, even if there is no package statement. Or we always get a "importList" node, even if there are no import statements. In these cases, the stop token is null.

@adangel adangel added this to the 7.24.0 milestone Apr 23, 2026
adangel added a commit to stokpop/pmd that referenced this pull request Apr 23, 2026
@adangel adangel force-pushed the fix-kotlin-grammar-minimal branch from 460a6d5 to 1328d18 Compare April 23, 2026 18:45
@adangel adangel merged commit 1436f7d into pmd:main Apr 23, 2026
2 checks passed
@stokpop stokpop deleted the fix-kotlin-grammar-minimal branch May 15, 2026 11:32
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.

[kotlin] Support multidollar interpolation (Kotlin 2.2)

2 participants