Skip to content

Commit 1ad7fba

Browse files
committed
Handle missing clauses in case statement
1 parent b700c29 commit 1ad7fba

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

include/yarp/diagnostic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ typedef enum {
5050
YP_ERR_CANNOT_PARSE_STRING_PART,
5151
YP_ERR_CASE_EXPRESSION_AFTER_CASE,
5252
YP_ERR_CASE_EXPRESSION_AFTER_WHEN,
53-
YP_ERR_CASE_LONELY_ELSE,
53+
YP_ERR_CASE_MISSING_CONDITIONS,
5454
YP_ERR_CASE_TERM,
5555
YP_ERR_CLASS_IN_METHOD,
5656
YP_ERR_CLASS_NAME,

src/diagnostic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static const char* const diagnostic_messages[YP_DIAGNOSTIC_ID_LEN] = {
8585
[YP_ERR_CANNOT_PARSE_STRING_PART] = "Cannot parse the string part",
8686
[YP_ERR_CASE_EXPRESSION_AFTER_CASE] = "Expected an expression after `case`",
8787
[YP_ERR_CASE_EXPRESSION_AFTER_WHEN] = "Expected an expression after `when`",
88-
[YP_ERR_CASE_LONELY_ELSE] = "Unexpected `else` in `case` statement; a `when` clause must precede `else`",
88+
[YP_ERR_CASE_MISSING_CONDITIONS] = "Expected a `when` or `in` clause after `case`",
8989
[YP_ERR_CASE_TERM] = "Expected an `end` to close the `case` statement",
9090
[YP_ERR_CLASS_IN_METHOD] = "Unexpected class definition in a method body",
9191
[YP_ERR_CLASS_NAME] = "Expected a constant name after `class`",

src/yarp.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11935,6 +11935,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
1193511935
}
1193611936

1193711937
if (accept1(parser, YP_TOKEN_KEYWORD_END)) {
11938+
yp_diagnostic_list_append(&parser->error_list, case_keyword.start, case_keyword.end, YP_ERR_CASE_MISSING_CONDITIONS);
1193811939
return (yp_node_t *) yp_case_node_create(parser, &case_keyword, predicate, NULL, &parser->previous);
1193911940
}
1194011941

@@ -12041,12 +12042,14 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
1204112042
}
1204212043
}
1204312044

12045+
// If we didn't parse any conditions (in or when) then we need to
12046+
// indicate that we have an error.
12047+
if (case_node->conditions.size == 0) {
12048+
yp_diagnostic_list_append(&parser->error_list, case_keyword.start, case_keyword.end, YP_ERR_CASE_MISSING_CONDITIONS);
12049+
}
12050+
1204412051
accept2(parser, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
1204512052
if (accept1(parser, YP_TOKEN_KEYWORD_ELSE)) {
12046-
if (case_node->conditions.size < 1) {
12047-
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_CASE_LONELY_ELSE);
12048-
}
12049-
1205012053
yp_token_t else_keyword = parser->previous;
1205112054
yp_else_node_t *else_node;
1205212055

test/yarp/errors_test.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,21 @@ def test_case_without_when_clauses_errors_on_else_clause
949949
)
950950

951951
assert_errors expected, "case :a\nelse\nend", [
952-
["Unexpected `else` in `case` statement; a `when` clause must precede `else`", 8..12]
952+
["Expected a `when` or `in` clause after `case`", 0..4]
953+
]
954+
end
955+
956+
def test_case_without_clauses
957+
expected = CaseNode(
958+
SymbolNode(Location(), Location(), nil, "a"),
959+
[],
960+
nil,
961+
Location(),
962+
Location()
963+
)
964+
965+
assert_errors expected, "case :a\nend", [
966+
["Expected a `when` or `in` clause after `case`", 0..4]
953967
]
954968
end
955969

0 commit comments

Comments
 (0)