Do a bit more cleanup of block params (#3455)

* Do a bit more cleanup of block params

* Do a bit more cleanup of block params
This commit is contained in:
JT 2021-05-21 19:04:27 +12:00 committed by GitHub
parent 28388b4e3a
commit 751de20f93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 157 additions and 186 deletions

View File

@ -360,6 +360,7 @@ mod tests {
#[test]
fn examples_work_as_expected() -> Result<(), ShellError> {
for cmd in only_examples() {
println!("cmd: {}", cmd.name());
test_examples(cmd)?;
}

View File

@ -98,7 +98,9 @@ fn any(args: CommandArgs) -> Result<OutputStream, ShellError> {
let result = args.input.fold(init, move |acc, row| {
let condition = condition.clone();
let ctx = ctx.clone();
ctx.scope.add_var("$it", row);
if let Some((arg, _)) = any_args.predicate.block.params.positional.first() {
ctx.scope.add_var(arg.name(), row);
}
let condition = evaluate_baseline_expr(&condition, &ctx);

View File

@ -88,17 +88,8 @@ pub fn process_row(
context.scope.enter_scope();
context.scope.add_vars(&captured_block.captured.entries);
if !captured_block.block.params.positional.is_empty() {
if captured_block.block.params.positional.len() > 1 {
return Err(ShellError::labeled_error(
"Expected block with less than two parameters",
"too many parameters",
captured_block.block.span,
));
}
context
.scope
.add_var(captured_block.block.params.positional[0].0.name(), input);
if let Some((arg, _)) = captured_block.block.params.positional.first() {
context.scope.add_var(arg.name(), input);
} else {
context.scope.add_var("$it", input);
}

View File

@ -140,7 +140,9 @@ fn process_row(
context.scope.enter_scope();
context.scope.add_vars(&default_block.captured.entries);
context.scope.add_var("$it", input.clone());
if let Some((arg, _)) = default_block.block.params.positional.first() {
context.scope.add_var(arg.name(), input.clone());
}
let stream = run_block(
&default_block.block,

View File

@ -80,7 +80,9 @@ fn process_row(
context.scope.enter_scope();
context.scope.add_vars(&block.captured.entries);
context.scope.add_var("$it", input.clone());
if let Some((arg, _)) = block.block.params.positional.first() {
context.scope.add_var(arg.name(), input.clone());
}
let result = run_block(
&block.block,

View File

@ -1,10 +1,12 @@
use crate::prelude::*;
use log::trace;
use nu_engine::evaluate_baseline_expr;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_parser::ParserScope;
use nu_protocol::{hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue, Value};
use nu_protocol::{
hir::{CapturedBlock, ClassifiedCommand},
Signature, SyntaxShape,
};
pub struct SubCommand;
@ -29,52 +31,38 @@ impl WholeStreamCommand for SubCommand {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let tag = args.call_info.name_tag.clone();
let call_info = args.evaluate_once()?;
let block = call_info.args.expect_nth(0)?.clone();
let (condition, captured) = match block {
Value {
value: UntaggedValue::Block(captured_block),
tag,
} => {
if captured_block.block.block.len() != 1 {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
match captured_block.block.block[0].pipelines.get(0) {
Some(item) => match item.list.get(0) {
Some(ClassifiedCommand::Expr(expr)) => {
(Arc::new(expr.clone()), captured_block.captured.clone())
}
_ => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
},
None => {
let block: CapturedBlock = call_info.req(0)?;
let condition = {
if block.block.block.len() != 1 {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
match block.block.block[0].pipelines.get(0) {
Some(item) => match item.list.get(0) {
Some(ClassifiedCommand::Expr(expr)) => expr.clone(),
_ => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
},
None => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
}
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
};
Ok(call_info
@ -83,13 +71,13 @@ impl WholeStreamCommand for SubCommand {
let condition = condition.clone();
let ctx = ctx.clone();
ctx.scope.enter_scope();
ctx.scope.add_vars(&captured.entries);
ctx.scope.add_var("$it", item.clone());
trace!("ITEM = {:?}", item);
ctx.scope.add_vars(&block.captured.entries);
if let Some((arg, _)) = block.block.params.positional.first() {
ctx.scope.add_var(arg.name(), item.clone());
}
let result = evaluate_baseline_expr(&*condition, &*ctx);
ctx.scope.exit_scope();
trace!("RESULT = {:?}", result);
!matches!(result, Ok(ref v) if v.is_true())
})

View File

@ -3,7 +3,10 @@ use log::trace;
use nu_engine::evaluate_baseline_expr;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue, Value};
use nu_protocol::{
hir::{CapturedBlock, ClassifiedCommand},
Signature, SyntaxShape,
};
pub struct SubCommand;
@ -28,51 +31,37 @@ impl WholeStreamCommand for SubCommand {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let tag = args.call_info.name_tag.clone();
let call_info = args.evaluate_once()?;
let block = call_info.args.expect_nth(0)?.clone();
let (condition, captured) = match block {
Value {
value: UntaggedValue::Block(captured_block),
tag,
} => {
if captured_block.block.block.len() != 1 {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
match captured_block.block.block[0].pipelines.get(0) {
Some(item) => match item.list.get(0) {
Some(ClassifiedCommand::Expr(expr)) => {
(Arc::new(expr.clone()), captured_block.captured.clone())
}
_ => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
},
None => {
let block: CapturedBlock = call_info.req(0)?;
let condition = {
if block.block.block.len() != 1 {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
match block.block.block[0].pipelines.get(0) {
Some(item) => match item.list.get(0) {
Some(ClassifiedCommand::Expr(expr)) => expr.clone(),
_ => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
},
None => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
}
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
};
Ok(call_info
@ -82,8 +71,10 @@ impl WholeStreamCommand for SubCommand {
let ctx = ctx.clone();
ctx.scope.enter_scope();
ctx.scope.add_var("$it", item.clone());
ctx.scope.add_vars(&captured.entries);
ctx.scope.add_vars(&block.captured.entries);
if let Some((arg, _)) = block.block.params.positional.first() {
ctx.scope.add_var(arg.name(), item.clone());
}
trace!("ITEM = {:?}", item);
let result = evaluate_baseline_expr(&*condition, &*ctx);

View File

@ -89,7 +89,13 @@ fn process_row(
context.scope.enter_scope();
context.scope.add_vars(&block.captured.entries);
context.scope.add_var("$it", row);
if let Some((arg, _)) = block.block.params.positional.first() {
context.scope.add_var(arg.name(), row);
} else {
context.scope.add_var("$it", row);
}
let result = run_block(
&block.block,
context,

View File

@ -3,7 +3,10 @@ use log::trace;
use nu_engine::evaluate_baseline_expr;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue, Value};
use nu_protocol::{
hir::{CapturedBlock, ClassifiedCommand},
Signature, SyntaxShape,
};
pub struct SubCommand;
@ -28,51 +31,37 @@ impl WholeStreamCommand for SubCommand {
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let tag = args.call_info.name_tag.clone();
let call_info = args.evaluate_once()?;
let block = call_info.args.expect_nth(0)?.clone();
let (condition, captured) = match block {
Value {
value: UntaggedValue::Block(captured_block),
tag,
} => {
if captured_block.block.block.len() != 1 {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
match captured_block.block.block[0].pipelines.get(0) {
Some(item) => match item.list.get(0) {
Some(ClassifiedCommand::Expr(expr)) => {
(Arc::new(expr.clone()), captured_block.captured.clone())
}
_ => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
},
None => {
let block: CapturedBlock = call_info.req(0)?;
let condition = {
if block.block.block.len() != 1 {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
match block.block.block[0].pipelines.get(0) {
Some(item) => match item.list.get(0) {
Some(ClassifiedCommand::Expr(expr)) => expr.clone(),
_ => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
},
None => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
}
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
};
Ok(call_info
@ -82,8 +71,10 @@ impl WholeStreamCommand for SubCommand {
let ctx = ctx.clone();
ctx.scope.enter_scope();
ctx.scope.add_var("$it", item.clone());
ctx.scope.add_vars(&captured.entries);
ctx.scope.add_vars(&block.captured.entries);
if let Some((arg, _)) = block.block.params.positional.first() {
ctx.scope.add_var(arg.name(), item.clone());
}
trace!("ITEM = {:?}", item);
let result = evaluate_baseline_expr(&*condition, &*ctx);

View File

@ -3,7 +3,10 @@ use log::trace;
use nu_engine::evaluate_baseline_expr;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue, Value};
use nu_protocol::{
hir::{CapturedBlock, ClassifiedCommand},
Signature, SyntaxShape,
};
pub struct SubCommand;
@ -28,51 +31,37 @@ impl WholeStreamCommand for SubCommand {
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let tag = args.call_info.name_tag.clone();
let call_info = args.evaluate_once()?;
let block = call_info.args.expect_nth(0)?.clone();
let (condition, captured) = match block {
Value {
value: UntaggedValue::Block(captured_block),
tag,
} => {
if captured_block.block.block.len() != 1 {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
match captured_block.block.block[0].pipelines.get(0) {
Some(item) => match item.list.get(0) {
Some(ClassifiedCommand::Expr(expr)) => {
(Arc::new(expr.clone()), captured_block.captured.clone())
}
_ => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
},
None => {
let block: CapturedBlock = call_info.req(0)?;
let condition = {
if block.block.block.len() != 1 {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
match block.block.block[0].pipelines.get(0) {
Some(item) => match item.list.get(0) {
Some(ClassifiedCommand::Expr(expr)) => expr.clone(),
_ => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
},
None => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
}
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Expected a condition",
"expected a condition",
tag,
));
}
};
Ok(call_info
@ -83,8 +72,10 @@ impl WholeStreamCommand for SubCommand {
let ctx = ctx.clone();
ctx.scope.enter_scope();
ctx.scope.add_vars(&captured.entries);
ctx.scope.add_var("$it", item.clone());
ctx.scope.add_vars(&block.captured.entries);
if let Some((arg, _)) = block.block.params.positional.first() {
ctx.scope.add_var(arg.name(), item.clone());
}
trace!("ITEM = {:?}", item);
let result = evaluate_baseline_expr(&*condition, &*ctx);

View File

@ -84,7 +84,10 @@ fn process_row(
let input_stream = vec![Ok(for_block)].into_iter().to_input_stream();
context.scope.enter_scope();
context.scope.add_var("$it", input.clone());
if let Some((arg, _)) = captured_block.block.params.positional.first() {
context.scope.add_var(arg.name(), input.clone());
}
context.scope.add_vars(&captured_block.captured.entries);
let result = run_block(

View File

@ -130,7 +130,10 @@ impl Iterator for WhereIterator {
while let Some(x) = self.input.next() {
self.context.scope.enter_scope();
self.context.scope.add_vars(&self.block.captured.entries);
self.context.scope.add_var("$it", x.clone());
if let Some((arg, _)) = self.block.block.params.positional.first() {
self.context.scope.add_var(arg.name(), x.clone());
}
//FIXME: should we use the scope that's brought in as well?
let condition = evaluate_baseline_expr(&self.condition, &self.context);

View File

@ -51,8 +51,6 @@ pub fn test_examples(cmd: Command) -> Result<(), ShellError> {
let block = parse_line(sample_pipeline.example, &ctx)?;
println!("{:#?}", block);
if let Some(expected) = &sample_pipeline.result {
let result = evaluate_block(block, &mut ctx)?;

View File

@ -1410,13 +1410,15 @@ fn parse_positional_argument(
let mut commands = hir::Pipeline::new(span);
commands.push(ClassifiedCommand::Expr(Box::new(arg)));
let block = hir::Block::new(
let mut block = hir::Block::new(
Signature::new("<cond>"),
vec![Group::new(vec![commands], lite_cmd.span())],
IndexMap::new(),
span,
);
block.infer_params();
let arg = SpannedExpression::new(Expression::Block(Arc::new(block)), span);
idx = new_idx - 1;

View File

@ -379,17 +379,6 @@ fn proper_shadow_let_aliases() {
assert_eq!(actual.out, "falsetruefalse");
}
#[test]
fn block_param_too_many() {
let actual = nu!(
cwd: ".",
r#"
[1, 2, 3] | each { |a, b| echo $a }
"#
);
assert!(actual.err.contains("too many"));
}
#[test]
fn block_params_override() {
let actual = nu!(
@ -401,6 +390,17 @@ fn block_params_override() {
assert!(actual.err.contains("unknown variable"));
}
#[test]
fn block_params_override_correct() {
let actual = nu!(
cwd: ".",
r#"
[1, 2, 3] | each { |a| echo $a } | to json
"#
);
assert_eq!(actual.out, "[1,2,3]");
}
#[test]
fn run_dynamic_blocks() {
let actual = nu!(