Skip to content

Fix C-style array method declaration parsing#6992

Draft
Jenson3210 wants to merge 9 commits intomainfrom
fix-cstyle-array-method-decl
Draft

Fix C-style array method declaration parsing#6992
Jenson3210 wants to merge 9 commits intomainfrom
fix-cstyle-array-method-decl

Conversation

@Jenson3210
Copy link
Contributor

@Jenson3210 Jenson3210 commented Mar 16, 2026

Summary

  • Fix parser to correctly handle C-style array method declarations (e.g., byte toByteArray()[])
  • Add dimensionsAfterName field to J.MethodDeclaration, consistent with how NamedVariable already handles C-style array variables
  • Updated all parsers (Java 8/11/17/21/25, Groovy, Kotlin) and RPC layers (Python, JavaScript, C#)

Problem

C-style array method declarations like byte toByteArray()[] are valid Java syntax, but the parser mangled them during printing — producing byte toByteArray()[]toByteArray() instead of preserving the original source. The parser's arrayTypeTree() method greedily searched forward for [ brackets, consuming the method name and params as prefix whitespace.

Solution

Adopted the same approach already used by VariableDeclarations.NamedVariable for C-style array variables:

  1. Check javac's endPosTable to detect whether [] follows immediately after the element type in source
  2. If not (C-style), only convert the base type as the return type expression
  3. After parsing method parameters, consume the [] brackets using arrayDimensions()
  4. Store dimensions in a new dimensionsAfterName field on J.MethodDeclaration (matching the existing field on NamedVariable)
  5. The printer outputs the dimensions after the parameter list

Test plan

Reproduces #6398: `byte toByteArray()[]` gets printed as
`byte toByteArray()[]toByteArray()` instead of preserving the
original source.
When array brackets appear after method parameters (e.g.,
`byte toByteArray()[]`), the parser was greedily consuming
the brackets as part of the return type, causing the method
name to appear in the array type's prefix space and be
duplicated during printing.

The fix detects C-style array return types by checking javac's
end position table, similar to how VariableDeclarations already
handles C-style arrays. When detected, only the base type is
parsed as the return type, and the array dimensions are consumed
after the parameters and stored in a CStyleArrayDeclaration marker
that the printer uses to output them in the correct position.

Fixes #6398
Replace the CStyleArrayDeclaration marker with a proper
dimensionsAfterName field on J.MethodDeclaration, consistent with
how NamedVariable already handles C-style array variables.

This stores C-style array dimensions (e.g. byte toByteArray()[])
directly on the MethodDeclaration model rather than as a marker,
including RPC sender/receiver support.

Fixes #6398
Update the Python and JavaScript/TypeScript modules to handle the
new dimensionsAfterName field on J.MethodDeclaration:
- Python: tree model, .pyi stub, parser visitors, RPC sender/receiver
- JavaScript: tree model, visitor, parser, RPC sender/receiver

/**
* C-style array dimensions that appear after the method parameters rather than
* after the return type. For example: {@code byte toByteArray()[]}.
Copy link
Member

@timtebeek timtebeek Mar 16, 2026

Choose a reason for hiding this comment

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

Thanks, I hate it. 🙃

To be clear: the notation style, not you adding support for it!

@Jenson3210 Jenson3210 marked this pull request as draft March 16, 2026 20:50
Update the .NET side of the C# module to handle the new
dimensionsAfterName field on J.MethodDeclaration:
- J.cs: add field, property, and all With* methods
- CSharpParser.cs: add [] to all 5 constructor calls
- JavaSender.cs/JavaReceiver.cs: add RPC send/receive
*/
@With
@Getter
List<JLeftPadded<Space>> dimensionsAfterName;
Copy link
Contributor

Choose a reason for hiding this comment

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

We need a strategy for how to deal with existing LST models that get deserialized and where this property will be null. So either we need an @JsonCreator constructor to set this to some non-null value or we need to declare it as nullable. In addition we should also add some comment so that we can see to removing this workaround after some time again.

Older serialized LSTs won't have the dimensionsAfterName field.
Add a @JsonCreator factory method that defaults null to emptyList()
so deserialization of existing LSTs continues to work.
@Jenson3210
Copy link
Contributor Author

Addressed @knutwannheden's feedback: added a @JsonCreator factory method on MethodDeclaration that accepts @Nullable dimensionsAfterName and defaults it to emptyList() for backwards-compatible deserialization of older LSTs. Comment added noting it can be removed once older LSTs are out of circulation.

Replace the comment with @deprecated and @toBeRemoved(after = "2026-09-17")
annotations so the backwards-compatibility factory method is tracked for
removal.
Ensures that whitespace before/inside brackets and block comments
between brackets are preserved losslessly for C-style array method
declarations.
Without this, space-visiting recipes (like formatting) would not
traverse the spaces inside C-style array dimensions on method
declarations, matching the existing pattern for NamedVariable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Java Parser might fail when array brackets [] come after method parameters

3 participants