Remove it expansion (#2701)

* Remove it-expansion, take 2

* Cleanup

* silly update to test CI
This commit is contained in:
Jonathan Turner
2020-10-26 19:55:52 +13:00
committed by GitHub
parent 502c9ea706
commit 6951fb440c
95 changed files with 175 additions and 642 deletions

View File

@ -393,13 +393,10 @@ pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
match nu_parser::lite_parse(&prompt_line, 0).map_err(ShellError::from) {
Ok(result) => {
let mut prompt_block =
nu_parser::classify_block(&result, context.registry());
let prompt_block = nu_parser::classify_block(&result, context.registry());
let env = context.get_env();
prompt_block.block.expand_it_usage();
match run_block(
&prompt_block.block,
&mut context,
@ -862,8 +859,7 @@ pub async fn parse_and_eval(line: &str, ctx: &mut EvaluationContext) -> Result<S
let lite_result = nu_parser::lite_parse(&line, 0)?;
// TODO ensure the command whose examples we're testing is actually in the pipeline
let mut classified_block = nu_parser::classify_block(&lite_result, ctx.registry());
classified_block.block.expand_it_usage();
let classified_block = nu_parser::classify_block(&lite_result, ctx.registry());
let input_stream = InputStream::empty();
let env = ctx.get_env();
@ -904,7 +900,7 @@ pub async fn process_line(
debug!("=== Parsed ===");
debug!("{:#?}", result);
let mut classified_block = nu_parser::classify_block(&result, ctx.registry());
let classified_block = nu_parser::classify_block(&result, ctx.registry());
debug!("{:#?}", classified_block);
//println!("{:#?}", pipeline);
@ -1021,8 +1017,6 @@ pub async fn process_line(
InputStream::empty()
};
classified_block.block.expand_it_usage();
trace!("{:#?}", classified_block);
let env = ctx.get_env();
match run_block(

View File

@ -4,7 +4,7 @@ use crate::prelude::*;
use nu_data::config;
use nu_errors::ShellError;
use nu_parser::SignatureRegistry;
use nu_protocol::hir::{ClassifiedCommand, Expression, NamedValue, SpannedExpression, Variable};
use nu_protocol::hir::{ClassifiedCommand, Expression, NamedValue, SpannedExpression};
use nu_protocol::{
hir::Block, CommandAction, NamedType, PositionalType, ReturnSuccess, Signature, SyntaxShape,
UntaggedValue, Value,
@ -243,7 +243,7 @@ fn find_expr_shapes(
Expression::Block(b) => find_block_shapes(&b, registry),
Expression::Path(path) => match &path.head.expr {
Expression::Invocation(b) => find_block_shapes(&b, registry),
Expression::Variable(Variable::Other(var, _)) => {
Expression::Variable(var, _) => {
let mut result = HashMap::new();
result.insert(var.to_string(), (spanned_expr.span, None));
Ok(result)

View File

@ -219,33 +219,15 @@ fn spawn(
UntaggedValue::Primitive(Primitive::Nothing) => continue,
UntaggedValue::Primitive(Primitive::String(s))
| UntaggedValue::Primitive(Primitive::Line(s)) => {
if let Err(e) = stdin_write.write(s.as_bytes()) {
let message = format!("Unable to write to stdin (error = {})", e);
let _ = stdin_write_tx.send(Ok(Value {
value: UntaggedValue::Error(ShellError::labeled_error(
message,
"application may have closed before completing pipeline",
&stdin_name_tag,
)),
tag: stdin_name_tag,
}));
return Err(());
if stdin_write.write(s.as_bytes()).is_err() {
// Other side has closed, so exit
return Ok(());
}
}
UntaggedValue::Primitive(Primitive::Binary(b)) => {
if let Err(e) = stdin_write.write(b) {
let message = format!("Unable to write to stdin (error = {})", e);
let _ = stdin_write_tx.send(Ok(Value {
value: UntaggedValue::Error(ShellError::labeled_error(
message,
"application may have closed before completing pipeline",
&stdin_name_tag,
)),
tag: stdin_name_tag,
}));
return Err(());
if stdin_write.write(b).is_err() {
// Other side has closed, so exit
return Ok(());
}
}
unsupported => {

View File

@ -97,7 +97,7 @@ pub async fn process_row(
&block,
Arc::make_mut(&mut context),
input_stream,
Scope::append_it(scope, input),
Scope::append_var(scope, "$it", input),
)
.await?
.to_output_stream())

View File

@ -187,7 +187,7 @@ async fn process_row(
let for_block = input.clone();
let input_stream = once(async { Ok(for_block) }).to_input_stream();
let scope = Scope::append_it(scope, input.clone());
let scope = Scope::append_var(scope, "$it", input.clone());
let mut stream = run_block(
&default_block,

View File

@ -50,7 +50,7 @@ impl WholeStreamCommand for Command {
},
Example {
description: "restrict the flattening by passing column names",
example: "echo [[origin, crate, versions]; [World, $(echo [[name]; ['nu-cli']]), ['0.21', '0.22']]] | flatten versions | last | = $it.versions",
example: "echo [[origin, crate, versions]; [World, $(echo [[name]; ['nu-cli']]), ['0.21', '0.22']]] | flatten versions | last | get versions",
result: Some(vec![Value::from("0.22")]),
}
]

View File

@ -83,7 +83,7 @@ async fn format_command(
let result = evaluate_baseline_expr(
&full_column_path.0,
&registry,
Scope::append_it(scope.clone(), value.clone()),
Scope::append_var(scope.clone(), "$it", value.clone()),
)
.await;

View File

@ -121,7 +121,7 @@ async fn if_command(
let then_case = then_case.clone();
let else_case = else_case.clone();
let registry = registry.clone();
let scope = Scope::append_it(scope.clone(), input);
let scope = Scope::append_var(scope.clone(), "$it", input);
let mut context = context.clone();
async move {

View File

@ -87,7 +87,7 @@ async fn process_row(
let for_block = input.clone();
let input_stream = once(async { Ok(for_block) }).to_input_stream();
let scope = Scope::append_it(scope, input.clone());
let scope = Scope::append_var(scope, "$it", input.clone());
let result = run_block(&block, Arc::make_mut(&mut context), input_stream, scope).await;
@ -140,7 +140,7 @@ async fn process_row(
value: UntaggedValue::Primitive(Primitive::Nothing),
..
} => match scope
.it()
.var("$it")
.unwrap_or_else(|| UntaggedValue::nothing().into_untagged_value())
.insert_data_at_column_path(&field, value.clone())
{

View File

@ -37,7 +37,7 @@ impl WholeStreamCommand for IntoInt {
fn examples(&self) -> Vec<Example> {
vec![Example {
description: "Convert filesize to integer",
example: "echo 1kb | into-int $it | = $it / 1024",
example: "into-int 1kb | each { = $it / 1024 }",
result: Some(vec![UntaggedValue::int(1).into()]),
}]
}

View File

@ -85,7 +85,7 @@ impl WholeStreamCommand for SubCommand {
.take_while(move |item| {
let condition = condition.clone();
let registry = registry.clone();
let scope = Scope::append_it(scope.clone(), item.clone());
let scope = Scope::append_var(scope.clone(), "$it", item.clone());
trace!("ITEM = {:?}", item);
async move {

View File

@ -84,7 +84,7 @@ impl WholeStreamCommand for SubCommand {
.take_while(move |item| {
let condition = condition.clone();
let registry = registry.clone();
let scope = Scope::append_it(scope.clone(), item.clone());
let scope = Scope::append_var(scope.clone(), "$it", item.clone());
trace!("ITEM = {:?}", item);
async move {

View File

@ -213,7 +213,8 @@ pub async fn fetch(
)),
};
let res = std::fs::read(location)?;
let res = std::fs::read(location)
.map_err(|_| ShellError::labeled_error("Can't open filename given", "can't open", span))?;
// If no encoding is provided we try to guess the encoding to read the file with
let encoding = if encoding_choice.is_none() {

View File

@ -87,7 +87,7 @@ async fn process_row(
let row_clone = row.clone();
let input_stream = once(async { Ok(row_clone) }).to_input_stream();
let scope = Scope::append_it(scope, row);
let scope = Scope::append_var(scope, "$it", row);
Ok(run_block(&block, Arc::make_mut(&mut context), input_stream, scope).await?)
}
@ -145,7 +145,7 @@ async fn reduce(
UntaggedValue::table(&values).into_untagged_value()
};
let scope = Scope::append_var(scope, "$acc".into(), f);
let scope = Scope::append_var(scope, "$acc", f);
process_row(block, scope, context, row).await
}
})
@ -173,7 +173,7 @@ async fn reduce(
UntaggedValue::table(&values).into_untagged_value()
};
let scope = Scope::append_var(scope, "$acc".into(), f);
let scope = Scope::append_var(scope, "$acc", f);
process_row(block, scope, context, row).await
}
})

View File

@ -84,7 +84,7 @@ impl WholeStreamCommand for SubCommand {
.skip_while(move |item| {
let condition = condition.clone();
let registry = registry.clone();
let scope = Scope::append_it(scope.clone(), item.clone());
let scope = Scope::append_var(scope.clone(), "$it", item.clone());
trace!("ITEM = {:?}", item);
async move {

View File

@ -85,7 +85,7 @@ impl WholeStreamCommand for SubCommand {
let item = item.clone();
let condition = condition.clone();
let registry = registry.clone();
let scope = Scope::append_it(scope.clone(), item.clone());
let scope = Scope::append_var(scope.clone(), "$it", item.clone());
trace!("ITEM = {:?}", item);
async move {

View File

@ -92,7 +92,7 @@ async fn process_row(
let for_block = input.clone();
let input_stream = once(async { Ok(for_block) }).to_input_stream();
let scope = Scope::append_it(scope, input.clone());
let scope = Scope::append_var(scope, "$it", input.clone());
let result = run_block(&block, Arc::make_mut(&mut context), input_stream, scope).await;
@ -149,7 +149,7 @@ async fn process_row(
value: UntaggedValue::Primitive(Primitive::Nothing),
..
} => match scope
.it()
.var("$it")
.unwrap_or_else(|| UntaggedValue::nothing().into_untagged_value())
.replace_data_at_column_path(&field, replacement.clone())
{

View File

@ -106,7 +106,7 @@ async fn where_command(
.filter_map(move |input| {
let condition = condition.clone();
let registry = registry.clone();
let scope = Scope::append_it(scope.clone(), input.clone());
let scope = Scope::append_var(scope.clone(), "$it", input.clone());
async move {
//FIXME: should we use the scope that's brought in as well?

View File

@ -38,7 +38,7 @@ impl<'s> Flatten<'s> {
.collect(),
Expression::Command => vec![LocationType::Command.spanned(e.span)],
Expression::Path(path) => self.expression(&path.head),
Expression::Variable(_) => vec![LocationType::Variable.spanned(e.span)],
Expression::Variable(_, _) => vec![LocationType::Variable.spanned(e.span)],
Expression::Boolean(_)
| Expression::FilePath(_)

View File

@ -32,7 +32,7 @@ pub(crate) async fn evaluate_baseline_expr(
Expression::Synthetic(hir::Synthetic::String(s)) => {
Ok(UntaggedValue::string(s).into_untagged_value())
}
Expression::Variable(var) => evaluate_reference(&var, scope, tag),
Expression::Variable(var, _) => evaluate_reference(&var, scope, tag),
Expression::Command => unimplemented!(),
Expression::Invocation(block) => evaluate_invocation(block, registry, scope).await,
Expression::ExternalCommand(_) => unimplemented!(),
@ -199,38 +199,36 @@ fn evaluate_literal(literal: &hir::Literal, span: Span) -> Value {
}
}
fn evaluate_reference(
name: &hir::Variable,
scope: Arc<Scope>,
tag: Tag,
) -> Result<Value, ShellError> {
fn evaluate_reference(name: &str, scope: Arc<Scope>, tag: Tag) -> Result<Value, ShellError> {
match name {
hir::Variable::It(_) => match scope.it() {
"$nu" => crate::evaluate::variables::nu(&scope.env(), tag),
"$true" => Ok(Value {
value: UntaggedValue::boolean(true),
tag,
}),
"$false" => Ok(Value {
value: UntaggedValue::boolean(false),
tag,
}),
"$it" => match scope.var("$it") {
Some(v) => Ok(v),
None => Err(ShellError::labeled_error(
"$it variable not in scope",
"not in scope (are you missing an 'each'?)",
"Variable not in scope",
"missing '$it' (note: $it is only available inside of a block)",
tag.span,
)),
},
hir::Variable::Other(name, _) => match name {
x if x == "$nu" => crate::evaluate::variables::nu(&scope.env(), tag),
x if x == "$true" => Ok(Value {
value: UntaggedValue::boolean(true),
tag,
}),
x if x == "$false" => Ok(Value {
value: UntaggedValue::boolean(false),
tag,
}),
x => match scope.var(x) {
Some(v) => Ok(v),
None => Err(ShellError::labeled_error(
"Variable not in scope",
"unknown variable",
tag.span,
)),
},
x => match scope.var(x) {
Some(v) => Ok(v),
None => Err(ShellError::labeled_error(
"Variable not in scope",
"unknown variable",
tag.span,
)),
},
}
}
@ -244,7 +242,7 @@ async fn evaluate_invocation(
let mut context = EvaluationContext::basic()?;
context.registry = registry.clone();
let input = match scope.it() {
let input = match scope.var("$it") {
Some(it) => InputStream::one(it),
None => InputStream::empty(),
};

View File

@ -200,8 +200,7 @@ fn parse_line(line: &str, ctx: &mut EvaluationContext) -> Result<ClassifiedBlock
let lite_result = nu_parser::lite_parse(&line, 0)?;
// TODO ensure the command whose examples we're testing is actually in the pipeline
let mut classified_block = nu_parser::classify_block(&lite_result, ctx.registry());
classified_block.block.expand_it_usage();
let classified_block = nu_parser::classify_block(&lite_result, ctx.registry());
Ok(classified_block)
}

View File

@ -737,15 +737,14 @@ impl Shell for FilesystemShell {
let mut codec = MaybeTextCodec::new(with_encoding);
match codec.decode(&mut bytes_mut).map_err(|e| {
ShellError::unexpected(format!("AsyncRead failed in open function: {:?}", e))
match codec.decode(&mut bytes_mut).map_err(|_| {
ShellError::labeled_error("Error opening file", "error opening file", name)
})? {
Some(sb) => Ok(futures::stream::iter(vec![Ok(sb)].into_iter()).boxed()),
None => Ok(futures::stream::iter(vec![].into_iter()).boxed()),
}
} else {
// We don't know that this is a finite file, so treat it as a stream
let f = std::fs::File::open(&path).map_err(|e| {
ShellError::labeled_error(
format!("Error opening file: {:?}", e),
@ -755,8 +754,8 @@ impl Shell for FilesystemShell {
})?;
let async_reader = futures::io::AllowStdIo::new(f);
let sob_stream = FramedRead::new(async_reader, MaybeTextCodec::new(with_encoding))
.map_err(|e| {
ShellError::unexpected(format!("AsyncRead failed in open function: {:?}", e))
.map_err(move |_| {
ShellError::labeled_error("Error opening file", "error opening file", name)
})
.into_stream();