Improve empty pipelines (#7383)

# Description

This fix changes pipelines to allow them to actually be empty. Mapping
over empty pipelines gives empty pipelines. Empty pipelines immediately
return `None` when iterated.

This removes a some of where `Span::new(0, 0)` was coming from, though
there are other cases where we still use it.

# User-Facing Changes

None

# Tests + Formatting

Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass

# After Submitting

If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
JT
2022-12-08 07:31:57 +13:00
committed by GitHub
parent d18587330a
commit eaec480f42
80 changed files with 194 additions and 190 deletions

View File

@ -92,7 +92,7 @@ impl NuCompleter {
&self.engine_state,
&mut callee_stack,
block,
PipelineData::new(span),
PipelineData::empty(),
true,
true,
);

View File

@ -67,7 +67,7 @@ impl Completer for CustomCompletion {
redirect_stdout: true,
redirect_stderr: true,
},
PipelineData::new(span),
PipelineData::empty(),
);
let mut custom_completion_options = None;

View File

@ -8,7 +8,7 @@ use nu_path::canonicalize_with;
use nu_protocol::engine::{EngineState, Stack, StateWorkingSet};
#[cfg(feature = "plugin")]
use nu_protocol::Spanned;
use nu_protocol::{HistoryFileFormat, PipelineData, Span};
use nu_protocol::{HistoryFileFormat, PipelineData};
use std::path::PathBuf;
#[cfg(feature = "plugin")]
@ -38,7 +38,7 @@ pub fn read_plugin_file(
stack,
&contents,
&plugin_filename,
PipelineData::new(Span::new(0, 0)),
PipelineData::empty(),
);
}
}
@ -85,7 +85,7 @@ pub fn eval_config_contents(
stack,
&contents,
&config_filename,
PipelineData::new(Span::new(0, 0)),
PipelineData::empty(),
);
// Merge the environment in case env vars changed in the config

View File

@ -39,13 +39,7 @@ pub fn evaluate_file(
if working_set.find_decl(b"main", &Type::Any).is_some() {
let args = format!("main {}", args.join(" "));
if !eval_source(
engine_state,
stack,
&file,
&path,
PipelineData::new(Span::new(0, 0)),
) {
if !eval_source(engine_state, stack, &file, &path, PipelineData::empty()) {
std::process::exit(1);
}
if !eval_source(engine_state, stack, args.as_bytes(), "<commandline>", input) {

View File

@ -50,14 +50,13 @@ Since this command has no output, there is no point in piping it with other comm
let args: Vec<Value> = call.rest(engine_state, stack, 0)?;
let no_newline = call.has_flag("no-newline");
let to_stderr = call.has_flag("stderr");
let head = call.head;
for arg in args {
arg.into_pipeline_data()
.print(engine_state, stack, no_newline, to_stderr)?;
}
Ok(PipelineData::new(head))
Ok(PipelineData::empty())
}
fn examples(&self) -> Vec<Example> {

View File

@ -4,7 +4,7 @@ use log::info;
use nu_engine::eval_subexpression;
use nu_protocol::{
engine::{EngineState, Stack, StateWorkingSet},
Config, PipelineData, Span, Value,
Config, PipelineData, Value,
};
use reedline::Prompt;
@ -37,12 +37,8 @@ fn get_prompt_string(
let block = engine_state.get_block(block_id);
let mut stack = stack.captures_to_stack(&captures);
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt
let ret_val = eval_subexpression(
engine_state,
&mut stack,
block,
PipelineData::new(Span::new(0, 0)), // Don't try this at home, 0 span is ignored
);
let ret_val =
eval_subexpression(engine_state, &mut stack, block, PipelineData::empty());
info!(
"get_prompt_string (block) {}:{}:{}",
file!(),
@ -62,12 +58,7 @@ fn get_prompt_string(
Value::Block { val: block_id, .. } => {
let block = engine_state.get_block(block_id);
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt
let ret_val = eval_subexpression(
engine_state,
stack,
block,
PipelineData::new(Span::new(0, 0)), // Don't try this at home, 0 span is ignored
);
let ret_val = eval_subexpression(engine_state, stack, block, PipelineData::empty());
info!(
"get_prompt_string (block) {}:{}:{}",
file!(),

View File

@ -149,7 +149,7 @@ pub fn evaluate_repl(
stack,
s.item.as_bytes(),
&format!("entry #{}", entry_num),
PipelineData::new(Span::new(0, 0)),
PipelineData::empty(),
);
engine_state.merge_env(stack, get_guaranteed_cwd(engine_state, stack))?;
}
@ -431,7 +431,7 @@ pub fn evaluate_repl(
stack,
s.as_bytes(),
&format!("entry #{}", entry_num),
PipelineData::new(Span::new(0, 0)),
PipelineData::empty(),
);
}
let cmd_duration = start_time.elapsed();
@ -637,7 +637,7 @@ pub fn eval_string_with_input(
let input_as_pipeline_data = match input {
Some(input) => PipelineData::Value(input, None),
None => PipelineData::new(Span::test_data()),
None => PipelineData::empty(),
};
eval_block(
@ -722,7 +722,7 @@ pub fn eval_hook(
val: "condition".to_string(),
span: value_span,
};
let mut output = PipelineData::new(Span::new(0, 0));
let mut output = PipelineData::empty();
let code_path = PathMember::String {
val: "code".to_string(),
@ -823,7 +823,7 @@ pub fn eval_hook(
};
engine_state.merge_delta(delta)?;
let input = PipelineData::new(value_span);
let input = PipelineData::empty();
let var_ids: Vec<VarId> = vars
.into_iter()
@ -943,7 +943,7 @@ pub fn run_hook_block(
) -> Result<Value, ShellError> {
let block = engine_state.get_block(block_id);
let input = optional_input.unwrap_or_else(|| PipelineData::new(span));
let input = optional_input.unwrap_or_else(PipelineData::empty);
let mut callee_stack = stack.gather_captures(&block.captures);