Also fix the flag params

This commit is contained in:
JT 2021-10-12 10:17:45 +13:00
parent 1f45304cf9
commit 96419f168b
6 changed files with 75 additions and 10 deletions

View File

@ -84,6 +84,9 @@ impl Highlighter for NuHighlighter {
Style::new().fg(nu_ansi_term::Color::Yellow).bold(),
next_token,
)),
FlatShape::Flag => {
output.push((Style::new().fg(nu_ansi_term::Color::Yellow), next_token))
}
FlatShape::Filepath => output.push((
Style::new().fg(nu_ansi_term::Color::Yellow).bold(),
next_token,

View File

@ -1,6 +1,6 @@
use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement};
use nu_protocol::engine::EvaluationContext;
use nu_protocol::{Range, ShellError, Span, Type, Unit, Value};
use nu_protocol::{Range, ShellError, Span, Spanned, Type, Unit, Value};
pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
match op {
@ -60,6 +60,29 @@ fn eval_call(context: &EvaluationContext, call: &Call, input: Value) -> Result<V
},
)
}
for named in decl.signature().named {
for call_named in &call.named {
if call_named.0.item == named.long {
let var_id = named
.var_id
.expect("internal error: all custom parameters must have var_ids");
if let Some(arg) = &call_named.1 {
let result = eval_expression(&state, arg)?;
state.add_var(var_id, result);
} else {
state.add_var(
var_id,
Value::Bool {
val: true,
span: call.head,
},
)
}
}
}
}
let engine_state = state.engine_state.borrow();
let block = engine_state.get_block(block_id);
eval_block(&state, block, input)
@ -98,7 +121,13 @@ fn eval_external(
}
if last_expression {
call.named.push(("last_expression".into(), None))
call.named.push((
Spanned {
item: "last_expression".into(),
span: Span::unknown(),
},
None,
))
}
command.run(context, &call, input)

View File

@ -18,6 +18,7 @@ pub enum FlatShape {
Filepath,
GlobPattern,
Variable,
Flag,
Custom(String),
}
@ -61,6 +62,12 @@ pub fn flatten_expression(
for positional in &call.positional {
output.extend(flatten_expression(working_set, positional));
}
for named in &call.named {
output.push((named.0.span, FlatShape::Flag));
if let Some(expr) = &named.1 {
output.extend(flatten_expression(working_set, expr));
}
}
output
}
Expr::ExternalCall(_, name_span, args) => {

View File

@ -57,7 +57,7 @@ fn check_call(command: Span, sig: &Signature, call: &Call) -> Option<ParseError>
Some(ParseError::MissingPositional(missing.name.clone(), command))
} else {
for req_flag in sig.named.iter().filter(|x| x.required) {
if call.named.iter().all(|(n, _)| n != &req_flag.long) {
if call.named.iter().all(|(n, _)| n.item != req_flag.long) {
return Some(ParseError::MissingRequiredFlag(
req_flag.long.clone(),
command,
@ -478,7 +478,13 @@ pub fn parse_internal_call(
if let Some(long_name) = long_name {
// We found a long flag, like --bar
error = error.or(err);
call.named.push((long_name, arg));
call.named.push((
Spanned {
item: long_name,
span: arg_span,
},
arg,
));
spans_idx += 1;
continue;
}
@ -500,13 +506,25 @@ pub fn parse_internal_call(
let (arg, err) = parse_value(working_set, *arg, &arg_shape);
error = error.or(err);
call.named.push((flag.long.clone(), Some(arg)));
call.named.push((
Spanned {
item: flag.long.clone(),
span: spans[spans_idx],
},
Some(arg),
));
spans_idx += 1;
} else {
error = error.or(Some(ParseError::MissingFlagParam(arg_span)))
}
} else {
call.named.push((flag.long.clone(), None));
call.named.push((
Spanned {
item: flag.long.clone(),
span: spans[spans_idx],
},
None,
));
}
}
spans_idx += 1;

View File

@ -1,5 +1,5 @@
use super::Expression;
use crate::{DeclId, Span};
use crate::{DeclId, Span, Spanned};
#[derive(Debug, Clone)]
pub struct Call {
@ -7,7 +7,7 @@ pub struct Call {
pub decl_id: DeclId,
pub head: Span,
pub positional: Vec<Expression>,
pub named: Vec<(String, Option<Expression>)>,
pub named: Vec<(Spanned<String>, Option<Expression>)>,
}
impl Default for Call {
@ -28,7 +28,7 @@ impl Call {
pub fn has_flag(&self, flag_name: &str) -> bool {
for name in &self.named {
if flag_name == name.0 {
if flag_name == name.0.item {
return true;
}
}
@ -38,7 +38,7 @@ impl Call {
pub fn get_flag_expr(&self, flag_name: &str) -> Option<Expression> {
for name in &self.named {
if flag_name == name.0 {
if flag_name == name.0.item {
return name.1.clone();
}
}

View File

@ -714,3 +714,11 @@ fn missing_column_error() -> TestResult {
fn missing_parameters() -> TestResult {
fail_test(r#"def foo {}"#, "expected [")
}
#[test]
fn flag_param_value() -> TestResult {
run_test(
r#"def foo [--bob: int] { $bob + 100 }; foo --bob 55"#,
"155",
)
}