Skip to content

Fix dcl-ds with likeds/likerec bracket matching and folding#530

Open
richardm90 wants to merge 3 commits into
codefori:mainfrom
richardm90:fix-dcl-ds-highlighting
Open

Fix dcl-ds with likeds/likerec bracket matching and folding#530
richardm90 wants to merge 3 commits into
codefori:mainfrom
richardm90:fix-dcl-ds-highlighting

Conversation

@richardm90

Copy link
Copy Markdown
Contributor

Changes

Problem

The extension incorrectly treated dcl-ds declarations with likeds or likerecas block openers requiring end-ds. This caused multiple issues:

  1. Bracket highlighting: end-proc was highlighted in red as mismatched when preceded by dcl-ds likeds(...)
  2. Nested structures: In nested data structures, single-line dcl-ds likeds(...) would incorrectly match with the next end-ds
  3. Comment edge case: dcl-ds x; // likeds(fake) was treated as single-line when it should be a block
  4. Incorrect folding: Code folding created fold points for single-line declarations

Before the changes in this PR:

image

Comment out the data structure declaration:

image

Root Cause

In RPGLE, dcl-ds has dual behavior:

  • Multi-line block: dcl-ds myStruct; ... end-ds; (requires end-ds)
  • Single-line declaration: dcl-ds myData likeds(SomeType); (no end-ds needed)

Both folding range provider and bracket matcher were treating all dcl-ds as block openers without checking for likeds()/likerec().

Solution

Updated stack-based block matching logic in both server and client to skip dcl-ds when it contains likeds() or likerec() on the same line (excluding comments).

Changes

Server-Side (Folding Ranges)

  • Strip comments before checking for likeds/likerec
  • Skip pushing dcl-ds to stack if it's a single-line declaration

Client-Side (Bracket Highlighting)

  • Added stripComments() helper to remove // comments
  • Added isDclDsWithLikedsOrLikerec() helper for consistent checking
  • Updated 5 functions: findMatchingOpenForClosing(), findMatchingOpenForAnyClosing(), findBlockIndices(), findMatchingClose(), findMatchingOpen()
  • All functions now pass text parameter and use helper to check for single-line declarations

Tests

  • Created multiple server side tests to check expected cases
  • Also created client side tests but these are purely documentation tests, following the same pattern as existing client side tests

Technical Notes

  • Fix is specific to dcl-ds only - it's the only RPGLE declaration I could think of with this dual behaviour
  • Other block types (dcl-proc, if, dow, etc.) are unaffected
  • Regex pattern /likeds\s*\(/ handles optional white-space and is case-insensitive
  • Comments are stripped before pattern matching to avoid false positives
  • Both client and server implementations use identical logic for consistency

Checklist

  • have tested my change
  • updated relevant documentation
  • Remove any/all console.logs I added
  • eslint is not complaining
  • have added myself to the contributors' list in the README
  • for feature PRs: PR only includes one feature enhancement.

dcl-ds declarations using likeds() or likerec() don't require end-ds,
but were incorrectly treated as block openers causing mismatched
bracket highlighting on subsequent end-proc statements.
Fixed bracketMatcher.ts to not treat dcl-ds with likeds/likerec as
block openers. Added documentation tests.
Comments now stripped before checking if dcl-ds has likeds/likerec,
preventing false positives. Added helper functions and test coverage.
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.

1 participant