forked from extern/nushell
Cut down on unnecessary parsing for SyntaxShape::Any (#9280)
# Description This removes some unnecessary SyntaxShapes when parsing a SyntaxShape::Any. Recent updates to the parser look for `{` and then handle the logic for that separately. # User-Facing Changes This may have a slight parser speedup. # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
parent
74724dee80
commit
7ead89844a
@ -1248,7 +1248,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_lots_of_files() {
|
||||
// this is a good test because it touches lots of differently named files
|
||||
glob("/*/*/*/*").unwrap().skip(10000).next();
|
||||
glob("/*/*/*/*").unwrap().nth(10000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1368,7 +1368,7 @@ pub fn parse_export_in_module(
|
||||
}
|
||||
_ => {
|
||||
working_set.error(ParseError::Expected(
|
||||
"def, def-env, alias, use, module, or extern keyword".into(),
|
||||
"def, def-env, alias, use, module, or extern keyword",
|
||||
spans[1],
|
||||
));
|
||||
|
||||
@ -1713,7 +1713,7 @@ pub fn parse_module_block(
|
||||
} => block.pipelines.push(garbage_pipeline(&command.parts)),
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("not a pipeline".into(), span));
|
||||
working_set.error(ParseError::Expected("not a pipeline", span));
|
||||
block.pipelines.push(garbage_pipeline(&[span]))
|
||||
}
|
||||
}
|
||||
@ -2042,7 +2042,7 @@ pub fn parse_module(
|
||||
if block_bytes.starts_with(b"{") {
|
||||
start += 1;
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("block".into(), block_span));
|
||||
working_set.error(ParseError::Expected("block", block_span));
|
||||
return (garbage_pipeline(spans), None);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ pub fn parse_variable_pattern(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
span,
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("valid variable name".into(), span));
|
||||
working_set.error(ParseError::Expected("valid variable name", span));
|
||||
garbage(span)
|
||||
}
|
||||
}
|
||||
@ -145,7 +145,7 @@ pub fn parse_list_pattern(working_set: &mut StateWorkingSet, span: Span) -> Matc
|
||||
} else {
|
||||
args.push(garbage(command.parts[spans_idx]));
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name".into(),
|
||||
"valid variable name",
|
||||
command.parts[spans_idx],
|
||||
));
|
||||
}
|
||||
@ -176,10 +176,7 @@ pub fn parse_record_pattern(working_set: &mut StateWorkingSet, span: Span) -> Ma
|
||||
if bytes.starts_with(b"{") {
|
||||
start += 1;
|
||||
} else {
|
||||
working_set.error(ParseError::Expected(
|
||||
"{".into(),
|
||||
Span::new(start, start + 1),
|
||||
));
|
||||
working_set.error(ParseError::Expected("{", Span::new(start, start + 1)));
|
||||
bytes = working_set.get_span_contents(span);
|
||||
}
|
||||
|
||||
@ -214,14 +211,14 @@ pub fn parse_record_pattern(working_set: &mut StateWorkingSet, span: Span) -> Ma
|
||||
|
||||
idx += 1;
|
||||
if idx == tokens.len() {
|
||||
working_set.error(ParseError::Expected("record".into(), span));
|
||||
working_set.error(ParseError::Expected("record", span));
|
||||
return garbage(span);
|
||||
}
|
||||
let colon = working_set.get_span_contents(tokens[idx].span);
|
||||
idx += 1;
|
||||
if idx == tokens.len() || colon != b":" {
|
||||
//FIXME: need better error
|
||||
working_set.error(ParseError::Expected("record".into(), span));
|
||||
working_set.error(ParseError::Expected("record", span));
|
||||
return garbage(span);
|
||||
}
|
||||
let pattern = parse_pattern(working_set, tokens[idx].span);
|
||||
|
@ -636,7 +636,10 @@ pub fn parse_multispan_value(
|
||||
|
||||
if starting_error_count == working_set.parse_errors.len() {
|
||||
return s;
|
||||
} else if let Some(ParseError::Expected(..)) = working_set.parse_errors.last() {
|
||||
} else if let Some(
|
||||
ParseError::Expected(..) | ParseError::ExpectedWithStringMsg(..),
|
||||
) = working_set.parse_errors.last()
|
||||
{
|
||||
working_set.parse_errors.truncate(starting_error_count);
|
||||
continue;
|
||||
}
|
||||
@ -664,7 +667,7 @@ pub fn parse_multispan_value(
|
||||
let span = spans[*spans_idx];
|
||||
|
||||
if working_set.parse_errors.is_empty() {
|
||||
working_set.error(ParseError::Expected(
|
||||
working_set.error(ParseError::ExpectedWithStringMsg(
|
||||
format!("one of a list of accepted shapes: {shapes:?}"),
|
||||
span,
|
||||
));
|
||||
@ -1177,8 +1180,11 @@ pub fn parse_binary(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
parse_binary_with_base(working_set, span, 16, 2, b"0x[", b"]")
|
||||
} else if contents.starts_with(b"0o[") {
|
||||
parse_binary_with_base(working_set, span, 8, 3, b"0o[", b"]")
|
||||
} else {
|
||||
} else if contents.starts_with(b"0b[") {
|
||||
parse_binary_with_base(working_set, span, 2, 8, b"0b[", b"]")
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("binary", span));
|
||||
garbage(span)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1218,7 +1224,7 @@ fn parse_binary_with_base(
|
||||
| TokenContents::OutGreaterThan
|
||||
| TokenContents::ErrGreaterThan
|
||||
| TokenContents::OutErrGreaterThan => {
|
||||
working_set.error(ParseError::Expected("binary".into(), span));
|
||||
working_set.error(ParseError::Expected("binary", span));
|
||||
return garbage(span);
|
||||
}
|
||||
TokenContents::Comment | TokenContents::Semicolon | TokenContents::Eol => {}
|
||||
@ -1260,7 +1266,7 @@ fn parse_binary_with_base(
|
||||
}
|
||||
}
|
||||
|
||||
working_set.error(ParseError::Expected("binary".into(), span));
|
||||
working_set.error(ParseError::Expected("binary", span));
|
||||
garbage(span)
|
||||
}
|
||||
|
||||
@ -1312,7 +1318,7 @@ pub fn parse_int(working_set: &mut StateWorkingSet, span: Span) -> Expression {
|
||||
let token = strip_underscores(token);
|
||||
|
||||
if token.is_empty() {
|
||||
working_set.error(ParseError::Expected("int".into(), span));
|
||||
working_set.error(ParseError::Expected("int", span));
|
||||
return garbage(span);
|
||||
}
|
||||
|
||||
@ -1330,7 +1336,7 @@ pub fn parse_int(working_set: &mut StateWorkingSet, span: Span) -> Expression {
|
||||
custom_completion: None,
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("int".into(), span));
|
||||
working_set.error(ParseError::Expected("int", span));
|
||||
garbage(span)
|
||||
}
|
||||
}
|
||||
@ -1347,7 +1353,7 @@ pub fn parse_float(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
custom_completion: None,
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("float".into(), span));
|
||||
working_set.error(ParseError::Expected("float", span));
|
||||
|
||||
garbage(span)
|
||||
}
|
||||
@ -1374,7 +1380,7 @@ pub fn parse_number(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
}
|
||||
working_set.parse_errors.truncate(starting_error_count);
|
||||
|
||||
working_set.error(ParseError::Expected("number".into(), span));
|
||||
working_set.error(ParseError::Expected("number", span));
|
||||
garbage(span)
|
||||
}
|
||||
|
||||
@ -1398,10 +1404,7 @@ pub fn parse_range(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
};
|
||||
|
||||
if !token.contains("..") {
|
||||
working_set.error(ParseError::Expected(
|
||||
"at least one range bound set".into(),
|
||||
span,
|
||||
));
|
||||
working_set.error(ParseError::Expected("at least one range bound set", span));
|
||||
return garbage(span);
|
||||
}
|
||||
|
||||
@ -1413,7 +1416,7 @@ pub fn parse_range(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
2 => (Some(dotdot_pos[0]), dotdot_pos[1]),
|
||||
_ => {
|
||||
working_set.error(ParseError::Expected(
|
||||
"one range operator ('..' or '..<') and optionally one next operator ('..')".into(),
|
||||
"one range operator ('..' or '..<') and optionally one next operator ('..')",
|
||||
span,
|
||||
));
|
||||
return garbage(span);
|
||||
@ -1430,7 +1433,7 @@ pub fn parse_range(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
(RangeInclusion::RightExclusive, "..<", op_span)
|
||||
} else {
|
||||
working_set.error(ParseError::Expected(
|
||||
"inclusive operator preceding second range bound".into(),
|
||||
"inclusive operator preceding second range bound",
|
||||
span,
|
||||
));
|
||||
return garbage(span);
|
||||
@ -1473,10 +1476,7 @@ pub fn parse_range(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
trace!("-- from: {:?} to: {:?}", from, to);
|
||||
|
||||
if let (None, None) = (&from, &to) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"at least one range bound set".into(),
|
||||
span,
|
||||
));
|
||||
working_set.error(ParseError::Expected("at least one range bound set", span));
|
||||
return garbage(span);
|
||||
}
|
||||
|
||||
@ -1567,7 +1567,7 @@ pub fn parse_brace_expr(
|
||||
// and then revisit the parsing.
|
||||
|
||||
if span.end <= (span.start + 1) {
|
||||
working_set.error(ParseError::Expected(
|
||||
working_set.error(ParseError::ExpectedWithStringMsg(
|
||||
format!("non-block value: {shape}"),
|
||||
span,
|
||||
));
|
||||
@ -1611,7 +1611,7 @@ pub fn parse_brace_expr(
|
||||
} else if matches!(shape, SyntaxShape::MatchBlock) {
|
||||
parse_match_block_expression(working_set, span)
|
||||
} else {
|
||||
working_set.error(ParseError::Expected(
|
||||
working_set.error(ParseError::ExpectedWithStringMsg(
|
||||
format!("non-block value: {shape}"),
|
||||
span,
|
||||
));
|
||||
@ -1861,7 +1861,7 @@ pub fn parse_cell_path(
|
||||
match expected_token {
|
||||
TokenType::Dot => {
|
||||
if bytes.len() != 1 || bytes[0] != b'.' {
|
||||
working_set.error(ParseError::Expected('.'.into(), path_element.span));
|
||||
working_set.error(ParseError::Expected(".", path_element.span));
|
||||
return tail;
|
||||
}
|
||||
expected_token = TokenType::PathMember;
|
||||
@ -1882,7 +1882,7 @@ pub fn parse_cell_path(
|
||||
}
|
||||
expected_token = TokenType::Dot;
|
||||
} else {
|
||||
working_set.error(ParseError::Expected(". or ?".into(), path_element.span));
|
||||
working_set.error(ParseError::Expected(". or ?", path_element.span));
|
||||
return tail;
|
||||
}
|
||||
}
|
||||
@ -1917,10 +1917,8 @@ pub fn parse_cell_path(
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
working_set.error(ParseError::Expected(
|
||||
"string".into(),
|
||||
path_element.span,
|
||||
));
|
||||
working_set
|
||||
.error(ParseError::Expected("string", path_element.span));
|
||||
return tail;
|
||||
}
|
||||
}
|
||||
@ -2113,7 +2111,7 @@ pub fn parse_directory(working_set: &mut StateWorkingSet, span: Span) -> Express
|
||||
custom_completion: None,
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("directory".into(), span));
|
||||
working_set.error(ParseError::Expected("directory", span));
|
||||
|
||||
garbage(span)
|
||||
}
|
||||
@ -2134,7 +2132,7 @@ pub fn parse_filepath(working_set: &mut StateWorkingSet, span: Span) -> Expressi
|
||||
custom_completion: None,
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("filepath".into(), span));
|
||||
working_set.error(ParseError::Expected("filepath", span));
|
||||
|
||||
garbage(span)
|
||||
}
|
||||
@ -2145,13 +2143,14 @@ pub fn parse_datetime(working_set: &mut StateWorkingSet, span: Span) -> Expressi
|
||||
|
||||
let bytes = working_set.get_span_contents(span);
|
||||
|
||||
if bytes.len() < 5
|
||||
if bytes.len() < 6
|
||||
|| !bytes[0].is_ascii_digit()
|
||||
|| !bytes[1].is_ascii_digit()
|
||||
|| !bytes[2].is_ascii_digit()
|
||||
|| !bytes[3].is_ascii_digit()
|
||||
|| bytes[4] != b'-'
|
||||
{
|
||||
working_set.error(ParseError::Expected("datetime".into(), span));
|
||||
working_set.error(ParseError::Expected("datetime", span));
|
||||
return garbage(span);
|
||||
}
|
||||
|
||||
@ -2188,7 +2187,7 @@ pub fn parse_datetime(working_set: &mut StateWorkingSet, span: Span) -> Expressi
|
||||
};
|
||||
}
|
||||
|
||||
working_set.error(ParseError::Expected("datetime".into(), span));
|
||||
working_set.error(ParseError::Expected("datetime", span));
|
||||
|
||||
garbage(span)
|
||||
}
|
||||
@ -2206,10 +2205,7 @@ pub fn parse_duration(working_set: &mut StateWorkingSet, span: Span) -> Expressi
|
||||
garbage(span)
|
||||
}
|
||||
None => {
|
||||
working_set.error(ParseError::Expected(
|
||||
"duration with valid units".into(),
|
||||
span,
|
||||
));
|
||||
working_set.error(ParseError::Expected("duration with valid units", span));
|
||||
garbage(span)
|
||||
}
|
||||
}
|
||||
@ -2230,10 +2226,7 @@ pub fn parse_filesize(working_set: &mut StateWorkingSet, span: Span) -> Expressi
|
||||
garbage(span)
|
||||
}
|
||||
None => {
|
||||
working_set.error(ParseError::Expected(
|
||||
"filesize with valid units".into(),
|
||||
span,
|
||||
));
|
||||
working_set.error(ParseError::Expected("filesize with valid units", span));
|
||||
garbage(span)
|
||||
}
|
||||
}
|
||||
@ -2401,7 +2394,7 @@ pub fn parse_glob_pattern(working_set: &mut StateWorkingSet, span: Span) -> Expr
|
||||
custom_completion: None,
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("glob pattern string".into(), span));
|
||||
working_set.error(ParseError::Expected("glob pattern string", span));
|
||||
|
||||
garbage(span)
|
||||
}
|
||||
@ -2589,10 +2582,7 @@ pub fn unescape_unquote_string(bytes: &[u8], span: Span) -> (String, Option<Pars
|
||||
if let Ok(token) = String::from_utf8(bytes) {
|
||||
(token, err)
|
||||
} else {
|
||||
(
|
||||
String::new(),
|
||||
Some(ParseError::Expected("string".into(), span)),
|
||||
)
|
||||
(String::new(), Some(ParseError::Expected("string", span)))
|
||||
}
|
||||
} else {
|
||||
let bytes = trim_quotes(bytes);
|
||||
@ -2600,10 +2590,7 @@ pub fn unescape_unquote_string(bytes: &[u8], span: Span) -> (String, Option<Pars
|
||||
if let Ok(token) = String::from_utf8(bytes.into()) {
|
||||
(token, None)
|
||||
} else {
|
||||
(
|
||||
String::new(),
|
||||
Some(ParseError::Expected("string".into(), span)),
|
||||
)
|
||||
(String::new(), Some(ParseError::Expected("string", span)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2614,7 +2601,7 @@ pub fn parse_string(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
let bytes = working_set.get_span_contents(span);
|
||||
|
||||
if bytes.is_empty() {
|
||||
working_set.error(ParseError::Expected("String".into(), span));
|
||||
working_set.error(ParseError::Expected("String", span));
|
||||
return Expression::garbage(span);
|
||||
}
|
||||
|
||||
@ -2681,7 +2668,7 @@ pub fn parse_string_strict(working_set: &mut StateWorkingSet, span: Span) -> Exp
|
||||
custom_completion: None,
|
||||
}
|
||||
} else if token.contains(' ') {
|
||||
working_set.error(ParseError::Expected("string".into(), span));
|
||||
working_set.error(ParseError::Expected("string", span));
|
||||
|
||||
garbage(span)
|
||||
} else {
|
||||
@ -2693,7 +2680,7 @@ pub fn parse_string_strict(working_set: &mut StateWorkingSet, span: Span) -> Exp
|
||||
}
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("string".into(), span));
|
||||
working_set.error(ParseError::Expected("string", span));
|
||||
garbage(span)
|
||||
}
|
||||
}
|
||||
@ -2750,7 +2737,7 @@ pub fn parse_shape_name(
|
||||
let command_name = trim_quotes(split[1]);
|
||||
|
||||
if command_name.is_empty() {
|
||||
working_set.error(ParseError::Expected("a command name".into(), cmd_span));
|
||||
working_set.error(ParseError::Expected("a command name", cmd_span));
|
||||
return SyntaxShape::Any;
|
||||
}
|
||||
|
||||
@ -2848,10 +2835,8 @@ fn parse_collection_shape(
|
||||
match maybe_colon.as_slice() {
|
||||
b":" => {
|
||||
if idx + 1 == tokens.len() {
|
||||
working_set.error(ParseError::Expected(
|
||||
"type after colon".into(),
|
||||
tokens[idx].span,
|
||||
));
|
||||
working_set
|
||||
.error(ParseError::Expected("type after colon", tokens[idx].span));
|
||||
break;
|
||||
} else {
|
||||
idx += 1;
|
||||
@ -3110,7 +3095,7 @@ pub fn parse_var_with_opt_type(
|
||||
|
||||
if !is_variable(&var_name) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name".into(),
|
||||
"valid variable name",
|
||||
spans[*spans_idx],
|
||||
));
|
||||
return garbage(spans[*spans_idx]);
|
||||
@ -3129,7 +3114,7 @@ pub fn parse_var_with_opt_type(
|
||||
|
||||
if !is_variable(&var_name) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name".into(),
|
||||
"valid variable name",
|
||||
spans[*spans_idx],
|
||||
));
|
||||
return garbage(spans[*spans_idx]);
|
||||
@ -3150,7 +3135,7 @@ pub fn parse_var_with_opt_type(
|
||||
|
||||
if !is_variable(&var_name) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name".into(),
|
||||
"valid variable name",
|
||||
spans[*spans_idx],
|
||||
));
|
||||
return garbage(spans[*spans_idx]);
|
||||
@ -3243,10 +3228,7 @@ pub fn parse_signature(working_set: &mut StateWorkingSet, span: Span) -> Express
|
||||
has_paren = true;
|
||||
start += 1;
|
||||
} else {
|
||||
working_set.error(ParseError::Expected(
|
||||
"[ or (".into(),
|
||||
Span::new(start, start + 1),
|
||||
));
|
||||
working_set.error(ParseError::Expected("[ or (", Span::new(start, start + 1)));
|
||||
return garbage(span);
|
||||
}
|
||||
|
||||
@ -3314,12 +3296,11 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
parse_mode = ParseMode::TypeMode;
|
||||
}
|
||||
ParseMode::AfterCommaArgMode => {
|
||||
working_set
|
||||
.error(ParseError::Expected("parameter or flag".into(), span));
|
||||
working_set.error(ParseError::Expected("parameter or flag", span));
|
||||
}
|
||||
ParseMode::TypeMode | ParseMode::DefaultValueMode => {
|
||||
// We're seeing two types for the same thing for some reason, error
|
||||
working_set.error(ParseError::Expected("type".into(), span));
|
||||
working_set.error(ParseError::Expected("type", span));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3330,12 +3311,11 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
parse_mode = ParseMode::DefaultValueMode;
|
||||
}
|
||||
ParseMode::AfterCommaArgMode => {
|
||||
working_set
|
||||
.error(ParseError::Expected("parameter or flag".into(), span));
|
||||
working_set.error(ParseError::Expected("parameter or flag", span));
|
||||
}
|
||||
ParseMode::DefaultValueMode => {
|
||||
// We're seeing two default values for some reason, error
|
||||
working_set.error(ParseError::Expected("default value".into(), span));
|
||||
working_set.error(ParseError::Expected("default value", span));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3344,14 +3324,13 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
match parse_mode {
|
||||
ParseMode::ArgMode => parse_mode = ParseMode::AfterCommaArgMode,
|
||||
ParseMode::AfterCommaArgMode => {
|
||||
working_set
|
||||
.error(ParseError::Expected("parameter or flag".into(), span));
|
||||
working_set.error(ParseError::Expected("parameter or flag", span));
|
||||
}
|
||||
ParseMode::TypeMode => {
|
||||
working_set.error(ParseError::Expected("type".into(), span));
|
||||
working_set.error(ParseError::Expected("type", span));
|
||||
}
|
||||
ParseMode::DefaultValueMode => {
|
||||
working_set.error(ParseError::Expected("default value".into(), span));
|
||||
working_set.error(ParseError::Expected("default value", span));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -3375,7 +3354,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
|
||||
if !is_variable(&variable_name) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name for this long flag".into(),
|
||||
"valid variable name for this long flag",
|
||||
span,
|
||||
))
|
||||
}
|
||||
@ -3396,7 +3375,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
}));
|
||||
} else if flags.len() >= 3 {
|
||||
working_set.error(ParseError::Expected(
|
||||
"only one short flag alternative".into(),
|
||||
"only one short flag alternative",
|
||||
span,
|
||||
));
|
||||
} else {
|
||||
@ -3405,7 +3384,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
|| !short_flag.ends_with(b")")
|
||||
{
|
||||
working_set.error(ParseError::Expected(
|
||||
"short flag alternative for the long flag".into(),
|
||||
"short flag alternative for the long flag",
|
||||
span,
|
||||
));
|
||||
short_flag
|
||||
@ -3430,7 +3409,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
|
||||
if !is_variable(&variable_name) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name for this short flag".into(),
|
||||
"valid variable name for this short flag",
|
||||
span,
|
||||
))
|
||||
}
|
||||
@ -3453,8 +3432,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
default_value: None,
|
||||
}));
|
||||
} else {
|
||||
working_set
|
||||
.error(ParseError::Expected("short flag".into(), span));
|
||||
working_set.error(ParseError::Expected("short flag", span));
|
||||
}
|
||||
}
|
||||
parse_mode = ParseMode::ArgMode;
|
||||
@ -3466,8 +3444,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
let chars: Vec<char> = short_flag.chars().collect();
|
||||
|
||||
if chars.len() > 1 {
|
||||
working_set
|
||||
.error(ParseError::Expected("short flag".into(), span));
|
||||
working_set.error(ParseError::Expected("short flag", span));
|
||||
}
|
||||
|
||||
let mut encoded_var_name = vec![0u8; 4];
|
||||
@ -3476,7 +3453,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
|
||||
if !is_variable(&variable_name) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name for this short flag".into(),
|
||||
"valid variable name for this short flag",
|
||||
span,
|
||||
))
|
||||
}
|
||||
@ -3499,16 +3476,13 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
// This is the same as the short flag in --b(-a)
|
||||
else if contents.starts_with(b"(-") {
|
||||
if matches!(parse_mode, ParseMode::AfterCommaArgMode) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"parameter or flag".into(),
|
||||
span,
|
||||
));
|
||||
working_set
|
||||
.error(ParseError::Expected("parameter or flag", span));
|
||||
}
|
||||
let short_flag = &contents[2..];
|
||||
|
||||
let short_flag = if !short_flag.ends_with(b")") {
|
||||
working_set
|
||||
.error(ParseError::Expected("short flag".into(), span));
|
||||
working_set.error(ParseError::Expected("short flag", span));
|
||||
short_flag
|
||||
} else {
|
||||
&short_flag[..(short_flag.len() - 1)]
|
||||
@ -3522,7 +3496,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
Some(Arg::Flag(flag)) => {
|
||||
if flag.short.is_some() {
|
||||
working_set.error(ParseError::Expected(
|
||||
"one short flag".into(),
|
||||
"one short flag",
|
||||
span,
|
||||
));
|
||||
} else {
|
||||
@ -3530,15 +3504,12 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
working_set.error(ParseError::Expected(
|
||||
"unknown flag".into(),
|
||||
span,
|
||||
));
|
||||
working_set
|
||||
.error(ParseError::Expected("unknown flag", span));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
working_set
|
||||
.error(ParseError::Expected("short flag".into(), span));
|
||||
working_set.error(ParseError::Expected("short flag", span));
|
||||
}
|
||||
}
|
||||
// Positional arg, optional
|
||||
@ -3548,7 +3519,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
|
||||
if !is_variable(&contents) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name for this optional parameter".into(),
|
||||
"valid variable name for this optional parameter",
|
||||
span,
|
||||
))
|
||||
}
|
||||
@ -3575,7 +3546,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
|
||||
if !is_variable(&contents_vec) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name for this rest parameter".into(),
|
||||
"valid variable name for this rest parameter",
|
||||
span,
|
||||
))
|
||||
}
|
||||
@ -3599,7 +3570,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
|
||||
if !is_variable(&contents_vec) {
|
||||
working_set.error(ParseError::Expected(
|
||||
"valid variable name for this parameter".into(),
|
||||
"valid variable name for this parameter",
|
||||
span,
|
||||
))
|
||||
}
|
||||
@ -4039,7 +4010,7 @@ pub fn parse_block_expression(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
if bytes.starts_with(b"{") {
|
||||
start += 1;
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("block".into(), span));
|
||||
working_set.error(ParseError::Expected("block", span));
|
||||
return garbage(span);
|
||||
}
|
||||
if bytes.ends_with(b"}") {
|
||||
@ -4065,10 +4036,7 @@ pub fn parse_block_expression(working_set: &mut StateWorkingSet, span: Span) ->
|
||||
contents: TokenContents::Pipe,
|
||||
span,
|
||||
}) => {
|
||||
working_set.error(ParseError::Expected(
|
||||
"block but found closure".into(),
|
||||
*span,
|
||||
));
|
||||
working_set.error(ParseError::Expected("block but found closure", *span));
|
||||
(None, 0)
|
||||
}
|
||||
_ => (None, 0),
|
||||
@ -4117,7 +4085,7 @@ pub fn parse_match_block_expression(working_set: &mut StateWorkingSet, span: Spa
|
||||
if bytes.starts_with(b"{") {
|
||||
start += 1;
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("closure".into(), span));
|
||||
working_set.error(ParseError::Expected("closure", span));
|
||||
return garbage(span);
|
||||
}
|
||||
if bytes.ends_with(b"}") {
|
||||
@ -4274,7 +4242,7 @@ pub fn parse_closure_expression(
|
||||
if bytes.starts_with(b"{") {
|
||||
start += 1;
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("closure".into(), span));
|
||||
working_set.error(ParseError::Expected("closure", span));
|
||||
return garbage(span);
|
||||
}
|
||||
if bytes.ends_with(b"}") {
|
||||
@ -4343,7 +4311,7 @@ pub fn parse_closure_expression(
|
||||
if let SyntaxShape::Closure(Some(v)) = shape {
|
||||
if let Some((sig, sig_span)) = &signature {
|
||||
if sig.num_positionals() > v.len() {
|
||||
working_set.error(ParseError::Expected(
|
||||
working_set.error(ParseError::ExpectedWithStringMsg(
|
||||
format!(
|
||||
"{} closure parameter{}",
|
||||
v.len(),
|
||||
@ -4427,7 +4395,7 @@ pub fn parse_value(
|
||||
custom_completion: None,
|
||||
};
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("non-boolean value".into(), span));
|
||||
working_set.error(ParseError::Expected("non-boolean value", span));
|
||||
return Expression::garbage(span);
|
||||
}
|
||||
}
|
||||
@ -4440,7 +4408,7 @@ pub fn parse_value(
|
||||
custom_completion: None,
|
||||
};
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("non-boolean value".into(), span));
|
||||
working_set.error(ParseError::Expected("non-boolean value", span));
|
||||
return Expression::garbage(span);
|
||||
}
|
||||
}
|
||||
@ -4472,7 +4440,7 @@ pub fn parse_value(
|
||||
| SyntaxShape::Table
|
||||
| SyntaxShape::Signature => {}
|
||||
_ => {
|
||||
working_set.error(ParseError::Expected("non-[] value".into(), span));
|
||||
working_set.error(ParseError::Expected("non-[] value", span));
|
||||
return Expression::garbage(span);
|
||||
}
|
||||
},
|
||||
@ -4502,7 +4470,7 @@ pub fn parse_value(
|
||||
if bytes.starts_with(b"[") {
|
||||
parse_signature(working_set, span)
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("signature".into(), span));
|
||||
working_set.error(ParseError::Expected("signature", span));
|
||||
|
||||
Expression::garbage(span)
|
||||
}
|
||||
@ -4511,7 +4479,7 @@ pub fn parse_value(
|
||||
if bytes.starts_with(b"[") {
|
||||
parse_list_expression(working_set, span, elem)
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("list".into(), span));
|
||||
working_set.error(ParseError::Expected("list", span));
|
||||
|
||||
Expression::garbage(span)
|
||||
}
|
||||
@ -4520,7 +4488,7 @@ pub fn parse_value(
|
||||
if bytes.starts_with(b"[") {
|
||||
parse_table_expression(working_set, span)
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("table".into(), span));
|
||||
working_set.error(ParseError::Expected("table", span));
|
||||
|
||||
Expression::garbage(span)
|
||||
}
|
||||
@ -4536,7 +4504,7 @@ pub fn parse_value(
|
||||
custom_completion: None,
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("bool".into(), span));
|
||||
working_set.error(ParseError::Expected("bool", span));
|
||||
|
||||
Expression::garbage(span)
|
||||
}
|
||||
@ -4545,10 +4513,7 @@ pub fn parse_value(
|
||||
// Be sure to return ParseError::Expected(..) if invoked for one of these shapes, but lex
|
||||
// stream doesn't start with '{'} -- parsing in SyntaxShape::Any arm depends on this error variant.
|
||||
SyntaxShape::Block | SyntaxShape::Closure(..) | SyntaxShape::Record(_) => {
|
||||
working_set.error(ParseError::Expected(
|
||||
"block, closure or record".into(),
|
||||
span,
|
||||
));
|
||||
working_set.error(ParseError::Expected("block, closure or record", span));
|
||||
|
||||
Expression::garbage(span)
|
||||
}
|
||||
@ -4563,10 +4528,7 @@ pub fn parse_value(
|
||||
SyntaxShape::Filesize,
|
||||
SyntaxShape::Duration,
|
||||
SyntaxShape::Range,
|
||||
SyntaxShape::DateTime, //FIXME requires 3 failed conversion attempts before failing
|
||||
SyntaxShape::Record(vec![]),
|
||||
SyntaxShape::Closure(None),
|
||||
SyntaxShape::Block,
|
||||
SyntaxShape::DateTime,
|
||||
SyntaxShape::Int,
|
||||
SyntaxShape::Number,
|
||||
SyntaxShape::String,
|
||||
@ -4580,7 +4542,10 @@ pub fn parse_value(
|
||||
return s;
|
||||
} else {
|
||||
match working_set.parse_errors.get(starting_error_count) {
|
||||
Some(ParseError::Expected(_, _)) => {
|
||||
Some(
|
||||
ParseError::Expected(_, _)
|
||||
| ParseError::ExpectedWithStringMsg(_, _),
|
||||
) => {
|
||||
working_set.parse_errors.truncate(starting_error_count);
|
||||
continue;
|
||||
}
|
||||
@ -4590,12 +4555,15 @@ pub fn parse_value(
|
||||
}
|
||||
}
|
||||
}
|
||||
working_set.error(ParseError::Expected("any shape".into(), span));
|
||||
working_set.error(ParseError::Expected("any shape", span));
|
||||
garbage(span)
|
||||
}
|
||||
}
|
||||
x => {
|
||||
working_set.error(ParseError::Expected(x.to_type().to_string(), span));
|
||||
working_set.error(ParseError::ExpectedWithStringMsg(
|
||||
x.to_type().to_string(),
|
||||
span,
|
||||
));
|
||||
garbage(span)
|
||||
}
|
||||
}
|
||||
@ -4727,7 +4695,7 @@ pub fn parse_operator(working_set: &mut StateWorkingSet, span: Span) -> Expressi
|
||||
return garbage(span);
|
||||
}
|
||||
_ => {
|
||||
working_set.error(ParseError::Expected("operator".into(), span));
|
||||
working_set.error(ParseError::Expected("operator", span));
|
||||
return garbage(span);
|
||||
}
|
||||
};
|
||||
@ -4770,7 +4738,7 @@ pub fn parse_math_expression(
|
||||
return parse_call(working_set, spans, spans[0], false);
|
||||
} else {
|
||||
working_set.error(ParseError::Expected(
|
||||
"expression".into(),
|
||||
"expression",
|
||||
Span::new(spans[0].end, spans[0].end),
|
||||
));
|
||||
return garbage(spans[0]);
|
||||
@ -4786,7 +4754,7 @@ pub fn parse_math_expression(
|
||||
};
|
||||
} else {
|
||||
working_set.error(ParseError::Expected(
|
||||
"expression".into(),
|
||||
"expression",
|
||||
Span::new(spans[0].end, spans[0].end),
|
||||
));
|
||||
return garbage(spans[0]);
|
||||
@ -5099,7 +5067,7 @@ pub fn parse_variable(working_set: &mut StateWorkingSet, span: Span) -> Option<V
|
||||
None
|
||||
}
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("valid variable name".into(), span));
|
||||
working_set.error(ParseError::Expected("valid variable name", span));
|
||||
|
||||
None
|
||||
}
|
||||
@ -5185,10 +5153,7 @@ pub fn parse_record(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
if bytes.starts_with(b"{") {
|
||||
start += 1;
|
||||
} else {
|
||||
working_set.error(ParseError::Expected(
|
||||
"{".into(),
|
||||
Span::new(start, start + 1),
|
||||
));
|
||||
working_set.error(ParseError::Expected("{", Span::new(start, start + 1)));
|
||||
return garbage(span);
|
||||
}
|
||||
|
||||
@ -5215,14 +5180,14 @@ pub fn parse_record(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
|
||||
idx += 1;
|
||||
if idx == tokens.len() {
|
||||
working_set.error(ParseError::Expected("record".into(), span));
|
||||
working_set.error(ParseError::Expected("record", span));
|
||||
return garbage(span);
|
||||
}
|
||||
let colon = working_set.get_span_contents(tokens[idx].span);
|
||||
idx += 1;
|
||||
if idx == tokens.len() || colon != b":" {
|
||||
//FIXME: need better error
|
||||
working_set.error(ParseError::Expected("record".into(), span));
|
||||
working_set.error(ParseError::Expected("record", span));
|
||||
return garbage(span);
|
||||
}
|
||||
let value = parse_value(working_set, tokens[idx].span, &SyntaxShape::Any);
|
||||
|
@ -42,7 +42,11 @@ pub enum ParseError {
|
||||
|
||||
#[error("Parse mismatch during operation.")]
|
||||
#[diagnostic(code(nu::parser::parse_mismatch))]
|
||||
Expected(String, #[label("expected {0}")] Span),
|
||||
Expected(&'static str, #[label("expected {0}")] Span),
|
||||
|
||||
#[error("Parse mismatch during operation.")]
|
||||
#[diagnostic(code(nu::parser::parse_mismatch_with_full_string_msg))]
|
||||
ExpectedWithStringMsg(String, #[label("expected {0}")] Span),
|
||||
|
||||
#[error("Type mismatch during operation.")]
|
||||
#[diagnostic(code(nu::parser::type_mismatch))]
|
||||
@ -473,6 +477,7 @@ impl ParseError {
|
||||
ParseError::Unclosed(_, s) => *s,
|
||||
ParseError::Unbalanced(_, _, s) => *s,
|
||||
ParseError::Expected(_, s) => *s,
|
||||
ParseError::ExpectedWithStringMsg(_, s) => *s,
|
||||
ParseError::Mismatch(_, _, s) => *s,
|
||||
ParseError::UnsupportedOperationLHS(_, _, s, _) => *s,
|
||||
ParseError::UnsupportedOperationRHS(_, _, _, _, s, _) => *s,
|
||||
|
Loading…
Reference in New Issue
Block a user