Don't add expansion error offset twice

Like the $status commit, this would add the offset to already existing
errors, so

```fish
(foo)
(bar)

something
```

would see the "(foo)" error, store the correct error location, then
see the "(bar)" error, and *add the offset of (bar)* to the "(foo)"
error location.

Solve this by making a new error list and appending it to the existing
ones.

There's a few other ways to solve this, including:

- Stopping after the first error (we only display the first anyway, I
think?)
- Making it so the source location has an "absolute" flag that shows
the offset has already been added (but do we ever need to add two offsets?)

I went with the simpler fix.
This commit is contained in:
Fabian Homborg
2021-09-28 17:59:59 +02:00
parent 6774a514fa
commit 4ffabd44be
2 changed files with 21 additions and 3 deletions

View File

@@ -1118,13 +1118,14 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
const wcstring &unexp_command = dst.command.source(buff_src, storage);
if (!unexp_command.empty()) {
wcstring command;
// Check that we can expand the command.
// Make a new error list so we can fix the offset for just those, then append later.
wcstring command;
parse_error_list_t new_errors;
if (expand_to_command_and_args(unexp_command, operation_context_t::empty(), &command,
nullptr, parse_errors,
nullptr, &new_errors,
true /* skip wildcards */) == expand_result_t::error) {
errored = true;
parse_error_offset_source_start(parse_errors, source_start);
}
// Check that pipes are sound.
@@ -1174,6 +1175,11 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
unexp_command.c_str());
}
}
if (parse_errors) {
parse_error_offset_source_start(&new_errors, source_start);
vec_append(*parse_errors, std::move(new_errors));
}
}
return errored;
}

View File

@@ -10,3 +10,15 @@ $status
# CHECK: <fish: The 'exec' command can not be used in a pipeline>
# CHECK: <echo foo | exec grep # this exec is not allowed!>
# CHECK: < ^>
echo '
(true one)
(true two)
# more things
' | $fish 2>| string replace -r '(.*)' '<$1>'
# CHECK: <fish: Command substitutions not allowed>
# CHECK: <(true one)>
# CHECK: <^>