Skip to content

Commit 8c0eb22

Browse files
kddnewtonmatzbot
authored andcommitted
[ruby/prism] Forward parameters into arrays
ruby/prism@2a11bfee76
1 parent bb2e1d8 commit 8c0eb22

File tree

3 files changed

+69
-23
lines changed

3 files changed

+69
-23
lines changed

prism/prism.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12467,7 +12467,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
1246712467
bool parsed_bare_hash = false;
1246812468

1246912469
while (!match2(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_EOF)) {
12470-
// Handle the case where we don't have a comma and we have a newline followed by a right bracket.
12470+
// Handle the case where we don't have a comma and we have a
12471+
// newline followed by a right bracket.
1247112472
if (accept1(parser, PM_TOKEN_NEWLINE) && match1(parser, PM_TOKEN_BRACKET_RIGHT)) {
1247212473
break;
1247312474
}
@@ -12476,16 +12477,25 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
1247612477
expect1(parser, PM_TOKEN_COMMA, PM_ERR_ARRAY_SEPARATOR);
1247712478
}
1247812479

12479-
// If we have a right bracket immediately following a comma, this is
12480-
// allowed since it's a trailing comma. In this case we can break out of
12481-
// the loop.
12480+
// If we have a right bracket immediately following a comma,
12481+
// this is allowed since it's a trailing comma. In this case we
12482+
// can break out of the loop.
1248212483
if (match1(parser, PM_TOKEN_BRACKET_RIGHT)) break;
1248312484

1248412485
pm_node_t *element;
1248512486

1248612487
if (accept1(parser, PM_TOKEN_USTAR)) {
1248712488
pm_token_t operator = parser->previous;
12488-
pm_node_t *expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR);
12489+
pm_node_t *expression = NULL;
12490+
12491+
if (match3(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_COMMA, PM_TOKEN_EOF)) {
12492+
if (pm_parser_local_depth(parser, &parser->previous) == -1) {
12493+
pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_STAR);
12494+
}
12495+
} else {
12496+
expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR);
12497+
}
12498+
1248912499
element = (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
1249012500
} else if (match2(parser, PM_TOKEN_LABEL, PM_TOKEN_USTAR_STAR)) {
1249112501
if (parsed_bare_hash) {

test/prism/fixtures/methods.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,5 @@ end
166166

167167
foo = 1
168168
def foo.bar; end
169+
170+
def f(*); [*]; end

test/prism/snapshots/methods.txt

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
@ ProgramNode (location: (1,0)-(168,16))
1+
@ ProgramNode (location: (1,0)-(170,18))
22
├── locals: [:a, :c, :foo]
33
└── statements:
4-
@ StatementsNode (location: (1,0)-(168,16))
5-
└── body: (length: 62)
4+
@ StatementsNode (location: (1,0)-(170,18))
5+
└── body: (length: 63)
66
├── @ DefNode (location: (1,0)-(2,3))
77
│ ├── name: :foo
88
│ ├── name_loc: (1,4)-(1,7) = "foo"
@@ -1632,19 +1632,53 @@
16321632
│ │ @ IntegerNode (location: (167,6)-(167,7))
16331633
│ │ └── flags: decimal
16341634
│ └── operator_loc: (167,4)-(167,5) = "="
1635-
└── @ DefNode (location: (168,0)-(168,16))
1636-
├── name: :bar
1637-
├── name_loc: (168,8)-(168,11) = "bar"
1638-
├── receiver:
1639-
│ @ LocalVariableReadNode (location: (168,4)-(168,7))
1640-
│ ├── name: :foo
1641-
│ └── depth: 0
1642-
├── parameters: ∅
1643-
├── body: ∅
1644-
├── locals: []
1645-
├── def_keyword_loc: (168,0)-(168,3) = "def"
1646-
├── operator_loc: (168,7)-(168,8) = "."
1647-
├── lparen_loc: ∅
1648-
├── rparen_loc: ∅
1635+
├── @ DefNode (location: (168,0)-(168,16))
1636+
│ ├── name: :bar
1637+
│ ├── name_loc: (168,8)-(168,11) = "bar"
1638+
│ ├── receiver:
1639+
│ │ @ LocalVariableReadNode (location: (168,4)-(168,7))
1640+
│ │ ├── name: :foo
1641+
│ │ └── depth: 0
1642+
│ ├── parameters: ∅
1643+
│ ├── body: ∅
1644+
│ ├── locals: []
1645+
│ ├── def_keyword_loc: (168,0)-(168,3) = "def"
1646+
│ ├── operator_loc: (168,7)-(168,8) = "."
1647+
│ ├── lparen_loc: ∅
1648+
│ ├── rparen_loc: ∅
1649+
│ ├── equal_loc: ∅
1650+
│ └── end_keyword_loc: (168,13)-(168,16) = "end"
1651+
└── @ DefNode (location: (170,0)-(170,18))
1652+
├── name: :f
1653+
├── name_loc: (170,4)-(170,5) = "f"
1654+
├── receiver: ∅
1655+
├── parameters:
1656+
│ @ ParametersNode (location: (170,6)-(170,7))
1657+
│ ├── requireds: (length: 0)
1658+
│ ├── optionals: (length: 0)
1659+
│ ├── rest:
1660+
│ │ @ RestParameterNode (location: (170,6)-(170,7))
1661+
│ │ ├── name: ∅
1662+
│ │ ├── name_loc: ∅
1663+
│ │ └── operator_loc: (170,6)-(170,7) = "*"
1664+
│ ├── posts: (length: 0)
1665+
│ ├── keywords: (length: 0)
1666+
│ ├── keyword_rest: ∅
1667+
│ └── block: ∅
1668+
├── body:
1669+
│ @ StatementsNode (location: (170,10)-(170,13))
1670+
│ └── body: (length: 1)
1671+
│ └── @ ArrayNode (location: (170,10)-(170,13))
1672+
│ ├── elements: (length: 1)
1673+
│ │ └── @ SplatNode (location: (170,11)-(170,12))
1674+
│ │ ├── operator_loc: (170,11)-(170,12) = "*"
1675+
│ │ └── expression: ∅
1676+
│ ├── opening_loc: (170,10)-(170,11) = "["
1677+
│ └── closing_loc: (170,12)-(170,13) = "]"
1678+
├── locals: [:*]
1679+
├── def_keyword_loc: (170,0)-(170,3) = "def"
1680+
├── operator_loc: ∅
1681+
├── lparen_loc: (170,5)-(170,6) = "("
1682+
├── rparen_loc: (170,7)-(170,8) = ")"
16491683
├── equal_loc: ∅
1650-
└── end_keyword_loc: (168,13)-(168,16) = "end"
1684+
└── end_keyword_loc: (170,15)-(170,18) = "end"

0 commit comments

Comments
 (0)