зеркало из https://github.com/github/ruby.git
[ruby/prism] Correct errors for invalid retry
https://github.com/ruby/prism/commit/96ca6e51fc
This commit is contained in:
Родитель
a83736c27d
Коммит
7d9e5061aa
|
@ -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 },
|
||||
|
|
Загрузка…
Ссылка в новой задаче