[ruby/prism] Correct errors for invalid retry

https://github.com/ruby/prism/commit/96ca6e51fc
This commit is contained in:
Kevin Newton 2024-04-02 11:11:06 -04:00
Родитель a83736c27d
Коммит 7d9e5061aa
3 изменённых файлов: 76 добавлений и 0 удалений

Просмотреть файл

@ -138,6 +138,9 @@ errors:
- INVALID_PRINTABLE_CHARACTER
- INVALID_VARIABLE_GLOBAL
- INVALID_VARIABLE_GLOBAL_3_3_0
- INVALID_RETRY_AFTER_ELSE
- INVALID_RETRY_AFTER_ENSURE
- INVALID_RETRY_WITHOUT_RESCUE
- IT_NOT_ALLOWED_NUMBERED
- IT_NOT_ALLOWED_ORDINARY
- LAMBDA_OPEN

Просмотреть файл

@ -15763,6 +15763,75 @@ parse_block_exit(pm_parser_t *parser, pm_token_t *token) {
}
}
/**
* Ensures that the current retry token is valid in the current context.
*/
static void
parse_retry(pm_parser_t *parser, pm_token_t *token) {
pm_context_node_t *context_node = parser->current_context;
while (context_node != NULL) {
switch (context_node->context) {
case PM_CONTEXT_RESCUE:
case PM_CONTEXT_RESCUE_DEF:
// These are the good cases. We're allowed to have a retry here.
return;
case PM_CONTEXT_CLASS:
case PM_CONTEXT_DEF:
case PM_CONTEXT_DEF_PARAMS:
case PM_CONTEXT_MAIN:
case PM_CONTEXT_MODULE:
case PM_CONTEXT_PREEXE:
case PM_CONTEXT_SCLASS:
// These are the bad cases. We're not allowed to have a retry in
// these contexts.
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, *token, PM_ERR_INVALID_RETRY_WITHOUT_RESCUE);
return;
case PM_CONTEXT_RESCUE_ELSE_DEF:
case PM_CONTEXT_RESCUE_ELSE:
// These are also bad cases, but with a more specific error
// message indicating the else.
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, *token, PM_ERR_INVALID_RETRY_AFTER_ELSE);
return;
case PM_CONTEXT_ENSURE:
case PM_CONTEXT_ENSURE_DEF:
// These are also bad cases, but with a more specific error
// message indicating the ensure.
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, *token, PM_ERR_INVALID_RETRY_AFTER_ENSURE);
return;
case PM_CONTEXT_NONE:
// This case should never happen.
assert(false && "unreachable");
break;
case PM_CONTEXT_BEGIN:
case PM_CONTEXT_BLOCK_BRACES:
case PM_CONTEXT_BLOCK_KEYWORDS:
case PM_CONTEXT_CASE_IN:
case PM_CONTEXT_CASE_WHEN:
case PM_CONTEXT_DEFAULT_PARAMS:
case PM_CONTEXT_ELSE:
case PM_CONTEXT_ELSIF:
case PM_CONTEXT_EMBEXPR:
case PM_CONTEXT_FOR_INDEX:
case PM_CONTEXT_FOR:
case PM_CONTEXT_IF:
case PM_CONTEXT_LAMBDA_BRACES:
case PM_CONTEXT_LAMBDA_DO_END:
case PM_CONTEXT_PARENS:
case PM_CONTEXT_POSTEXE:
case PM_CONTEXT_PREDICATE:
case PM_CONTEXT_UNLESS:
case PM_CONTEXT_UNTIL:
case PM_CONTEXT_WHILE:
// In these contexts we should continue walking up the list of
// contexts.
break;
}
context_node = context_node->prev;
}
}
/**
* Parse an expression that begins with the previous node that we just lexed.
*/
@ -17355,6 +17424,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
parser_lex(parser);
return (pm_node_t *) pm_redo_node_create(parser, &parser->previous);
case PM_TOKEN_KEYWORD_RETRY:
parse_retry(parser, &parser->current);
parser_lex(parser);
return (pm_node_t *) pm_retry_node_create(parser, &parser->previous);
case PM_TOKEN_KEYWORD_SELF:

Просмотреть файл

@ -219,6 +219,9 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
[PM_ERR_INVALID_MULTIBYTE_ESCAPE] = { "invalid multibyte escape: /%.*s/", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_PRINTABLE_CHARACTER] = { "invalid character `%c`", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_PERCENT] = { "invalid `%` token", PM_ERROR_LEVEL_SYNTAX }, // TODO WHAT?
[PM_ERR_INVALID_RETRY_AFTER_ELSE] = { "Invalid retry after else", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_RETRY_AFTER_ENSURE] = { "Invalid retry after ensure", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_RETRY_WITHOUT_RESCUE] = { "Invalid retry without rescue", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_VARIABLE_GLOBAL_3_3_0] = { "`%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_VARIABLE_GLOBAL] = { "'%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "`it` is not allowed when an numbered parameter is defined", PM_ERROR_LEVEL_SYNTAX },