mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 23:24:39 +00:00
Teach parse_util_detect_errors about unterminated pipelines
Allow it to return PARSER_TEST_INCOMPLETE for code like `echo | `
This commit is contained in:
parent
26ea8dc362
commit
ddd1afc57c
2 changed files with 21 additions and 1 deletions
|
@ -727,6 +727,18 @@ static void test_parser() {
|
|||
err(L"redirection after 'end' wrongly reported as error");
|
||||
}
|
||||
|
||||
if (parse_util_detect_errors(L"true | ") != PARSER_TEST_INCOMPLETE) {
|
||||
err(L"unterminated pipe not reported properly");
|
||||
}
|
||||
|
||||
if (parse_util_detect_errors(L"begin ; true ; end | ") != PARSER_TEST_INCOMPLETE) {
|
||||
err(L"unterminated pipe not reported properly");
|
||||
}
|
||||
|
||||
if (parse_util_detect_errors(L" | true ") != PARSER_TEST_ERROR) {
|
||||
err(L"leading pipe not reported properly");
|
||||
}
|
||||
|
||||
if (detect_argument_errors(L"foo")) {
|
||||
err(L"simple argument reported as error");
|
||||
}
|
||||
|
|
|
@ -1198,6 +1198,10 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
|
|||
// source.
|
||||
bool has_unclosed_block = false;
|
||||
|
||||
// Whether we encounter a missing statement, i.e. a newline after a pipe. This is found by
|
||||
// detecting job_continuations that have source for pipes but not the statement.
|
||||
bool has_unclosed_pipe = false;
|
||||
|
||||
// Whether there's an unclosed quote, and therefore unfinished. This is only set if
|
||||
// allow_incomplete is set.
|
||||
bool has_unclosed_quote = false;
|
||||
|
@ -1243,6 +1247,9 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
|
|||
if (node.type == symbol_end_command && !node.has_source()) {
|
||||
// An 'end' without source is an unclosed block.
|
||||
has_unclosed_block = true;
|
||||
} else if (node.type == symbol_statement && !node.has_source()) {
|
||||
// Check for a statement without source in a pipeline, i.e. unterminated pipeline.
|
||||
has_unclosed_pipe |= statement_is_in_pipeline({&node_tree, &node}, false);
|
||||
} else if (node.type == symbol_boolean_statement) {
|
||||
// 'or' and 'and' can be in a pipeline, as long as they're first.
|
||||
tnode_t<g::boolean_statement> gbs{&node_tree, &node};
|
||||
|
@ -1290,7 +1297,8 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
|
|||
|
||||
if (errored) res |= PARSER_TEST_ERROR;
|
||||
|
||||
if (has_unclosed_block || has_unclosed_quote) res |= PARSER_TEST_INCOMPLETE;
|
||||
if (has_unclosed_block || has_unclosed_quote || has_unclosed_pipe)
|
||||
res |= PARSER_TEST_INCOMPLETE;
|
||||
|
||||
if (out_errors != NULL) {
|
||||
*out_errors = std::move(parse_errors);
|
||||
|
|
Loading…
Reference in a new issue