Fix C-style array method declaration parsing#6992
Conversation
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()[]}. |
There was a problem hiding this comment.
Thanks, I hate it. 🙃
To be clear: the notation style, not you adding support for it!
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; |
There was a problem hiding this comment.
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.
|
Addressed @knutwannheden's feedback: added a |
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.
Summary
byte toByteArray()[])dimensionsAfterNamefield toJ.MethodDeclaration, consistent with howNamedVariablealready handles C-style array variablesProblem
C-style array method declarations like
byte toByteArray()[]are valid Java syntax, but the parser mangled them during printing — producingbyte toByteArray()[]toByteArray()instead of preserving the original source. The parser'sarrayTypeTree()method greedily searched forward for[brackets, consuming the method name and params as prefix whitespace.Solution
Adopted the same approach already used by
VariableDeclarations.NamedVariablefor C-style array variables:endPosTableto detect whether[]follows immediately after the element type in source[]brackets usingarrayDimensions()dimensionsAfterNamefield onJ.MethodDeclaration(matching the existing field onNamedVariable)Test plan
Added test for basic C-style array method (
byte toByteArray()[])Added test for C-style array method with parameters (
byte getData(int offset, int length)[])Added test for multi-dimensional C-style arrays (
int get()[][])Existing
JavaParserTestandrewrite-javatests passFixes Java Parser might fail when array brackets
[]come after method parameters #6398