Parse parenthesized arguments after a command call with a block - #11
Open
tarebyte wants to merge 1 commit into
Open
Parse parenthesized arguments after a command call with a block#11tarebyte wants to merge 1 commit into
tarebyte wants to merge 1 commit into
Conversation
A call chained off a command call that carries a block, such as
`foo bar do |x| x end.each(&:sort)`, was reachable only through
`command_call`, whose arguments are an unparenthesized
`command_argument_list`. The `(` therefore started a
`parenthesized_statements` argument rather than the call's own
`argument_list`, so `&blk` and `&:sym` produced an ERROR node and a
trailing block was parsed as a hash.
A command call with a block is not a `_primary`, so such a receiver
cannot flow through `_call`/`call`. Mirror that pair for it:
`_chained_command_call_with_arguments` gives the chain a parenthesized
argument list and/or a block, and `_command_call_with_block_chain` lets
a chain act as the receiver of a further chained call, so
`end.map(&:to_s).join(", ")` and `end.size.upcase` also parse.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Chaining a call off a command call that carries a block already worked on
master—_expressionincludes_chained_command_call. But that rule is onlyreceiver,operator,method, with no argument list. A(after the chained method therefore could not be absorbed by the chain and instead completed acommand_call, whose arguments are an unparenthesizedcommand_argument_list, making the parentheses aparenthesized_statementsargument. A block-pass argument then produced anERROR:a.each(&:sort),foo(bar).each(&:sort)andfoo { }.each(&:sort)were all fine — only thedo ... endcommand-call receiver was affected.A command call carrying a block is not a
_primary, so the chain cannot go through_call/call. This adds a mirrored pair of rules for such receivers:_chained_command_call_with_argumentsadds a parenthesized argument list and/or a block, and_command_call_with_block_chainlets either it or the existing_chained_command_callact as the receiver of a further chained call. No newconflictsentries were needed.Validation
ruby/specfiles withmasterand with this branch produces identical trees. This is a regression check only — no file in that corpus reaches the new rules, which is why the result is identical rather than merely equivalent.puts (1 + 2).to_sandfoo (a), (b), where the parentheses really are a command-call argument, are unchanged.end.size.upcase,end.each do ... end,end.each(1).size,end.each(&:sort).first.end[0]andend.map(&:to_s) + z, which need the receiver to be a_primary.src/parser.cgrows 31,457,296 -> 32,058,713 bytes (+1.9%).References
Found while checking tree-sitter#266, which reported the chaining itself. The chaining now works on
master; this fixes the argument list that chain produces.Note: this branch and #6 both regenerate
src/parser.c, so whichever merges second will need a regenerate.