Skip to content

Properly number anonymous classes within anonymous classes - #69

Merged
sciwhiz12 merged 3 commits into
mainfrom
nested-anonymous-classes
Oct 24, 2026
Merged

sciwhiz12 merged 3 commits into
mainfrom
nested-anonymous-classes

Conversation

@sciwhiz12

@sciwhiz12 sciwhiz12 commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

This PR fixes the numbering of nested anonymous classes (anonymous classes within anonymous classes) by skipping traversal of the children of nested classes (but not the nested classes themselves) in PsiHelper#getNonQualifiedClassIdx.

The numbering of anonymous classes is done independently by traversing the containing class in a post-order depth-first traversal, collecting any anonymous (nonqualified) classes, and numbering them in encounter order.

This poses a problem when there are anonymous classes nested within the top-level anonymous classes (where top-level is in reference to the root containing class.) The traversal also encounters those classes, so it includes them in the numbering. This is contrary to the actual numbering scheme, which only accounts for the 'immediate' children of the containing class.

In the added test, this would show up as example.C$1 being numbered as example.C$2, because the actual example.C$1$1 would be erroneously numbered as example.C$1.

This PR also fixes a problem found while debugging, where the root node itself (if also an anonymous class) would be traversed and numbered in the map. This would be problematic for both AT validation, where an invalid nested anonymous class reference might not be caught but silently applied against the containing anonymous class, and for debugging where the map seems to have one more entry than expected. For the sake of both (and the sanity of whoever else needs to debug this), we fix that by skipping the root node for numbering.

Thanks to @covers1624 for reporting the issue.

The numbering of anonymous classes is done independently by traversing
the containing class in a post-order depth-first traversal, collecting
any anonymous (nonqualified) classes, and numbering them in encounter
order.

This poses a problem when there are anonymous classes nested within the
top-level anonymous classes (where top-level is in reference to the root
containing class.) The traversal also encounters those classes, so it
includes them in the numbering. This is contrary to the actual
numbering scheme, which only accounts for the 'immediate' children of
the containing class.

In the added test, this would show up as `example.C$1` being numbered as
`example.C$2`, because the actual `example.C$1$1` would be erroneously
numbered as `example.C$1`.

Fix this by skipping traversal of the children of nested classes (but
not the nested classes themselves).
Because of post-order traversal, the root node would get added to the
end of the map if the root node itself was an anonmyous/nonqualified
class.
@sciwhiz12
sciwhiz12 requested a review from Matyrobbrt October 24, 2026 14:51
@sciwhiz12 sciwhiz12 added the bug Something isn't working label Oct 24, 2026
@neoforged-pr-publishing

Copy link
Copy Markdown
  • Publish PR to GitHub Packages

@sciwhiz12
sciwhiz12 merged commit a323e4e into main Oct 24, 2026
2 checks passed
@sciwhiz12
sciwhiz12 deleted the nested-anonymous-classes branch October 24, 2026 15:18
@neoforged-releases

Copy link
Copy Markdown

🚀 This PR has been released as JavaSourceTransformer version 2.0.12.

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants