forked from extern/nushell
enable flag value type checking (#11311)
# Description Fixes: #11310 # User-Facing Changes After the change, the following code will go to error: ```nushell > def a [--x: int = 3] { "aa" } > let y = "aa" > a --x=$y Error: nu::parser::type_mismatch × Type mismatch. ╭─[entry #32:2:1] 2 │ let y = "aa" 3 │ a --x=$y · ─┬ · ╰── expected int, found string ╰──── ```
This commit is contained in:
parent
1cecb37628
commit
697f3c03f1
@ -344,6 +344,37 @@ pub fn parse_external_call(
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_flag_arg_type(
|
||||
working_set: &mut StateWorkingSet,
|
||||
arg_name: String,
|
||||
arg: Expression,
|
||||
arg_shape: &SyntaxShape,
|
||||
long_name_span: Span,
|
||||
) -> (Spanned<String>, Expression) {
|
||||
if !type_compatible(&arg.ty, &arg_shape.to_type()) {
|
||||
working_set.error(ParseError::TypeMismatch(
|
||||
arg_shape.to_type(),
|
||||
arg.ty,
|
||||
arg.span,
|
||||
));
|
||||
(
|
||||
Spanned {
|
||||
item: arg_name,
|
||||
span: long_name_span,
|
||||
},
|
||||
Expression::garbage(arg.span),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
Spanned {
|
||||
item: arg_name,
|
||||
span: long_name_span,
|
||||
},
|
||||
arg,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_long_flag(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
@ -368,25 +399,21 @@ fn parse_long_flag(
|
||||
span.start += long_name_len + 3; //offset by long flag and '='
|
||||
|
||||
let arg = parse_value(working_set, span, arg_shape);
|
||||
|
||||
(
|
||||
Some(Spanned {
|
||||
item: long_name,
|
||||
span: Span::new(arg_span.start, arg_span.start + long_name_len + 2),
|
||||
}),
|
||||
Some(arg),
|
||||
)
|
||||
let (arg_name, val_expression) = ensure_flag_arg_type(
|
||||
working_set,
|
||||
long_name,
|
||||
arg,
|
||||
arg_shape,
|
||||
Span::new(arg_span.start, arg_span.start + long_name_len + 2),
|
||||
);
|
||||
(Some(arg_name), Some(val_expression))
|
||||
} else if let Some(arg) = spans.get(*spans_idx + 1) {
|
||||
let arg = parse_value(working_set, *arg, arg_shape);
|
||||
|
||||
*spans_idx += 1;
|
||||
(
|
||||
Some(Spanned {
|
||||
item: long_name,
|
||||
span: arg_span,
|
||||
}),
|
||||
Some(arg),
|
||||
)
|
||||
let (arg_name, val_expression) =
|
||||
ensure_flag_arg_type(working_set, long_name, arg, arg_shape, arg_span);
|
||||
(Some(arg_name), Some(val_expression))
|
||||
} else {
|
||||
working_set.error(ParseError::MissingFlagParam(
|
||||
arg_shape.to_string(),
|
||||
@ -411,13 +438,14 @@ fn parse_long_flag(
|
||||
|
||||
let arg = parse_value(working_set, span, &SyntaxShape::Boolean);
|
||||
|
||||
(
|
||||
Some(Spanned {
|
||||
item: long_name,
|
||||
span: Span::new(arg_span.start, arg_span.start + long_name_len + 2),
|
||||
}),
|
||||
Some(arg),
|
||||
)
|
||||
let (arg_name, val_expression) = ensure_flag_arg_type(
|
||||
working_set,
|
||||
long_name,
|
||||
arg,
|
||||
&SyntaxShape::Boolean,
|
||||
Span::new(arg_span.start, arg_span.start + long_name_len + 2),
|
||||
);
|
||||
(Some(arg_name), Some(val_expression))
|
||||
} else {
|
||||
(
|
||||
Some(Spanned {
|
||||
|
@ -73,6 +73,14 @@ fn custom_switch1() -> TestResult {
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_flag_with_type_checking() -> TestResult {
|
||||
fail_test(
|
||||
r#"def florb [--dry-run: int] { $dry_run }; let y = "3"; florb --dry-run=$y"#,
|
||||
"type_mismatch",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_switch2() -> TestResult {
|
||||
run_test(
|
||||
@ -116,7 +124,7 @@ fn custom_flag1() -> TestResult {
|
||||
r#"def florb [
|
||||
--age: int = 0
|
||||
--name = "foobar"
|
||||
] {
|
||||
] {
|
||||
($age | into string) + $name
|
||||
}
|
||||
florb"#,
|
||||
|
Loading…
Reference in New Issue
Block a user