Skip to content

Fix aref_field bracket consumption causing invalid source_range - #1642

Merged
lsegal merged 1 commit into
lsegal:mainfrom
dduugg:fix-aref-field-bracket-consumption
Jan 16, 2026
Merged

Fix aref_field bracket consumption causing invalid source_range#1642
lsegal merged 1 commit into
lsegal:mainfrom
dduugg:fix-aref-field-bracket-consumption

Conversation

@dduugg

@dduugg dduugg commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #1420

I caused the above regression four years ago and am proposing a fix here. This PR was heavily AI-assisted.

The issue occurred when parsing code with an aref assignment (a[:b] = 1) followed by a constant assignment using aref (X = a[:b]). The parser would create an invalid source_range for the constant's aref node, where the ending position was less than the beginning position.

Root Cause:

When Ripper encounters an aref on the left-hand side of an assignment (e.g., a[:b] = 1), it calls on_aref_field instead of on_aref. The on_aref_field method was not consuming the closing bracket position from @map[:aref], which tracks bracket positions. This left the bracket position from the assignment in the map.

When the next aref expression (X = a[:b]) was parsed, on_aref would shift the old bracket position from @map[:aref], causing it to use the wrong ending position and create an invalid source_range where end < begin.

The Fix:

Updated on_aref_field to match the behavior of on_aref:

  • Consume the closing bracket position from @map[:aref] using shift
  • Use the bracket position to correctly calculate the source_range
  • Set both source_range and line_range based on the actual bracket position

This ensures that when on_aref_field processes a[:b] = 1, it consumes the bracket, so when on_aref processes X = a[:b], it gets the correct bracket position and creates a valid source_range.

Changes:

  • Modified on_aref_field in lib/yard/parser/ruby/ruby_parser.rb to consume bracket positions from @map[:aref] and calculate source_range correctly
  • Added spec to verify constant assignments with aref after aref assignments parse correctly with valid source_range

The fix ensures both on_aref and on_aref_field handle bracket consumption consistently, preventing the parser from getting confused by previous aref assignments.

Completed Tasks

  • I have read the Contributing Guide.
  • The pull request is complete (implemented / written).
  • Git commits have been cleaned up (squash WIP / revert commits).
  • I wrote tests and ran bundle exec rake locally (if code is attached to PR).

Fixes lsegal#1420

The issue occurred when parsing code with an aref assignment (a[:b] = 1)
followed by a constant assignment using aref (X = a[:b]). The parser would
create an invalid source_range for the constant's aref node, where the
ending position was less than the beginning position.

Root Cause:
-----------
When Ripper encounters an aref on the left-hand side of an assignment
(e.g., a[:b] = 1), it calls on_aref_field instead of on_aref. The
on_aref_field method was not consuming the closing bracket position from
@Map[:aref], which tracks bracket positions. This left the bracket position
from the assignment in the map.

When the next aref expression (X = a[:b]) was parsed, on_aref would shift
the old bracket position from @Map[:aref], causing it to use the wrong
ending position and create an invalid source_range where end < begin.

The Fix:
--------
Updated on_aref_field to match the behavior of on_aref:
- Consume the closing bracket position from @Map[:aref] using shift
- Use the bracket position to correctly calculate the source_range
- Set both source_range and line_range based on the actual bracket position

This ensures that when on_aref_field processes a[:b] = 1, it consumes the
bracket, so when on_aref processes X = a[:b], it gets the correct bracket
position and creates a valid source_range.

Changes:
--------
- Modified on_aref_field in lib/yard/parser/ruby/ruby_parser.rb to consume
  bracket positions from @Map[:aref] and calculate source_range correctly
- Added spec to verify constant assignments with aref after aref assignments
  parse correctly with valid source_range

The fix ensures both on_aref and on_aref_field handle bracket consumption
consistently, preventing the parser from getting confused by previous aref
assignments.
@lsegal

lsegal commented Jan 16, 2026

Copy link
Copy Markdown
Owner

Thank you!

@lsegal
lsegal merged commit 4dc66fc into lsegal:main Jan 16, 2026
21 checks passed
@dduugg
dduugg deleted the fix-aref-field-bracket-consumption branch January 16, 2026 21:09
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.

[0.9.27 regression] Parser gets confused by aref assignment

2 participants