Skip to content

Commit a3a218b

Browse files
Validate ParametersNode
1 parent ec662f5 commit a3a218b

3 files changed

Lines changed: 13 additions & 11 deletions

File tree

config.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4044,11 +4044,7 @@ nodes:
40444044
kind:
40454045
- RequiredParameterNode
40464046
- MultiTargetNode
4047-
# On parsing error of `f(**kwargs, ...)` or `f(**nil, ...)`, the keyword_rest value is moved here:
4048-
- on error: KeywordRestParameterNode
4049-
- on error: NoKeywordsParameterNode
4050-
# On parsing error of `f(..., ...)`, the first forwarding parameter is moved here:
4051-
- on error: ForwardingParameterNode
4047+
- on error: ErrorRecoveryNode
40524048
- name: keywords
40534049
type: node[]
40544050
kind:

src/prism.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13944,7 +13944,9 @@ parse_parameters(
1394413944
pm_parameters_node_block_set(params, param);
1394513945
} else {
1394613946
pm_parser_err_node(parser, UP(param), PM_ERR_PARAMETER_BLOCK_MULTI);
13947-
pm_parameters_node_posts_append(params, UP(param));
13947+
pm_node_t *post_param = UP(param);
13948+
PM_VALIDATE_NODE_TYPE(parser, post_param, PM_REQUIRED_PARAMETER_NODE, PM_MULTI_TARGET_NODE);
13949+
pm_parameters_node_posts_append(params, post_param);
1394813950
}
1394913951

1395013952
break;
@@ -13964,6 +13966,7 @@ parse_parameters(
1396413966
// If we already have a keyword rest parameter, then we replace it with the
1396513967
// forwarding parameter and move the keyword rest parameter to the posts list.
1396613968
pm_node_t *keyword_rest = params->keyword_rest;
13969+
PM_VALIDATE_NODE_TYPE(parser, keyword_rest, PM_REQUIRED_PARAMETER_NODE, PM_MULTI_TARGET_NODE);
1396713970
pm_parameters_node_posts_append(params, keyword_rest);
1396813971
if (succeeded) pm_parser_err_previous(parser, PM_ERR_PARAMETER_UNEXPECTED_FWD);
1396913972
params->keyword_rest = NULL;
@@ -14178,6 +14181,7 @@ parse_parameters(
1417814181
pm_parameters_node_rest_set(params, param);
1417914182
} else {
1418014183
pm_parser_err_node(parser, param, PM_ERR_PARAMETER_SPLAT_MULTI);
14184+
PM_VALIDATE_NODE_TYPE(parser, param, PM_REQUIRED_PARAMETER_NODE, PM_MULTI_TARGET_NODE);
1418114185
pm_parameters_node_posts_append(params, param);
1418214186
}
1418314187

@@ -14221,6 +14225,7 @@ parse_parameters(
1422114225
pm_parameters_node_keyword_rest_set(params, param);
1422214226
} else {
1422314227
pm_parser_err_node(parser, param, PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI);
14228+
PM_VALIDATE_NODE_TYPE(parser, param, PM_REQUIRED_PARAMETER_NODE, PM_MULTI_TARGET_NODE);
1422414229
pm_parameters_node_posts_append(params, param);
1422514230
}
1422614231

@@ -14236,8 +14241,9 @@ parse_parameters(
1423614241
if (params->rest == NULL) {
1423714242
pm_parameters_node_rest_set(params, param);
1423814243
} else {
14239-
pm_parser_err_node(parser, UP(param), PM_ERR_PARAMETER_SPLAT_MULTI);
14240-
pm_parameters_node_posts_append(params, UP(param));
14244+
pm_parser_err_node(parser, param, PM_ERR_PARAMETER_SPLAT_MULTI);
14245+
PM_VALIDATE_NODE_TYPE(parser, param, PM_REQUIRED_PARAMETER_NODE, PM_MULTI_TARGET_NODE);
14246+
pm_parameters_node_posts_append(params, param);
1424114247
}
1424214248
} else {
1424314249
pm_parser_err_previous(parser, PM_ERR_PARAMETER_WILD_LOOSE_COMMA);

test/prism/result/error_recovery_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,23 +170,23 @@ def test_parameters_node_posts_keyword_rest
170170
refute result.success?
171171

172172
node = result.value.statements.body.first.parameters
173-
assert node.posts.any? { |post| post.is_a?(KeywordRestParameterNode) }
173+
assert node.posts.any? { |post| post.is_a?(ErrorRecoveryNode) && post.child.is_a?(KeywordRestParameterNode) }
174174
end
175175

176176
def test_parameters_node_posts_no_keywords
177177
result = Prism.parse("def f(**nil, ...); end")
178178
refute result.success?
179179

180180
node = result.value.statements.body.first.parameters
181-
assert node.posts.any? { |post| post.is_a?(NoKeywordsParameterNode) }
181+
assert node.posts.any? { |post| post.is_a?(ErrorRecoveryNode) && post.child.is_a?(NoKeywordsParameterNode) }
182182
end
183183

184184
def test_parameters_node_posts_forwarding
185185
result = Prism.parse("def f(..., ...); end")
186186
refute result.success?
187187

188188
node = result.value.statements.body.first.parameters
189-
assert node.posts.any? { |post| post.is_a?(ForwardingParameterNode) }
189+
assert node.posts.any? { |post| post.is_a?(ErrorRecoveryNode) && post.child.is_a?(ForwardingParameterNode) }
190190
end
191191

192192
def test_pinned_variable_node_variable_missing

0 commit comments

Comments
 (0)