[ruby/yarp] Handle missing clauses in case statement

https://github.com/ruby/yarp/commit/1ad7fba5ef
This commit is contained in:
Kevin Newton 2023-09-15 11:09:18 -04:00 коммит произвёл git
Родитель 4c28a61e83
Коммит cb686b9ccc
4 изменённых файлов: 24 добавлений и 7 удалений

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

@ -949,7 +949,21 @@ module YARP
)
assert_errors expected, "case :a\nelse\nend", [
["Unexpected `else` in `case` statement; a `when` clause must precede `else`", 8..12]
["Expected a `when` or `in` clause after `case`", 0..4]
]
end
def test_case_without_clauses
expected = CaseNode(
SymbolNode(Location(), Location(), nil, "a"),
[],
nil,
Location(),
Location()
)
assert_errors expected, "case :a\nend", [
["Expected a `when` or `in` clause after `case`", 0..4]
]
end

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

@ -85,7 +85,7 @@ static const char* const diagnostic_messages[YP_DIAGNOSTIC_ID_LEN] = {
[YP_ERR_CANNOT_PARSE_STRING_PART] = "Cannot parse the string part",
[YP_ERR_CASE_EXPRESSION_AFTER_CASE] = "Expected an expression after `case`",
[YP_ERR_CASE_EXPRESSION_AFTER_WHEN] = "Expected an expression after `when`",
[YP_ERR_CASE_LONELY_ELSE] = "Unexpected `else` in `case` statement; a `when` clause must precede `else`",
[YP_ERR_CASE_MISSING_CONDITIONS] = "Expected a `when` or `in` clause after `case`",
[YP_ERR_CASE_TERM] = "Expected an `end` to close the `case` statement",
[YP_ERR_CLASS_IN_METHOD] = "Unexpected class definition in a method body",
[YP_ERR_CLASS_NAME] = "Expected a constant name after `class`",

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

@ -50,7 +50,7 @@ typedef enum {
YP_ERR_CANNOT_PARSE_STRING_PART,
YP_ERR_CASE_EXPRESSION_AFTER_CASE,
YP_ERR_CASE_EXPRESSION_AFTER_WHEN,
YP_ERR_CASE_LONELY_ELSE,
YP_ERR_CASE_MISSING_CONDITIONS,
YP_ERR_CASE_TERM,
YP_ERR_CLASS_IN_METHOD,
YP_ERR_CLASS_NAME,

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

@ -11935,6 +11935,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
if (accept1(parser, YP_TOKEN_KEYWORD_END)) {
yp_diagnostic_list_append(&parser->error_list, case_keyword.start, case_keyword.end, YP_ERR_CASE_MISSING_CONDITIONS);
return (yp_node_t *) yp_case_node_create(parser, &case_keyword, predicate, NULL, &parser->previous);
}
@ -12041,12 +12042,14 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
}
// If we didn't parse any conditions (in or when) then we need to
// indicate that we have an error.
if (case_node->conditions.size == 0) {
yp_diagnostic_list_append(&parser->error_list, case_keyword.start, case_keyword.end, YP_ERR_CASE_MISSING_CONDITIONS);
}
accept2(parser, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
if (accept1(parser, YP_TOKEN_KEYWORD_ELSE)) {
if (case_node->conditions.size < 1) {
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_CASE_LONELY_ELSE);
}
yp_token_t else_keyword = parser->previous;
yp_else_node_t *else_node;