[ruby/prism] Fix parsing ...
in arguments
(https://github.com/ruby/prism/pull/1882) * Fix parsing `...` in arguments Fix https://github.com/ruby/prism/pull/1830 Fix https://github.com/ruby/prism/pull/1831 * Rename the constant name to PM_ERR_ARGUMENT_FORWARDING_UNBOUND https://github.com/ruby/prism/pull/1882#discussion_r1398461156 https://github.com/ruby/prism/commit/519653aec2
This commit is contained in:
parent
83da4a7e62
commit
caa9ae7804
@ -54,12 +54,14 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
||||
[PM_ERR_ALIAS_ARGUMENT] = "Invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable",
|
||||
[PM_ERR_AMPAMPEQ_MULTI_ASSIGN] = "Unexpected `&&=` in a multiple assignment",
|
||||
[PM_ERR_ARGUMENT_AFTER_BLOCK] = "Unexpected argument after a block argument",
|
||||
[PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES] = "Unexpected argument after `...`",
|
||||
[PM_ERR_ARGUMENT_BARE_HASH] = "Unexpected bare hash argument",
|
||||
[PM_ERR_ARGUMENT_BLOCK_MULTI] = "Multiple block arguments; only one block is allowed",
|
||||
[PM_ERR_ARGUMENT_FORMAL_CLASS] = "Invalid formal argument; formal argument cannot be a class variable",
|
||||
[PM_ERR_ARGUMENT_FORMAL_CONSTANT] = "Invalid formal argument; formal argument cannot be a constant",
|
||||
[PM_ERR_ARGUMENT_FORMAL_GLOBAL] = "Invalid formal argument; formal argument cannot be a global variable",
|
||||
[PM_ERR_ARGUMENT_FORMAL_IVAR] = "Invalid formal argument; formal argument cannot be an instance variable",
|
||||
[PM_ERR_ARGUMENT_FORWARDING_UNBOUND] = "Unexpected `...` in an non-parenthesized call",
|
||||
[PM_ERR_ARGUMENT_NO_FORWARDING_AMP] = "Unexpected `&` when the parent method is not forwarding",
|
||||
[PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = "Unexpected `...` when the parent method is not forwarding",
|
||||
[PM_ERR_ARGUMENT_NO_FORWARDING_STAR] = "Unexpected `*` when the parent method is not forwarding",
|
||||
|
@ -40,12 +40,14 @@ typedef enum {
|
||||
PM_ERR_ALIAS_ARGUMENT,
|
||||
PM_ERR_AMPAMPEQ_MULTI_ASSIGN,
|
||||
PM_ERR_ARGUMENT_AFTER_BLOCK,
|
||||
PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES,
|
||||
PM_ERR_ARGUMENT_BARE_HASH,
|
||||
PM_ERR_ARGUMENT_BLOCK_MULTI,
|
||||
PM_ERR_ARGUMENT_FORMAL_CLASS,
|
||||
PM_ERR_ARGUMENT_FORMAL_CONSTANT,
|
||||
PM_ERR_ARGUMENT_FORMAL_GLOBAL,
|
||||
PM_ERR_ARGUMENT_FORMAL_IVAR,
|
||||
PM_ERR_ARGUMENT_FORWARDING_UNBOUND,
|
||||
PM_ERR_ARGUMENT_NO_FORWARDING_AMP,
|
||||
PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES,
|
||||
PM_ERR_ARGUMENT_NO_FORWARDING_STAR,
|
||||
|
@ -11039,13 +11039,18 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
||||
return;
|
||||
}
|
||||
|
||||
bool parsed_first_argument = false;
|
||||
bool parsed_bare_hash = false;
|
||||
bool parsed_block_argument = false;
|
||||
bool parsed_forwarding_arguments = false;
|
||||
|
||||
while (!match1(parser, PM_TOKEN_EOF)) {
|
||||
if (parsed_block_argument) {
|
||||
pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_BLOCK);
|
||||
}
|
||||
if (parsed_forwarding_arguments) {
|
||||
pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES);
|
||||
}
|
||||
|
||||
pm_node_t *argument = NULL;
|
||||
|
||||
@ -11129,9 +11134,13 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
||||
if (pm_parser_local_depth(parser, &parser->previous) == -1) {
|
||||
pm_parser_err_previous(parser, PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES);
|
||||
}
|
||||
if (parsed_first_argument && terminator == PM_TOKEN_EOF) {
|
||||
pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORWARDING_UNBOUND);
|
||||
}
|
||||
|
||||
argument = (pm_node_t *) pm_forwarding_arguments_node_create(parser, &parser->previous);
|
||||
parse_arguments_append(parser, arguments, argument);
|
||||
parsed_forwarding_arguments = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -11183,6 +11192,8 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
||||
}
|
||||
}
|
||||
|
||||
parsed_first_argument = true;
|
||||
|
||||
// If parsing the argument failed, we need to stop parsing arguments.
|
||||
if (PM_NODE_TYPE_P(argument, PM_MISSING_NODE) || parser->recovering) break;
|
||||
|
||||
|
@ -1682,6 +1682,20 @@ module Prism
|
||||
]
|
||||
end
|
||||
|
||||
def test_argument_after_ellipsis
|
||||
source = 'def foo(...); foo(..., 1); end'
|
||||
assert_errors expression(source), source, [
|
||||
['Unexpected argument after `...`', 23..24]
|
||||
]
|
||||
end
|
||||
|
||||
def test_ellipsis_in_no_paren_call
|
||||
source = 'def foo(...); foo 1, ...; end'
|
||||
assert_errors expression(source), source, [
|
||||
['Unexpected `...` in an non-parenthesized call', 21..24]
|
||||
]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assert_errors(expected, source, errors, compare_ripper: RUBY_ENGINE == "ruby")
|
||||
|
Loading…
x
Reference in New Issue
Block a user