merge revision(s) 55694ad7efc3f8dc6d5c7aefa60ded4c303ed6cf: [Backport #21945]

[Bug #21945] Correctly handle `and?` and similar
This commit is contained in:
Takashi Kokubun 2026-03-16 11:55:53 -07:00
parent 0d845e4a07
commit 1d3581e18a
2 changed files with 55 additions and 0 deletions

View File

@ -7010,6 +7010,9 @@ peek_word_at(struct parser_params *p, const char *str, size_t len, int at)
if (lex_eol_ptr_n_p(p, ptr, len-1)) return false;
if (memcmp(ptr, str, len)) return false;
if (lex_eol_ptr_n_p(p, ptr, len)) return true;
switch (ptr[len]) {
case '!': case '?': return false;
}
return !is_identchar(p, ptr+len, p->lex.pend, p->enc);
}

View File

@ -586,6 +586,58 @@ world"
assert_lexer(expected, code)
end
def test_fluent_and
code = "foo\n" "and"
expected = [
[[1, 0], :on_ident, "foo", state(:EXPR_CMDARG)],
[[1, 3], :on_ignored_nl, "\n", state(:EXPR_CMDARG)],
[[2, 0], :on_kw, "and", state(:EXPR_BEG)],
]
assert_lexer(expected, code)
code = "foo\n" "and?"
expected = [
[[1, 0], :on_ident, "foo", state(:EXPR_CMDARG)],
[[1, 3], :on_nl, "\n", state(:EXPR_BEG)],
[[2, 0], :on_ident, "and?", state(:EXPR_CMDARG)],
]
assert_lexer(expected, code)
code = "foo\n" "and!"
expected = [
[[1, 0], :on_ident, "foo", state(:EXPR_CMDARG)],
[[1, 3], :on_nl, "\n", state(:EXPR_BEG)],
[[2, 0], :on_ident, "and!", state(:EXPR_CMDARG)],
]
assert_lexer(expected, code)
end
def test_fluent_or
code = "foo\n" "or"
expected = [
[[1, 0], :on_ident, "foo", state(:EXPR_CMDARG)],
[[1, 3], :on_ignored_nl, "\n", state(:EXPR_CMDARG)],
[[2, 0], :on_kw, "or", state(:EXPR_BEG)],
]
assert_lexer(expected, code)
code = "foo\n" "or?"
expected = [
[[1, 0], :on_ident, "foo", state(:EXPR_CMDARG)],
[[1, 3], :on_nl, "\n", state(:EXPR_BEG)],
[[2, 0], :on_ident, "or?", state(:EXPR_CMDARG)],
]
assert_lexer(expected, code)
code = "foo\n" "or!"
expected = [
[[1, 0], :on_ident, "foo", state(:EXPR_CMDARG)],
[[1, 3], :on_nl, "\n", state(:EXPR_BEG)],
[[2, 0], :on_ident, "or!", state(:EXPR_CMDARG)],
]
assert_lexer(expected, code)
end
def assert_lexer(expected, code)
assert_equal(code, Ripper.tokenize(code).join(""))
assert_equal(expected, result = Ripper.lex(code),