Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f592959

Browse files
committedJun 14, 2024
Ensure ranges are non-associative
1 parent 7cd2407 commit f592959

File tree

4 files changed

+13
-11
lines changed

4 files changed

+13
-11
lines changed
 

‎config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ errors:
267267
- UNEXPECTED_INDEX_BLOCK
268268
- UNEXPECTED_INDEX_KEYWORDS
269269
- UNEXPECTED_MULTI_WRITE
270+
- UNEXPECTED_RANGE_OPERATOR
270271
- UNEXPECTED_SAFE_NAVIGATION
271272
- UNEXPECTED_TOKEN_CLOSE_CONTEXT
272273
- UNEXPECTED_TOKEN_IGNORE

‎src/prism.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17737,6 +17737,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1773717737
parser_lex(parser);
1773817738

1773917739
pm_node_t *right = parse_expression(parser, pm_binding_powers[operator.type].left, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
17740+
17741+
// Unary .. and ... are special because these are non-associative
17742+
// operators that can also be unary operators. In this case we need
17743+
// to explicitly reject code that has a .. or ... that follows this
17744+
// expression.
17745+
if (match2(parser, PM_TOKEN_DOT_DOT, PM_TOKEN_DOT_DOT_DOT)) {
17746+
pm_parser_err_current(parser, PM_ERR_UNEXPECTED_RANGE_OPERATOR);
17747+
}
17748+
1774017749
return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
1774117750
}
1774217751
case PM_TOKEN_FLOAT:
@@ -20987,15 +20996,6 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
2098720996
return node;
2098820997
}
2098920998
break;
20990-
case PM_RANGE_NODE:
20991-
// Range operators are non-associative, so that it does not
20992-
// associate with other range operators (i.e. `..1..` should be
20993-
// rejected). For this reason, we check such a case for unary ranges
20994-
// here, and if so, it returns the node immediately.
20995-
if ((((pm_range_node_t *) node)->left == NULL) && pm_binding_powers[parser->current.type].left >= PM_BINDING_POWER_RANGE) {
20996-
return node;
20997-
}
20998-
break;
2099920999
default:
2100021000
break;
2100121001
}

‎templates/src/diagnostic.c.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
348348
[PM_ERR_UNEXPECTED_INDEX_BLOCK] = { "unexpected block arg given in index assignment; blocks are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX },
349349
[PM_ERR_UNEXPECTED_INDEX_KEYWORDS] = { "unexpected keyword arg given in index assignment; keywords are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX },
350350
[PM_ERR_UNEXPECTED_MULTI_WRITE] = { "unexpected multiple assignment; multiple assignment is not allowed in this context", PM_ERROR_LEVEL_SYNTAX },
351+
[PM_ERR_UNEXPECTED_RANGE_OPERATOR] = { "unexpected range operator; .. and ... are non-associative and cannot be chained", PM_ERROR_LEVEL_SYNTAX },
351352
[PM_ERR_UNEXPECTED_SAFE_NAVIGATION] = { "&. inside multiple assignment destination", PM_ERROR_LEVEL_SYNTAX },
352353
[PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT] = { "unexpected %s, assuming it is closing the parent %s", PM_ERROR_LEVEL_SYNTAX },
353354
[PM_ERR_UNEXPECTED_TOKEN_IGNORE] = { "unexpected %s, ignoring it", PM_ERROR_LEVEL_SYNTAX },

‎test/prism/errors_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,8 +1975,8 @@ def test_binary_range_with_left_unary_range
19751975
RUBY
19761976

19771977
assert_errors expression(source), source, [
1978-
["unexpected .., expecting end-of-input", 3..5],
1979-
["unexpected .., ignoring it", 3..5],
1978+
["unexpected range operator; .. and ... are non-associative and cannot be chained", 3..5],
1979+
["unexpected range operator; .. and ... are non-associative and cannot be chained", 10..12],
19801980
["unexpected .., expecting end-of-input", 10..12],
19811981
["unexpected .., ignoring it", 10..12]
19821982
]

0 commit comments

Comments
 (0)
Please sign in to comment.