omg it compiles
This commit is contained in:
parent
acee591003
commit
b0d24ea434
|
@ -39,6 +39,8 @@ impl Command for TimeIt {
|
|||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
// FIXME: get working with IR. I don't think this should actually be so AST dependent
|
||||
let call = call.assert_ast_call()?;
|
||||
let command_to_run = call.positional_nth(0);
|
||||
|
||||
// Get the start time after all other computation has been done.
|
||||
|
|
1
crates/nu-command/src/env/export_env.rs
vendored
1
crates/nu-command/src/env/export_env.rs
vendored
|
@ -30,6 +30,7 @@ impl Command for ExportEnv {
|
|||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let call = call.assert_ast_call()?; // FIXME
|
||||
let block_id = call
|
||||
.positional_nth(0)
|
||||
.expect("checked through parser")
|
||||
|
|
1
crates/nu-command/src/env/source_env.rs
vendored
1
crates/nu-command/src/env/source_env.rs
vendored
|
@ -35,6 +35,7 @@ impl Command for SourceEnv {
|
|||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let call = call.assert_ast_call()?; // FIXME
|
||||
let source_filename: Spanned<String> = call.req(engine_state, caller_stack, 0)?;
|
||||
|
||||
// Note: this hidden positional is the block_id that corresponded to the 0th position
|
||||
|
|
|
@ -103,7 +103,7 @@ impl Command for Du {
|
|||
let current_dir = current_dir(engine_state, stack)?;
|
||||
|
||||
let paths = get_rest_for_glob_pattern(engine_state, stack, call, 0)?;
|
||||
let paths = if call.rest_iter(0).count() == 0 {
|
||||
let paths = if !call.has_positional_args(stack, 0) {
|
||||
None
|
||||
} else {
|
||||
Some(paths)
|
||||
|
|
|
@ -110,7 +110,7 @@ impl Command for Ls {
|
|||
};
|
||||
|
||||
let pattern_arg = get_rest_for_glob_pattern(engine_state, stack, call, 0)?;
|
||||
let input_pattern_arg = if call.rest_iter(0).count() == 0 {
|
||||
let input_pattern_arg = if !call.has_positional_args(stack, 0) {
|
||||
None
|
||||
} else {
|
||||
Some(pattern_arg)
|
||||
|
|
|
@ -57,7 +57,7 @@ impl Command for Open {
|
|||
let mut paths = get_rest_for_glob_pattern(engine_state, stack, call, 0)?;
|
||||
let eval_block = get_eval_block(engine_state);
|
||||
|
||||
if paths.is_empty() && call.rest_iter(0).next().is_none() {
|
||||
if paths.is_empty() && !call.has_positional_args(stack, 0) {
|
||||
// try to use path from pipeline input if there were no positional or spread args
|
||||
let (filename, span) = match input {
|
||||
PipelineData::Value(val, ..) => {
|
||||
|
|
|
@ -4,10 +4,8 @@ use nu_engine::get_eval_block;
|
|||
use nu_engine::{command_prelude::*, current_dir};
|
||||
use nu_path::expand_path_with;
|
||||
use nu_protocol::{
|
||||
ast::{Expr, Expression},
|
||||
byte_stream::copy_with_interrupt,
|
||||
process::ChildPipe,
|
||||
ByteStreamSource, DataSource, OutDest, PipelineMetadata,
|
||||
ast, byte_stream::copy_with_interrupt, process::ChildPipe, ByteStreamSource, DataSource,
|
||||
OutDest, PipelineMetadata,
|
||||
};
|
||||
use std::{
|
||||
fs::File,
|
||||
|
@ -70,24 +68,6 @@ impl Command for Save {
|
|||
let append = call.has_flag(engine_state, stack, "append")?;
|
||||
let force = call.has_flag(engine_state, stack, "force")?;
|
||||
let progress = call.has_flag(engine_state, stack, "progress")?;
|
||||
let out_append = if let Some(Expression {
|
||||
expr: Expr::Bool(out_append),
|
||||
..
|
||||
}) = call.get_parser_info("out-append")
|
||||
{
|
||||
*out_append
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let err_append = if let Some(Expression {
|
||||
expr: Expr::Bool(err_append),
|
||||
..
|
||||
}) = call.get_parser_info("err-append")
|
||||
{
|
||||
*err_append
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let span = call.head;
|
||||
#[allow(deprecated)]
|
||||
|
@ -110,14 +90,7 @@ impl Command for Save {
|
|||
PipelineData::ByteStream(stream, metadata) => {
|
||||
check_saving_to_source_file(metadata.as_ref(), &path, stderr_path.as_ref())?;
|
||||
|
||||
let (file, stderr_file) = get_files(
|
||||
&path,
|
||||
stderr_path.as_ref(),
|
||||
append,
|
||||
out_append,
|
||||
err_append,
|
||||
force,
|
||||
)?;
|
||||
let (file, stderr_file) = get_files(&path, stderr_path.as_ref(), append, force)?;
|
||||
|
||||
let size = stream.known_size();
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
@ -222,14 +195,7 @@ impl Command for Save {
|
|||
stderr_path.as_ref(),
|
||||
)?;
|
||||
|
||||
let (mut file, _) = get_files(
|
||||
&path,
|
||||
stderr_path.as_ref(),
|
||||
append,
|
||||
out_append,
|
||||
err_append,
|
||||
force,
|
||||
)?;
|
||||
let (mut file, _) = get_files(&path, stderr_path.as_ref(), append, force)?;
|
||||
for val in ls {
|
||||
file.write_all(&value_to_bytes(val)?)
|
||||
.map_err(|err| ShellError::IOError {
|
||||
|
@ -259,14 +225,7 @@ impl Command for Save {
|
|||
input_to_bytes(input, Path::new(&path.item), raw, engine_state, stack, span)?;
|
||||
|
||||
// Only open file after successful conversion
|
||||
let (mut file, _) = get_files(
|
||||
&path,
|
||||
stderr_path.as_ref(),
|
||||
append,
|
||||
out_append,
|
||||
err_append,
|
||||
force,
|
||||
)?;
|
||||
let (mut file, _) = get_files(&path, stderr_path.as_ref(), append, force)?;
|
||||
|
||||
file.write_all(&bytes).map_err(|err| ShellError::IOError {
|
||||
msg: err.to_string(),
|
||||
|
@ -398,7 +357,8 @@ fn convert_to_extension(
|
|||
let eval_block = get_eval_block(engine_state);
|
||||
eval_block(engine_state, stack, block, input)
|
||||
} else {
|
||||
decl.run(engine_state, stack, &Call::new(span), input)
|
||||
let call = ast::Call::new(span);
|
||||
decl.run(engine_state, stack, &(&call).into(), input)
|
||||
}
|
||||
} else {
|
||||
Ok(input)
|
||||
|
@ -474,19 +434,17 @@ fn get_files(
|
|||
path: &Spanned<PathBuf>,
|
||||
stderr_path: Option<&Spanned<PathBuf>>,
|
||||
append: bool,
|
||||
out_append: bool,
|
||||
err_append: bool,
|
||||
force: bool,
|
||||
) -> Result<(File, Option<File>), ShellError> {
|
||||
// First check both paths
|
||||
let (path, path_span) = prepare_path(path, append || out_append, force)?;
|
||||
let (path, path_span) = prepare_path(path, append, force)?;
|
||||
let stderr_path_and_span = stderr_path
|
||||
.as_ref()
|
||||
.map(|stderr_path| prepare_path(stderr_path, append || err_append, force))
|
||||
.map(|stderr_path| prepare_path(stderr_path, append, force))
|
||||
.transpose()?;
|
||||
|
||||
// Only if both files can be used open and possibly truncate them
|
||||
let file = open_file(path, path_span, append || out_append)?;
|
||||
let file = open_file(path, path_span, append)?;
|
||||
|
||||
let stderr_file = stderr_path_and_span
|
||||
.map(|(stderr_path, stderr_path_span)| {
|
||||
|
@ -499,7 +457,7 @@ fn get_files(
|
|||
inner: vec![],
|
||||
})
|
||||
} else {
|
||||
open_file(stderr_path, stderr_path_span, append || err_append)
|
||||
open_file(stderr_path, stderr_path_span, append)
|
||||
}
|
||||
})
|
||||
.transpose()?;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use dialoguer::Input;
|
||||
use nu_engine::{command_prelude::*, get_eval_expression};
|
||||
use nu_protocol::{ast::Expr, FromValue, NuGlob};
|
||||
use nu_protocol::{FromValue, NuGlob};
|
||||
use std::{
|
||||
error::Error,
|
||||
path::{Path, PathBuf},
|
||||
|
@ -92,42 +92,19 @@ pub fn is_older(src: &Path, dst: &Path) -> Option<bool> {
|
|||
|
||||
/// Get rest arguments from given `call`, starts with `starting_pos`.
|
||||
///
|
||||
/// It's similar to `call.rest`, except that it always returns NuGlob. And if input argument has
|
||||
/// Type::Glob, the NuGlob is unquoted, which means it's required to expand.
|
||||
/// It's similar to `call.rest`, except that it always returns NuGlob.
|
||||
pub fn get_rest_for_glob_pattern(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
starting_pos: usize,
|
||||
) -> Result<Vec<Spanned<NuGlob>>, ShellError> {
|
||||
let mut output = vec![];
|
||||
let eval_expression = get_eval_expression(engine_state);
|
||||
|
||||
for result in call.rest_iter_flattened(starting_pos, |expr| {
|
||||
let result = eval_expression(engine_state, stack, expr);
|
||||
match result {
|
||||
Err(e) => Err(e),
|
||||
Ok(result) => {
|
||||
let span = result.span();
|
||||
// convert from string to quoted string if expr is a variable
|
||||
// or string interpolation
|
||||
match result {
|
||||
Value::String { val, .. }
|
||||
if matches!(
|
||||
&expr.expr,
|
||||
Expr::FullCellPath(_) | Expr::StringInterpolation(_)
|
||||
) =>
|
||||
{
|
||||
// should not expand if given input type is not glob.
|
||||
Ok(Value::glob(val, expr.ty != Type::Glob, span))
|
||||
}
|
||||
other => Ok(other),
|
||||
}
|
||||
}
|
||||
}
|
||||
})? {
|
||||
output.push(FromValue::from_value(result)?);
|
||||
}
|
||||
|
||||
Ok(output)
|
||||
call.rest_iter_flattened(engine_state, stack, eval_expression, starting_pos)?
|
||||
.into_iter()
|
||||
// This used to be much more complex, but I think `FromValue` should be able to handle the
|
||||
// nuance here.
|
||||
.map(FromValue::from_value)
|
||||
.collect()
|
||||
}
|
||||
|
|
|
@ -149,27 +149,27 @@ pub fn transpose(
|
|||
if !args.rest.is_empty() && args.header_row {
|
||||
return Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "Can not provide header names and use `--header-row`".into(),
|
||||
span: call.get_named_arg("header-row").expect("has flag").span,
|
||||
span: call.get_flag_span(stack, "header-row").expect("has flag"),
|
||||
});
|
||||
}
|
||||
if !args.header_row && args.keep_all {
|
||||
return Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "Can only be used with `--header-row`(`-r`)".into(),
|
||||
span: call.get_named_arg("keep-all").expect("has flag").span,
|
||||
span: call.get_flag_span(stack, "keep-all").expect("has flag"),
|
||||
});
|
||||
}
|
||||
if !args.header_row && args.keep_last {
|
||||
return Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "Can only be used with `--header-row`(`-r`)".into(),
|
||||
span: call.get_named_arg("keep-last").expect("has flag").span,
|
||||
span: call.get_flag_span(stack, "keep-last").expect("has flag"),
|
||||
});
|
||||
}
|
||||
if args.keep_all && args.keep_last {
|
||||
return Err(ShellError::IncompatibleParameters {
|
||||
left_message: "can't use `--keep-last` at the same time".into(),
|
||||
left_span: call.get_named_arg("keep-last").expect("has flag").span,
|
||||
left_span: call.get_flag_span(stack, "keep-last").expect("has flag"),
|
||||
right_message: "because of `--keep-all`".into(),
|
||||
right_span: call.get_named_arg("keep-all").expect("has flag").span,
|
||||
right_span: call.get_flag_span(stack, "keep-all").expect("has flag"),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use nu_engine::{CallExt, ClosureEval};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Closure, EngineState, Stack},
|
||||
engine::{Call, Closure, EngineState, Stack},
|
||||
IntoPipelineData, PipelineData, ShellError, Span, Value,
|
||||
};
|
||||
|
||||
|
|
|
@ -676,7 +676,7 @@ Operating system commands:
|
|||
}
|
||||
};
|
||||
|
||||
let output = heavy_lifting(code, escape, osc, call)?;
|
||||
let output = heavy_lifting(code, escape, osc, stack, call)?;
|
||||
|
||||
Ok(Value::string(output, call.head).into_pipeline_data())
|
||||
}
|
||||
|
@ -710,26 +710,30 @@ Operating system commands:
|
|||
}
|
||||
};
|
||||
|
||||
let output = heavy_lifting(code, escape, osc, call)?;
|
||||
let output = heavy_lifting(code, escape, osc, &Stack::new(), call)?;
|
||||
|
||||
Ok(Value::string(output, call.head).into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
||||
fn heavy_lifting(code: Value, escape: bool, osc: bool, call: &Call) -> Result<String, ShellError> {
|
||||
fn heavy_lifting(
|
||||
code: Value,
|
||||
escape: bool,
|
||||
osc: bool,
|
||||
stack: &Stack,
|
||||
call: &Call,
|
||||
) -> Result<String, ShellError> {
|
||||
let param_is_string = matches!(code, Value::String { .. });
|
||||
if escape && osc {
|
||||
return Err(ShellError::IncompatibleParameters {
|
||||
left_message: "escape".into(),
|
||||
left_span: call
|
||||
.get_named_arg("escape")
|
||||
.expect("Unexpected missing argument")
|
||||
.span,
|
||||
.get_flag_span(stack, "escape")
|
||||
.expect("Unexpected missing argument"),
|
||||
right_message: "osc".into(),
|
||||
right_span: call
|
||||
.get_named_arg("osc")
|
||||
.expect("Unexpected missing argument")
|
||||
.span,
|
||||
.get_flag_span(stack, "osc")
|
||||
.expect("Unexpected missing argument"),
|
||||
});
|
||||
}
|
||||
let code_string = if param_is_string {
|
||||
|
@ -741,10 +745,7 @@ fn heavy_lifting(code: Value, escape: bool, osc: bool, call: &Call) -> Result<St
|
|||
if (escape || osc) && (param_is_valid_string) {
|
||||
let code_vec: Vec<char> = code_string.chars().collect();
|
||||
if code_vec[0] == '\\' {
|
||||
let span = match call.get_flag_expr("escape") {
|
||||
Some(expr) => expr.span,
|
||||
None => call.head,
|
||||
};
|
||||
let span = call.get_flag_span(stack, "escape").unwrap_or(call.head);
|
||||
|
||||
return Err(ShellError::TypeMismatch {
|
||||
err_message: "no need for escape characters".into(),
|
||||
|
|
|
@ -58,7 +58,7 @@ impl Command for IsTerminal {
|
|||
_ => {
|
||||
return Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "Only one stream may be checked".into(),
|
||||
span: Span::merge_many(call.arguments.iter().map(|arg| arg.span())),
|
||||
span: call.arguments_span(),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -84,27 +84,26 @@ impl Command for Kill {
|
|||
{
|
||||
return Err(ShellError::IncompatibleParameters {
|
||||
left_message: "force".to_string(),
|
||||
left_span: call
|
||||
.get_named_arg("force")
|
||||
.ok_or_else(|| ShellError::GenericError {
|
||||
left_span: call.get_flag_span(stack, "force").ok_or_else(|| {
|
||||
ShellError::GenericError {
|
||||
error: "Flag error".into(),
|
||||
msg: "flag force not found".into(),
|
||||
span: Some(call.head),
|
||||
help: None,
|
||||
inner: vec![],
|
||||
})?
|
||||
.span,
|
||||
}
|
||||
})?,
|
||||
right_message: "signal".to_string(),
|
||||
right_span: Span::merge(
|
||||
call.get_named_arg("signal")
|
||||
.ok_or_else(|| ShellError::GenericError {
|
||||
call.get_flag_span(stack, "signal").ok_or_else(|| {
|
||||
ShellError::GenericError {
|
||||
error: "Flag error".into(),
|
||||
msg: "flag signal not found".into(),
|
||||
span: Some(call.head),
|
||||
help: None,
|
||||
inner: vec![],
|
||||
})?
|
||||
.span,
|
||||
}
|
||||
})?,
|
||||
signal_span,
|
||||
),
|
||||
});
|
||||
|
|
|
@ -17,8 +17,7 @@ pub use str_::*;
|
|||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{EngineState, Stack, StateWorkingSet},
|
||||
engine::{Call, EngineState, Stack, StateWorkingSet},
|
||||
ShellError,
|
||||
};
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ On Windows based systems, Nushell will wait for the command to finish and then e
|
|||
command.envs(envs);
|
||||
|
||||
// Configure args.
|
||||
let args = crate::eval_arguments_from_call(engine_state, stack, call)?;
|
||||
let args = crate::eval_arguments_from_call(engine_state, stack, call.assert_ast_call()?)?;
|
||||
command.args(args.into_iter().map(|s| s.item));
|
||||
|
||||
// Execute the child process, replacing/terminating the current process
|
||||
|
|
|
@ -87,7 +87,7 @@ impl Command for NuCheck {
|
|||
&path_str.item,
|
||||
engine_state,
|
||||
stack,
|
||||
get_dirs_var_from_call(call),
|
||||
get_dirs_var_from_call(call.assert_ast_call()?), // FIXME
|
||||
) {
|
||||
Ok(path) => {
|
||||
if let Some(path) = path {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use nu_cmd_base::hook::eval_hook;
|
||||
use nu_engine::{command_prelude::*, env_to_strings, get_eval_expression};
|
||||
use nu_protocol::{
|
||||
ast::{Expr, Expression},
|
||||
ast::{self, Expr, Expression},
|
||||
did_you_mean,
|
||||
process::ChildProcess,
|
||||
ByteStream, NuGlob, OutDest,
|
||||
|
@ -45,6 +45,9 @@ impl Command for External {
|
|||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
// FIXME: this currently only works with AST calls, but I think #13089 totally fixes that
|
||||
// so if I can merge that, this should just work fine
|
||||
let call = call.assert_ast_call()?;
|
||||
let cwd = engine_state.cwd(Some(stack))?;
|
||||
|
||||
// Evaluate the command name in the same way the arguments are evaluated. Since this isn't
|
||||
|
@ -236,7 +239,7 @@ fn remove_quotes(s: &str) -> Cow<'_, str> {
|
|||
pub fn eval_arguments_from_call(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
call: &ast::Call,
|
||||
) -> Result<Vec<Spanned<String>>, ShellError> {
|
||||
let ctrlc = &engine_state.ctrlc;
|
||||
let cwd = engine_state.cwd(Some(stack))?;
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
use nu_protocol::record;
|
||||
use nu_protocol::Value;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Type,
|
||||
};
|
||||
use nu_engine::command_prelude::*;
|
||||
use nu_protocol::{record, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UName;
|
||||
|
|
|
@ -339,7 +339,7 @@ fn get_theme_flag(
|
|||
struct CmdInput<'a> {
|
||||
engine_state: &'a EngineState,
|
||||
stack: &'a mut Stack,
|
||||
call: &'a Call,
|
||||
call: &'a Call<'a>,
|
||||
data: PipelineData,
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,7 @@ impl<'a> CmdInput<'a> {
|
|||
fn new(
|
||||
engine_state: &'a EngineState,
|
||||
stack: &'a mut Stack,
|
||||
call: &'a Call,
|
||||
call: &'a Call<'a>,
|
||||
data: PipelineData,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
|
|
@ -4,7 +4,7 @@ use nu_protocol::{
|
|||
debugger::WithoutDebug,
|
||||
engine::{self, EngineState, Stack, StateWorkingSet},
|
||||
eval_const::eval_constant,
|
||||
ir, FromValue, ShellError, Value,
|
||||
ir, FromValue, ShellError, Span, Value,
|
||||
};
|
||||
|
||||
pub trait CallExt {
|
||||
|
@ -23,6 +23,9 @@ pub trait CallExt {
|
|||
name: &str,
|
||||
) -> Result<Option<T>, ShellError>;
|
||||
|
||||
/// Efficiently get the span of a flag argument
|
||||
fn get_flag_span(&self, stack: &Stack, name: &str) -> Option<Span>;
|
||||
|
||||
fn rest<T: FromValue>(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -107,6 +110,10 @@ impl CallExt for ast::Call {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_flag_span(&self, _stack: &Stack, name: &str) -> Option<Span> {
|
||||
self.get_named_arg(name).map(|arg| arg.span)
|
||||
}
|
||||
|
||||
fn rest<T: FromValue>(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -224,6 +231,11 @@ impl CallExt for ir::Call {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_flag_span(&self, stack: &Stack, name: &str) -> Option<Span> {
|
||||
self.named_iter(stack)
|
||||
.find_map(|(i_name, _)| (i_name.item == name).then_some(i_name.span))
|
||||
}
|
||||
|
||||
fn rest<T: FromValue>(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
|
@ -317,6 +329,10 @@ impl CallExt for engine::Call<'_> {
|
|||
proxy!(self.get_flag(engine_state, stack, name))
|
||||
}
|
||||
|
||||
fn get_flag_span(&self, stack: &Stack, name: &str) -> Option<Span> {
|
||||
proxy!(self.get_flag_span(stack, name))
|
||||
}
|
||||
|
||||
fn rest<T: FromValue>(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
|
|
@ -244,6 +244,7 @@ pub fn path_str(
|
|||
}
|
||||
|
||||
pub const DIR_VAR_PARSER_INFO: &str = "dirs_var";
|
||||
// FIXME: this should be possible on IR calls
|
||||
pub fn get_dirs_var_from_call(call: &Call) -> Option<VarId> {
|
||||
call.get_parser_info(DIR_VAR_PARSER_INFO).and_then(|x| {
|
||||
if let Expr::Var(id) = x.expr {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use nu_parser::*;
|
||||
use nu_protocol::{
|
||||
ast::{Argument, Call, Expr, ExternalArgument, PathMember, Range},
|
||||
engine::{Command, EngineState, Stack, StateWorkingSet},
|
||||
ast::{Argument, Expr, ExternalArgument, PathMember, Range},
|
||||
engine::{Call, Command, EngineState, Stack, StateWorkingSet},
|
||||
ParseError, PipelineData, ShellError, Signature, Span, SyntaxShape,
|
||||
};
|
||||
use rstest::rstest;
|
||||
|
@ -1507,10 +1507,7 @@ mod range {
|
|||
#[cfg(test)]
|
||||
mod input_types {
|
||||
use super::*;
|
||||
use nu_protocol::{
|
||||
ast::{Argument, Call},
|
||||
Category, PipelineData, ShellError, Type,
|
||||
};
|
||||
use nu_protocol::{ast::Argument, engine::Call, Category, PipelineData, ShellError, Type};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LsTest;
|
||||
|
|
|
@ -21,6 +21,18 @@ pub enum CallImpl<'a> {
|
|||
}
|
||||
|
||||
impl Call<'_> {
|
||||
/// Returns a new AST call with the given span. This is often used by commands that need an
|
||||
/// empty call to pass to a command. It's not easily possible to add anything to this.
|
||||
pub fn new(span: Span) -> Self {
|
||||
// this is using the boxed variant, which isn't so efficient... but this is only temporary
|
||||
// anyway.
|
||||
Call {
|
||||
head: span,
|
||||
decl_id: 0,
|
||||
inner: CallImpl::AstBox(Box::new(ast::Call::new(span))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the `Call` from any lifetime into `'static`, by cloning the data within onto the
|
||||
/// heap.
|
||||
pub fn to_owned(&self) -> Call<'static> {
|
||||
|
@ -85,6 +97,16 @@ impl Call<'_> {
|
|||
.rest_const(working_set, starting_pos)
|
||||
}
|
||||
|
||||
/// Returns a span covering the call's arguments.
|
||||
pub fn arguments_span(&self) -> Span {
|
||||
match &self.inner {
|
||||
CallImpl::AstRef(call) => call.arguments_span(),
|
||||
CallImpl::AstBox(call) => call.arguments_span(),
|
||||
CallImpl::IrRef(call) => call.arguments_span(),
|
||||
CallImpl::IrBox(call) => call.arguments_span(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a span covering the whole call.
|
||||
pub fn span(&self) -> Span {
|
||||
match &self.inner {
|
||||
|
|
|
@ -175,7 +175,7 @@ impl CallBuilder {
|
|||
self.inner.args_base = stack.argument_stack.get_base();
|
||||
}
|
||||
self.inner.args_len += 1;
|
||||
self.inner.span.end = self.inner.span.end.max(argument.span().end);
|
||||
self.inner.span = self.inner.span.append(argument.span());
|
||||
stack.argument_stack.push(argument);
|
||||
self
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user