From 0a630fa461a7260235842e482f682deca30172d6 Mon Sep 17 00:00:00 2001 From: Haldun Bayhantopcu Date: Wed, 20 Sep 2023 10:36:26 +0200 Subject: [ruby/yarp] Check whether the conditional predicate is closed https://github.com/ruby/yarp/commit/5022b51db2 --- test/yarp/errors_test.rb | 8 ++++++++ yarp/diagnostic.c | 1 + yarp/diagnostic.h | 1 + yarp/yarp.c | 7 +++++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb index 5a4d469c26..110834428b 100644 --- a/test/yarp/errors_test.rb +++ b/test/yarp/errors_test.rb @@ -1302,6 +1302,14 @@ module YARP assert_error_messages "%sXfooX", error_messages end + def test_conditional_predicate_closed + source = "if 0 0; end\nunless 0 0; end" + assert_errors expression(source), source, [ + ["Expected `then` or `;` or '\n" + "'", 5..6], + ["Expected `then` or `;` or '\n" + "'", 21..22], + ] + end + private def assert_errors(expected, source, errors, compare_ripper: RUBY_ENGINE == "ruby") diff --git a/yarp/diagnostic.c b/yarp/diagnostic.c index 34da3f97a5..68e6a412fb 100644 --- a/yarp/diagnostic.c +++ b/yarp/diagnostic.c @@ -93,6 +93,7 @@ static const char* const diagnostic_messages[YP_DIAGNOSTIC_ID_LEN] = { [YP_ERR_CLASS_TERM] = "Expected an `end` to close the `class` statement", [YP_ERR_CONDITIONAL_ELSIF_PREDICATE] = "Expected a predicate expression for the `elsif` statement", [YP_ERR_CONDITIONAL_IF_PREDICATE] = "Expected a predicate expression for the `if` statement", + [YP_ERR_CONDITIONAL_PREDICATE_TERM] = "Expected `then` or `;` or '\n'", [YP_ERR_CONDITIONAL_TERM] = "Expected an `end` to close the conditional clause", [YP_ERR_CONDITIONAL_TERM_ELSE] = "Expected an `end` to close the `else` clause", [YP_ERR_CONDITIONAL_UNLESS_PREDICATE] = "Expected a predicate expression for the `unless` statement", diff --git a/yarp/diagnostic.h b/yarp/diagnostic.h index b8d9fe0100..9de36650fc 100644 --- a/yarp/diagnostic.h +++ b/yarp/diagnostic.h @@ -58,6 +58,7 @@ typedef enum { YP_ERR_CLASS_TERM, YP_ERR_CONDITIONAL_ELSIF_PREDICATE, YP_ERR_CONDITIONAL_IF_PREDICATE, + YP_ERR_CONDITIONAL_PREDICATE_TERM, YP_ERR_CONDITIONAL_TERM, YP_ERR_CONDITIONAL_TERM_ELSE, YP_ERR_CONDITIONAL_UNLESS_PREDICATE, diff --git a/yarp/yarp.c b/yarp/yarp.c index ddaecc2c84..73d2489225 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -9814,8 +9814,11 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) { yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, error_id); // Predicates are closed by a term, a "then", or a term and then a "then". - accept2(parser, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - accept1(parser, YP_TOKEN_KEYWORD_THEN); + bool predicate_closed = accept2(parser, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); + predicate_closed |= accept1(parser, YP_TOKEN_KEYWORD_THEN); + if (!predicate_closed) { + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_CONDITIONAL_PREDICATE_TERM); + } context_pop(parser); yp_statements_node_t *statements = NULL; -- cgit v1.2.3