[ruby/prism] Forward parameters into arrays

https://github.com/ruby/prism/commit/2a11bfee76
This commit is contained in:
Kevin Newton 2023-11-01 09:36:49 -04:00 committed by git
parent bb2e1d8eef
commit 8c0eb221b7
3 changed files with 69 additions and 23 deletions

View File

@ -12467,7 +12467,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
bool parsed_bare_hash = false; bool parsed_bare_hash = false;
while (!match2(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_EOF)) { while (!match2(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_EOF)) {
// Handle the case where we don't have a comma and we have a newline followed by a right bracket. // Handle the case where we don't have a comma and we have a
// newline followed by a right bracket.
if (accept1(parser, PM_TOKEN_NEWLINE) && match1(parser, PM_TOKEN_BRACKET_RIGHT)) { if (accept1(parser, PM_TOKEN_NEWLINE) && match1(parser, PM_TOKEN_BRACKET_RIGHT)) {
break; break;
} }
@ -12476,16 +12477,25 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
expect1(parser, PM_TOKEN_COMMA, PM_ERR_ARRAY_SEPARATOR); expect1(parser, PM_TOKEN_COMMA, PM_ERR_ARRAY_SEPARATOR);
} }
// If we have a right bracket immediately following a comma, this is // If we have a right bracket immediately following a comma,
// allowed since it's a trailing comma. In this case we can break out of // this is allowed since it's a trailing comma. In this case we
// the loop. // can break out of the loop.
if (match1(parser, PM_TOKEN_BRACKET_RIGHT)) break; if (match1(parser, PM_TOKEN_BRACKET_RIGHT)) break;
pm_node_t *element; pm_node_t *element;
if (accept1(parser, PM_TOKEN_USTAR)) { if (accept1(parser, PM_TOKEN_USTAR)) {
pm_token_t operator = parser->previous; pm_token_t operator = parser->previous;
pm_node_t *expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR); pm_node_t *expression = NULL;
if (match3(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_COMMA, PM_TOKEN_EOF)) {
if (pm_parser_local_depth(parser, &parser->previous) == -1) {
pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_STAR);
}
} else {
expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR);
}
element = (pm_node_t *) pm_splat_node_create(parser, &operator, expression); element = (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
} else if (match2(parser, PM_TOKEN_LABEL, PM_TOKEN_USTAR_STAR)) { } else if (match2(parser, PM_TOKEN_LABEL, PM_TOKEN_USTAR_STAR)) {
if (parsed_bare_hash) { if (parsed_bare_hash) {

View File

@ -166,3 +166,5 @@ end
foo = 1 foo = 1
def foo.bar; end def foo.bar; end
def f(*); [*]; end

View File

@ -1,8 +1,8 @@
@ ProgramNode (location: (1,0)-(168,16)) @ ProgramNode (location: (1,0)-(170,18))
├── locals: [:a, :c, :foo] ├── locals: [:a, :c, :foo]
└── statements: └── statements:
@ StatementsNode (location: (1,0)-(168,16)) @ StatementsNode (location: (1,0)-(170,18))
└── body: (length: 62) └── body: (length: 63)
├── @ DefNode (location: (1,0)-(2,3)) ├── @ DefNode (location: (1,0)-(2,3))
│ ├── name: :foo │ ├── name: :foo
│ ├── name_loc: (1,4)-(1,7) = "foo" │ ├── name_loc: (1,4)-(1,7) = "foo"
@ -1632,19 +1632,53 @@
│ │ @ IntegerNode (location: (167,6)-(167,7)) │ │ @ IntegerNode (location: (167,6)-(167,7))
│ │ └── flags: decimal │ │ └── flags: decimal
│ └── operator_loc: (167,4)-(167,5) = "=" │ └── operator_loc: (167,4)-(167,5) = "="
└── @ DefNode (location: (168,0)-(168,16)) ├── @ DefNode (location: (168,0)-(168,16))
├── name: :bar │ ├── name: :bar
├── name_loc: (168,8)-(168,11) = "bar" │ ├── name_loc: (168,8)-(168,11) = "bar"
├── receiver: │ ├── receiver:
│ @ LocalVariableReadNode (location: (168,4)-(168,7)) │ │ @ LocalVariableReadNode (location: (168,4)-(168,7))
│ ├── name: :foo │ │ ├── name: :foo
│ └── depth: 0 │ │ └── depth: 0
├── parameters: ∅ │ ├── parameters: ∅
├── body: ∅ │ ├── body: ∅
├── locals: [] │ ├── locals: []
├── def_keyword_loc: (168,0)-(168,3) = "def" │ ├── def_keyword_loc: (168,0)-(168,3) = "def"
├── operator_loc: (168,7)-(168,8) = "." │ ├── operator_loc: (168,7)-(168,8) = "."
├── lparen_loc: ∅ │ ├── lparen_loc: ∅
├── rparen_loc: ∅ │ ├── rparen_loc: ∅
│ ├── equal_loc: ∅
│ └── end_keyword_loc: (168,13)-(168,16) = "end"
└── @ DefNode (location: (170,0)-(170,18))
├── name: :f
├── name_loc: (170,4)-(170,5) = "f"
├── receiver: ∅
├── parameters:
│ @ ParametersNode (location: (170,6)-(170,7))
│ ├── requireds: (length: 0)
│ ├── optionals: (length: 0)
│ ├── rest:
│ │ @ RestParameterNode (location: (170,6)-(170,7))
│ │ ├── name: ∅
│ │ ├── name_loc: ∅
│ │ └── operator_loc: (170,6)-(170,7) = "*"
│ ├── posts: (length: 0)
│ ├── keywords: (length: 0)
│ ├── keyword_rest: ∅
│ └── block: ∅
├── body:
│ @ StatementsNode (location: (170,10)-(170,13))
│ └── body: (length: 1)
│ └── @ ArrayNode (location: (170,10)-(170,13))
│ ├── elements: (length: 1)
│ │ └── @ SplatNode (location: (170,11)-(170,12))
│ │ ├── operator_loc: (170,11)-(170,12) = "*"
│ │ └── expression: ∅
│ ├── opening_loc: (170,10)-(170,11) = "["
│ └── closing_loc: (170,12)-(170,13) = "]"
├── locals: [:*]
├── def_keyword_loc: (170,0)-(170,3) = "def"
├── operator_loc: ∅
├── lparen_loc: (170,5)-(170,6) = "("
├── rparen_loc: (170,7)-(170,8) = ")"
├── equal_loc: ∅ ├── equal_loc: ∅
└── end_keyword_loc: (168,13)-(168,16) = "end" └── end_keyword_loc: (170,15)-(170,18) = "end"