forked from extern/nushell
Some error improvements (#659)
This commit is contained in:
@ -16,8 +16,8 @@ pub enum ParseError {
|
||||
ExtraTokens(#[label = "extra tokens"] Span),
|
||||
|
||||
#[error("Extra positional argument.")]
|
||||
#[diagnostic(code(nu::parser::extra_positional), url(docsrs))]
|
||||
ExtraPositional(#[label = "extra positional argument"] Span),
|
||||
#[diagnostic(code(nu::parser::extra_positional), url(docsrs), help("Usage: {0}"))]
|
||||
ExtraPositional(String, #[label = "extra positional argument"] Span),
|
||||
|
||||
#[error("Unexpected end of code.")]
|
||||
#[diagnostic(code(nu::parser::unexpected_eof), url(docsrs))]
|
||||
@ -106,28 +106,36 @@ pub enum ParseError {
|
||||
NonUtf8(#[label = "non-UTF8 string"] Span),
|
||||
|
||||
#[error("The `{0}` command doesn't have flag `{1}`.")]
|
||||
#[diagnostic(code(nu::parser::unknown_flag), url(docsrs))]
|
||||
#[diagnostic(
|
||||
code(nu::parser::unknown_flag),
|
||||
url(docsrs),
|
||||
help("use {0} --help for a list of flags")
|
||||
)]
|
||||
UnknownFlag(String, String, #[label = "unknown flag"] Span),
|
||||
|
||||
#[error("Unknown type.")]
|
||||
#[diagnostic(code(nu::parser::unknown_type), url(docsrs))]
|
||||
UnknownType(#[label = "unknown type"] Span),
|
||||
|
||||
#[error("Missing flag param.")]
|
||||
#[error("Missing flag argument.")]
|
||||
#[diagnostic(code(nu::parser::missing_flag_param), url(docsrs))]
|
||||
MissingFlagParam(#[label = "flag missing param"] Span),
|
||||
MissingFlagParam(String, #[label = "flag missing {0} argument"] Span),
|
||||
|
||||
#[error("Batches of short flags can't take arguments.")]
|
||||
#[diagnostic(code(nu::parser::short_flag_arg_cant_take_arg), url(docsrs))]
|
||||
ShortFlagBatchCantTakeArg(#[label = "short flag batches can't take args"] Span),
|
||||
|
||||
#[error("Missing required positional argument.")]
|
||||
#[diagnostic(code(nu::parser::missing_positional), url(docsrs))]
|
||||
MissingPositional(String, #[label("missing {0}")] Span),
|
||||
#[diagnostic(code(nu::parser::missing_positional), url(docsrs), help("Usage: {2}"))]
|
||||
MissingPositional(String, #[label("missing {0}")] Span, String),
|
||||
|
||||
#[error("Missing argument to `{0}`.")]
|
||||
#[error("Missing argument to `{1}`.")]
|
||||
#[diagnostic(code(nu::parser::keyword_missing_arg), url(docsrs))]
|
||||
KeywordMissingArgument(String, #[label("missing value that follows {0}")] Span),
|
||||
KeywordMissingArgument(
|
||||
String,
|
||||
String,
|
||||
#[label("missing {0} value that follows {1}")] Span,
|
||||
),
|
||||
|
||||
#[error("Missing type.")]
|
||||
#[diagnostic(code(nu::parser::missing_type), url(docsrs))]
|
||||
|
@ -344,6 +344,9 @@ pub fn parse_export(
|
||||
);
|
||||
}
|
||||
|
||||
let sig = working_set.get_decl(call.decl_id);
|
||||
let call_signature = sig.signature().call_signature();
|
||||
|
||||
call.head = span(&spans[0..=1]);
|
||||
|
||||
if let Some(name_span) = spans.get(2) {
|
||||
@ -385,7 +388,11 @@ pub fn parse_export(
|
||||
};
|
||||
|
||||
error = error.or_else(|| {
|
||||
Some(ParseError::MissingPositional("block".into(), err_span))
|
||||
Some(ParseError::MissingPositional(
|
||||
"block".into(),
|
||||
err_span,
|
||||
call_signature,
|
||||
))
|
||||
});
|
||||
|
||||
None
|
||||
@ -400,6 +407,7 @@ pub fn parse_export(
|
||||
Some(ParseError::MissingPositional(
|
||||
"environment variable name".into(),
|
||||
err_span,
|
||||
call_signature,
|
||||
))
|
||||
});
|
||||
|
||||
@ -426,6 +434,7 @@ pub fn parse_export(
|
||||
start: export_span.end,
|
||||
end: export_span.end,
|
||||
},
|
||||
"'def' or 'env' keyword.".to_string(),
|
||||
))
|
||||
});
|
||||
|
||||
@ -925,6 +934,9 @@ pub fn parse_let(
|
||||
}
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(b"let") {
|
||||
let cmd = working_set.get_decl(decl_id);
|
||||
let call_signature = cmd.signature().call_signature();
|
||||
|
||||
if spans.len() >= 4 {
|
||||
// This is a bit of by-hand parsing to get around the issue where we want to parse in the reverse order
|
||||
// so that the var-id created by the variable isn't visible in the expression that init it
|
||||
@ -943,7 +955,10 @@ pub fn parse_let(
|
||||
error = error.or(err);
|
||||
|
||||
if idx < (spans.len() - 1) {
|
||||
error = error.or(Some(ParseError::ExtraPositional(spans[idx + 1])));
|
||||
error = error.or(Some(ParseError::ExtraPositional(
|
||||
call_signature,
|
||||
spans[idx + 1],
|
||||
)));
|
||||
}
|
||||
|
||||
let mut idx = 0;
|
||||
|
@ -102,15 +102,42 @@ pub fn check_call(command: Span, sig: &Signature, call: &Call) -> Option<ParseEr
|
||||
}
|
||||
});
|
||||
if !found {
|
||||
return Some(ParseError::MissingPositional(
|
||||
argument.name.clone(),
|
||||
command,
|
||||
));
|
||||
if let Some(last) = call.positional.last() {
|
||||
return Some(ParseError::MissingPositional(
|
||||
argument.name.clone(),
|
||||
Span {
|
||||
start: last.span.end,
|
||||
end: last.span.end,
|
||||
},
|
||||
sig.call_signature(),
|
||||
));
|
||||
} else {
|
||||
return Some(ParseError::MissingPositional(
|
||||
argument.name.clone(),
|
||||
command,
|
||||
sig.call_signature(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let missing = &sig.required_positional[call.positional.len()];
|
||||
Some(ParseError::MissingPositional(missing.name.clone(), command))
|
||||
if let Some(last) = call.positional.last() {
|
||||
Some(ParseError::MissingPositional(
|
||||
missing.name.clone(),
|
||||
Span {
|
||||
start: last.span.end,
|
||||
end: last.span.end,
|
||||
},
|
||||
sig.call_signature(),
|
||||
))
|
||||
} else {
|
||||
Some(ParseError::MissingPositional(
|
||||
missing.name.clone(),
|
||||
command,
|
||||
sig.call_signature(),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
for req_flag in sig.named.iter().filter(|x| x.required) {
|
||||
if call.named.iter().all(|(n, _)| n.item != req_flag.long) {
|
||||
@ -228,7 +255,10 @@ fn parse_long_flag(
|
||||
(
|
||||
Some(long_name),
|
||||
None,
|
||||
Some(ParseError::MissingFlagParam(arg_span)),
|
||||
Some(ParseError::MissingFlagParam(
|
||||
arg_shape.to_string(),
|
||||
arg_span,
|
||||
)),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@ -467,8 +497,12 @@ pub fn parse_multispan_value(
|
||||
if *spans_idx >= spans.len() {
|
||||
error = error.or_else(|| {
|
||||
Some(ParseError::KeywordMissingArgument(
|
||||
arg.to_string(),
|
||||
String::from_utf8_lossy(keyword).into(),
|
||||
spans[*spans_idx - 1],
|
||||
Span {
|
||||
start: spans[*spans_idx - 1].end,
|
||||
end: spans[*spans_idx - 1].end,
|
||||
},
|
||||
))
|
||||
});
|
||||
return (
|
||||
@ -584,7 +618,12 @@ pub fn parse_internal_call(
|
||||
));
|
||||
spans_idx += 1;
|
||||
} else {
|
||||
error = error.or(Some(ParseError::MissingFlagParam(arg_span)))
|
||||
error = error.or_else(|| {
|
||||
Some(ParseError::MissingFlagParam(
|
||||
arg_shape.to_string(),
|
||||
arg_span,
|
||||
))
|
||||
})
|
||||
}
|
||||
} else {
|
||||
call.named.push((
|
||||
@ -614,6 +653,7 @@ pub fn parse_internal_call(
|
||||
Some(ParseError::MissingPositional(
|
||||
positional.name.clone(),
|
||||
spans[spans_idx],
|
||||
signature.call_signature(),
|
||||
))
|
||||
});
|
||||
positional_idx += 1;
|
||||
@ -646,7 +686,12 @@ pub fn parse_internal_call(
|
||||
positional_idx += 1;
|
||||
} else {
|
||||
call.positional.push(Expression::garbage(arg_span));
|
||||
error = error.or(Some(ParseError::ExtraPositional(arg_span)))
|
||||
error = error.or_else(|| {
|
||||
Some(ParseError::ExtraPositional(
|
||||
signature.call_signature(),
|
||||
arg_span,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
error = error.or(err);
|
||||
|
Reference in New Issue
Block a user