Inside an unclosed subshell, do not report other parse errors

In an interactive shell, typing "for x in (<RET>" would print an error:

	fish: Expected end of the statement, but found a parse_token_type_t::tokenizer_error

Our tokenizer converts "(" into a special error token, hence this message.
Fix two cases by not reporting errors, but only if we allow parsing incomplete
input. I'm not really sure if this is necessary, but it's sufficient.

Fixes #7693
This commit is contained in:
Johannes Altmanninger 2021-02-09 22:06:59 +01:00
parent e423a58e24
commit 38b95defbd
2 changed files with 18 additions and 0 deletions

View File

@ -1111,6 +1111,11 @@ class ast_t::populator_t {
if (!token.allows_token(peek_token().type)) {
const auto &peek = peek_token();
if ((flags_ & parse_flag_leave_unterminated) &&
peek.tok_error == tokenizer_error_t::unterminated_subshell) {
return;
}
parse_error(peek, parse_error_generic, L"Expected %ls, but found %ls",
token_types_user_presentable_description({TokTypes...}).c_str(),
peek.user_presentable_description().c_str());
@ -1134,6 +1139,11 @@ class ast_t::populator_t {
keyword.unsourced = true;
const auto &peek = peek_token();
if ((flags_ & parse_flag_leave_unterminated) &&
peek.tok_error == tokenizer_error_t::unterminated_subshell) {
return;
}
// Special error reporting for keyword_t<kw_end>.
std::array<parse_keyword_t, sizeof...(KWs)> allowed = {{KWs...}};
if (allowed.size() == 1 && allowed[0] == parse_keyword_t::kw_end) {

View File

@ -4790,6 +4790,14 @@ static void test_new_parser_ad_hoc() {
// because we don't want to color it as an error.
ast = ast_t::parse(L"a=", parse_flag_leave_unterminated);
do_test(!ast.errored());
parse_error_list_t errors;
ast = ast_t::parse(L"begin; echo (", parse_flag_leave_unterminated, &errors);
do_test(errors.size() == 1 && errors.at(0).code == parse_error_tokenizer_unterminated_subshell);
errors.clear();
ast = ast_t::parse(L"for x in (", parse_flag_leave_unterminated, &errors);
do_test(errors.size() == 1 && errors.at(0).code == parse_error_tokenizer_unterminated_subshell);
}
static void test_new_parser_errors() {