mirror of
https://github.com/nushell/nushell.git
synced 2025-04-16 01:08:21 +02:00
Remove shape-directed import pattern parsing (#7570)
This commit is contained in:
parent
74656bf976
commit
23a5c5dc09
@ -66,6 +66,7 @@ impl Completer for CustomCompletion {
|
|||||||
],
|
],
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: true,
|
redirect_stderr: true,
|
||||||
|
parser_info: vec![],
|
||||||
},
|
},
|
||||||
PipelineData::empty(),
|
PipelineData::empty(),
|
||||||
);
|
);
|
||||||
|
@ -17,7 +17,12 @@ impl Command for ExportUse {
|
|||||||
fn signature(&self) -> nu_protocol::Signature {
|
fn signature(&self) -> nu_protocol::Signature {
|
||||||
Signature::build("export use")
|
Signature::build("export use")
|
||||||
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
|
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
|
||||||
.required("pattern", SyntaxShape::ImportPattern, "import pattern")
|
.required("module", SyntaxShape::String, "Module or module file")
|
||||||
|
.optional(
|
||||||
|
"members",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"Which members of the module to import",
|
||||||
|
)
|
||||||
.category(Category::Core)
|
.category(Category::Core)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,12 @@ impl Command for Hide {
|
|||||||
fn signature(&self) -> nu_protocol::Signature {
|
fn signature(&self) -> nu_protocol::Signature {
|
||||||
Signature::build("hide")
|
Signature::build("hide")
|
||||||
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
|
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
|
||||||
.required("pattern", SyntaxShape::ImportPattern, "import pattern")
|
.required("module", SyntaxShape::String, "Module or module file")
|
||||||
|
.optional(
|
||||||
|
"members",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"Which members of the module to import",
|
||||||
|
)
|
||||||
.category(Category::Core)
|
.category(Category::Core)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +49,7 @@ This command is a parser keyword. For details, check:
|
|||||||
let env_var_name = if let Some(Expression {
|
let env_var_name = if let Some(Expression {
|
||||||
expr: Expr::ImportPattern(pat),
|
expr: Expr::ImportPattern(pat),
|
||||||
..
|
..
|
||||||
}) = call.positional_nth(0)
|
}) = call.parser_info_nth(0)
|
||||||
{
|
{
|
||||||
Spanned {
|
Spanned {
|
||||||
item: String::from_utf8_lossy(&pat.head.name).to_string(),
|
item: String::from_utf8_lossy(&pat.head.name).to_string(),
|
||||||
|
@ -66,7 +66,7 @@ impl Command for OverlayUse {
|
|||||||
let mut name_arg: Spanned<String> = call.req(engine_state, caller_stack, 0)?;
|
let mut name_arg: Spanned<String> = call.req(engine_state, caller_stack, 0)?;
|
||||||
name_arg.item = trim_quotes_str(&name_arg.item).to_string();
|
name_arg.item = trim_quotes_str(&name_arg.item).to_string();
|
||||||
|
|
||||||
let maybe_origin_module_id = if let Some(overlay_expr) = call.positional_nth(0) {
|
let maybe_origin_module_id = if let Some(overlay_expr) = call.parser_info_nth(0) {
|
||||||
if let Expr::Overlay(module_id) = overlay_expr.expr {
|
if let Expr::Overlay(module_id) = overlay_expr.expr {
|
||||||
module_id
|
module_id
|
||||||
} else {
|
} else {
|
||||||
|
@ -20,7 +20,12 @@ impl Command for Use {
|
|||||||
fn signature(&self) -> nu_protocol::Signature {
|
fn signature(&self) -> nu_protocol::Signature {
|
||||||
Signature::build("use")
|
Signature::build("use")
|
||||||
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
|
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
|
||||||
.required("pattern", SyntaxShape::ImportPattern, "import pattern")
|
.required("module", SyntaxShape::String, "Module or module file")
|
||||||
|
.optional(
|
||||||
|
"members",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"Which members of the module to import",
|
||||||
|
)
|
||||||
.category(Category::Core)
|
.category(Category::Core)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +48,7 @@ impl Command for Use {
|
|||||||
let import_pattern = if let Some(Expression {
|
let import_pattern = if let Some(Expression {
|
||||||
expr: Expr::ImportPattern(pat),
|
expr: Expr::ImportPattern(pat),
|
||||||
..
|
..
|
||||||
}) = call.positional_nth(0)
|
}) = call.parser_info_nth(0)
|
||||||
{
|
{
|
||||||
pat
|
pat
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +45,7 @@ impl Command for Source {
|
|||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
// Note: this hidden positional is the block_id that corresponded to the 0th position
|
// Note: this hidden positional is the block_id that corresponded to the 0th position
|
||||||
// it is put here by the parser
|
// it is put here by the parser
|
||||||
let block_id: i64 = call.req(engine_state, stack, 1)?;
|
let block_id: i64 = call.req_parser_info(engine_state, stack, 0)?;
|
||||||
|
|
||||||
let block = engine_state.get_block(block_id as usize).clone();
|
let block = engine_state.get_block(block_id as usize).clone();
|
||||||
eval_block(
|
eval_block(
|
||||||
|
2
crates/nu-command/src/env/source_env.rs
vendored
2
crates/nu-command/src/env/source_env.rs
vendored
@ -42,7 +42,7 @@ impl Command for SourceEnv {
|
|||||||
|
|
||||||
// Note: this hidden positional is the block_id that corresponded to the 0th position
|
// Note: this hidden positional is the block_id that corresponded to the 0th position
|
||||||
// it is put here by the parser
|
// it is put here by the parser
|
||||||
let block_id: i64 = call.req(engine_state, caller_stack, 1)?;
|
let block_id: i64 = call.req_parser_info(engine_state, caller_stack, 0)?;
|
||||||
|
|
||||||
// Set the currently evaluated directory (file-relative PWD)
|
// Set the currently evaluated directory (file-relative PWD)
|
||||||
let mut parent = if let Some(path) =
|
let mut parent = if let Some(path) =
|
||||||
|
@ -34,6 +34,13 @@ pub trait CallExt {
|
|||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
) -> Result<T, ShellError>;
|
) -> Result<T, ShellError>;
|
||||||
|
|
||||||
|
fn req_parser_info<T: FromValue>(
|
||||||
|
&self,
|
||||||
|
engine_state: &EngineState,
|
||||||
|
stack: &mut Stack,
|
||||||
|
pos: usize,
|
||||||
|
) -> Result<T, ShellError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallExt for Call {
|
impl CallExt for Call {
|
||||||
@ -99,4 +106,23 @@ impl CallExt for Call {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn req_parser_info<T: FromValue>(
|
||||||
|
&self,
|
||||||
|
engine_state: &EngineState,
|
||||||
|
stack: &mut Stack,
|
||||||
|
pos: usize,
|
||||||
|
) -> Result<T, ShellError> {
|
||||||
|
if let Some(expr) = self.parser_info_nth(pos) {
|
||||||
|
let result = eval_expression(engine_state, stack, expr)?;
|
||||||
|
FromValue::from_value(&result)
|
||||||
|
} else if self.parser_info.is_empty() {
|
||||||
|
Err(ShellError::AccessEmptyContent(self.head))
|
||||||
|
} else {
|
||||||
|
Err(ShellError::AccessBeyondEnd(
|
||||||
|
self.parser_info.len() - 1,
|
||||||
|
self.head,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -814,6 +814,7 @@ pub fn eval_element_with_input(
|
|||||||
],
|
],
|
||||||
redirect_stdout: false,
|
redirect_stdout: false,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
)
|
)
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::eval::{eval_constant, value_as_string};
|
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nu_path::canonicalize_with;
|
use nu_path::canonicalize_with;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
@ -17,13 +16,14 @@ static LIB_DIRS_ENV: &str = "NU_LIB_DIRS";
|
|||||||
static PLUGIN_DIRS_ENV: &str = "NU_PLUGIN_DIRS";
|
static PLUGIN_DIRS_ENV: &str = "NU_PLUGIN_DIRS";
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
eval::{eval_constant, value_as_string},
|
||||||
known_external::KnownExternal,
|
known_external::KnownExternal,
|
||||||
lex,
|
lex,
|
||||||
lite_parser::{lite_parse, LiteCommand, LiteElement},
|
lite_parser::{lite_parse, LiteCommand, LiteElement},
|
||||||
parser::{
|
parser::{
|
||||||
check_call, check_name, garbage, garbage_pipeline, parse, parse_internal_call,
|
check_call, check_name, garbage, garbage_pipeline, parse, parse_import_pattern,
|
||||||
parse_multispan_value, parse_signature, parse_string, parse_value, parse_var_with_opt_type,
|
parse_internal_call, parse_multispan_value, parse_signature, parse_string, parse_value,
|
||||||
trim_quotes, ParsedInternalCall,
|
parse_var_with_opt_type, trim_quotes, ParsedInternalCall,
|
||||||
},
|
},
|
||||||
unescape_unquote_string, ParseError,
|
unescape_unquote_string, ParseError,
|
||||||
};
|
};
|
||||||
@ -578,6 +578,7 @@ pub fn parse_alias(
|
|||||||
decl_id,
|
decl_id,
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
}));
|
}));
|
||||||
return (
|
return (
|
||||||
Pipeline::from_vec(vec![Expression {
|
Pipeline::from_vec(vec![Expression {
|
||||||
@ -840,6 +841,7 @@ pub fn parse_export_in_module(
|
|||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
});
|
});
|
||||||
|
|
||||||
let exportables = if let Some(kw_span) = spans.get(1) {
|
let exportables = if let Some(kw_span) = spans.get(1) {
|
||||||
@ -1505,6 +1507,7 @@ pub fn parse_module(
|
|||||||
],
|
],
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
});
|
});
|
||||||
|
|
||||||
(
|
(
|
||||||
@ -1562,7 +1565,7 @@ pub fn parse_use(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (call, call_span, use_decl_id) = match working_set.find_decl(b"use", &Type::Any) {
|
let (call, call_span, args_spans) = match working_set.find_decl(b"use", &Type::Any) {
|
||||||
Some(decl_id) => {
|
Some(decl_id) => {
|
||||||
let (command_spans, rest_spans) = spans.split_at(split_id);
|
let (command_spans, rest_spans) = spans.split_at(split_id);
|
||||||
|
|
||||||
@ -1595,7 +1598,7 @@ pub fn parse_use(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
(call, call_span, decl_id)
|
(call, call_span, rest_spans)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
return (
|
return (
|
||||||
@ -1609,34 +1612,31 @@ pub fn parse_use(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let import_pattern = if let Some(expr) = call.positional_nth(0) {
|
let mut error = None;
|
||||||
if let Some(pattern) = expr.as_import_pattern() {
|
|
||||||
pattern
|
let (import_pattern_expr, err) =
|
||||||
|
parse_import_pattern(working_set, args_spans, expand_aliases_denylist);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
let import_pattern = if let Expression {
|
||||||
|
expr: Expr::ImportPattern(import_pattern),
|
||||||
|
..
|
||||||
|
} = &import_pattern_expr
|
||||||
|
{
|
||||||
|
import_pattern.clone()
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
garbage_pipeline(spans),
|
garbage_pipeline(spans),
|
||||||
vec![],
|
vec![],
|
||||||
Some(ParseError::UnknownState(
|
Some(ParseError::UnknownState(
|
||||||
"internal error: Import pattern positional is not import pattern".into(),
|
"internal error: Import pattern positional is not import pattern".into(),
|
||||||
expr.span,
|
import_pattern_expr.span,
|
||||||
)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
garbage_pipeline(spans),
|
|
||||||
vec![],
|
|
||||||
Some(ParseError::UnknownState(
|
|
||||||
"internal error: Missing required positional after call parsing".into(),
|
|
||||||
call_span,
|
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let cwd = working_set.get_cwd();
|
let cwd = working_set.get_cwd();
|
||||||
|
|
||||||
let mut error = None;
|
|
||||||
|
|
||||||
// TODO: Add checking for importing too long import patterns, e.g.:
|
// TODO: Add checking for importing too long import patterns, e.g.:
|
||||||
// > use spam foo non existent names here do not throw error
|
// > use spam foo non existent names here do not throw error
|
||||||
let (import_pattern, module) = if let Some(module_id) = import_pattern.head.id {
|
let (import_pattern, module) = if let Some(module_id) = import_pattern.head.id {
|
||||||
@ -1842,18 +1842,13 @@ pub fn parse_use(
|
|||||||
// Create a new Use command call to pass the new import pattern
|
// Create a new Use command call to pass the new import pattern
|
||||||
let import_pattern_expr = Expression {
|
let import_pattern_expr = Expression {
|
||||||
expr: Expr::ImportPattern(import_pattern),
|
expr: Expr::ImportPattern(import_pattern),
|
||||||
span: span(&spans[1..]),
|
span: span(args_spans),
|
||||||
ty: Type::List(Box::new(Type::String)),
|
ty: Type::Any,
|
||||||
custom_completion: None,
|
custom_completion: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let call = Box::new(Call {
|
let mut call = call;
|
||||||
head: span(spans.split_at(split_id).0),
|
call.add_parser_info(import_pattern_expr);
|
||||||
decl_id: use_decl_id,
|
|
||||||
arguments: vec![Argument::Positional(import_pattern_expr)],
|
|
||||||
redirect_stdout: true,
|
|
||||||
redirect_stderr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
(
|
(
|
||||||
Pipeline::from_vec(vec![Expression {
|
Pipeline::from_vec(vec![Expression {
|
||||||
@ -1882,7 +1877,7 @@ pub fn parse_hide(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (call, call_span, hide_decl_id) = match working_set.find_decl(b"hide", &Type::Any) {
|
let (call, args_spans) = match working_set.find_decl(b"hide", &Type::Any) {
|
||||||
Some(decl_id) => {
|
Some(decl_id) => {
|
||||||
let ParsedInternalCall {
|
let ParsedInternalCall {
|
||||||
call,
|
call,
|
||||||
@ -1912,7 +1907,7 @@ pub fn parse_hide(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
(call, call_span, decl_id)
|
(call, &spans[1..])
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
return (
|
return (
|
||||||
@ -1925,29 +1920,28 @@ pub fn parse_hide(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let import_pattern = if let Some(expr) = call.positional_nth(0) {
|
let mut error = None;
|
||||||
if let Some(pattern) = expr.as_import_pattern() {
|
|
||||||
pattern
|
let (import_pattern_expr, err) =
|
||||||
|
parse_import_pattern(working_set, args_spans, expand_aliases_denylist);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
let import_pattern = if let Expression {
|
||||||
|
expr: Expr::ImportPattern(import_pattern),
|
||||||
|
..
|
||||||
|
} = &import_pattern_expr
|
||||||
|
{
|
||||||
|
import_pattern.clone()
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
garbage_pipeline(spans),
|
garbage_pipeline(spans),
|
||||||
Some(ParseError::UnknownState(
|
Some(ParseError::UnknownState(
|
||||||
"internal error: Import pattern positional is not import pattern".into(),
|
"internal error: Import pattern positional is not import pattern".into(),
|
||||||
call_span,
|
import_pattern_expr.span,
|
||||||
)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
garbage_pipeline(spans),
|
|
||||||
Some(ParseError::UnknownState(
|
|
||||||
"internal error: Missing required positional after call parsing".into(),
|
|
||||||
call_span,
|
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut error = None;
|
|
||||||
let bytes = working_set.get_span_contents(spans[0]);
|
let bytes = working_set.get_span_contents(spans[0]);
|
||||||
|
|
||||||
if bytes == b"hide" && spans.len() >= 2 {
|
if bytes == b"hide" && spans.len() >= 2 {
|
||||||
@ -2054,18 +2048,13 @@ pub fn parse_hide(
|
|||||||
// Create a new Use command call to pass the new import pattern
|
// Create a new Use command call to pass the new import pattern
|
||||||
let import_pattern_expr = Expression {
|
let import_pattern_expr = Expression {
|
||||||
expr: Expr::ImportPattern(import_pattern),
|
expr: Expr::ImportPattern(import_pattern),
|
||||||
span: span(&spans[1..]),
|
span: span(args_spans),
|
||||||
ty: Type::List(Box::new(Type::String)),
|
ty: Type::Any,
|
||||||
custom_completion: None,
|
custom_completion: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let call = Box::new(Call {
|
let mut call = call;
|
||||||
head: spans[0],
|
call.add_parser_info(import_pattern_expr);
|
||||||
decl_id: hide_decl_id,
|
|
||||||
arguments: vec![Argument::Positional(import_pattern_expr)],
|
|
||||||
redirect_stdout: true,
|
|
||||||
redirect_stderr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
(
|
(
|
||||||
Pipeline::from_vec(vec![Expression {
|
Pipeline::from_vec(vec![Expression {
|
||||||
@ -2612,13 +2601,16 @@ pub fn parse_overlay_use(
|
|||||||
|
|
||||||
// Change the call argument to include the Overlay expression with the module ID
|
// Change the call argument to include the Overlay expression with the module ID
|
||||||
let mut call = call;
|
let mut call = call;
|
||||||
if let Some(overlay_expr) = call.positional_nth_mut(0) {
|
call.add_parser_info(Expression {
|
||||||
overlay_expr.expr = Expr::Overlay(if is_module_updated {
|
expr: Expr::Overlay(if is_module_updated {
|
||||||
Some(origin_module_id)
|
Some(origin_module_id)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
}),
|
||||||
|
span: overlay_name_span,
|
||||||
|
ty: Type::Any,
|
||||||
|
custom_completion: None,
|
||||||
});
|
});
|
||||||
} // no need to check for else since it was already checked
|
|
||||||
|
|
||||||
let pipeline = Pipeline::from_vec(vec![Expression {
|
let pipeline = Pipeline::from_vec(vec![Expression {
|
||||||
expr: Expr::Call(call),
|
expr: Expr::Call(call),
|
||||||
@ -2836,6 +2828,7 @@ pub fn parse_let_or_const(
|
|||||||
],
|
],
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -2957,6 +2950,7 @@ pub fn parse_mut(
|
|||||||
],
|
],
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -3131,7 +3125,7 @@ pub fn parse_source(
|
|||||||
|
|
||||||
// FIXME: Adding this expression to the positional creates a syntax highlighting error
|
// FIXME: Adding this expression to the positional creates a syntax highlighting error
|
||||||
// after writing `source example.nu`
|
// after writing `source example.nu`
|
||||||
call_with_block.add_positional(Expression {
|
call_with_block.add_parser_info(Expression {
|
||||||
expr: Expr::Int(block_id as i64),
|
expr: Expr::Int(block_id as i64),
|
||||||
span: spans[1],
|
span: spans[1],
|
||||||
ty: Type::Any,
|
ty: Type::Any,
|
||||||
|
@ -695,16 +695,6 @@ pub fn parse_multispan_value(
|
|||||||
|
|
||||||
(arg, error)
|
(arg, error)
|
||||||
}
|
}
|
||||||
SyntaxShape::ImportPattern => {
|
|
||||||
trace!("parsing: import pattern");
|
|
||||||
|
|
||||||
let (arg, err) =
|
|
||||||
parse_import_pattern(working_set, &spans[*spans_idx..], expand_aliases_denylist);
|
|
||||||
error = error.or(err);
|
|
||||||
*spans_idx = spans.len() - 1;
|
|
||||||
|
|
||||||
(arg, error)
|
|
||||||
}
|
|
||||||
SyntaxShape::Keyword(keyword, arg) => {
|
SyntaxShape::Keyword(keyword, arg) => {
|
||||||
trace!(
|
trace!(
|
||||||
"parsing: keyword({}) {:?}",
|
"parsing: keyword({}) {:?}",
|
||||||
@ -5171,6 +5161,7 @@ pub fn parse_expression(
|
|||||||
arguments,
|
arguments,
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
(
|
(
|
||||||
@ -5904,6 +5895,7 @@ fn wrap_expr_with_collect(working_set: &mut StateWorkingSet, expr: &Expression)
|
|||||||
decl_id,
|
decl_id,
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
})),
|
})),
|
||||||
span,
|
span,
|
||||||
ty: Type::String,
|
ty: Type::String,
|
||||||
|
@ -18,6 +18,8 @@ pub struct Call {
|
|||||||
pub arguments: Vec<Argument>,
|
pub arguments: Vec<Argument>,
|
||||||
pub redirect_stdout: bool,
|
pub redirect_stdout: bool,
|
||||||
pub redirect_stderr: bool,
|
pub redirect_stderr: bool,
|
||||||
|
/// this field is used by the parser to pass additional command-specific information
|
||||||
|
pub parser_info: Vec<Expression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Call {
|
impl Call {
|
||||||
@ -28,6 +30,7 @@ impl Call {
|
|||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
redirect_stdout: true,
|
redirect_stdout: true,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
|
parser_info: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +70,10 @@ impl Call {
|
|||||||
self.arguments.push(Argument::Positional(positional));
|
self.arguments.push(Argument::Positional(positional));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_parser_info(&mut self, info: Expression) {
|
||||||
|
self.parser_info.push(info);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_unknown(&mut self, unknown: Expression) {
|
pub fn add_unknown(&mut self, unknown: Expression) {
|
||||||
self.arguments.push(Argument::Unknown(unknown));
|
self.arguments.push(Argument::Unknown(unknown));
|
||||||
}
|
}
|
||||||
@ -99,6 +106,10 @@ impl Call {
|
|||||||
self.positional_iter().count()
|
self.positional_iter().count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parser_info_nth(&self, i: usize) -> Option<&Expression> {
|
||||||
|
self.parser_info.get(i)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn has_flag(&self, flag_name: &str) -> bool {
|
pub fn has_flag(&self, flag_name: &str) -> bool {
|
||||||
for name in self.named_iter() {
|
for name in self.named_iter() {
|
||||||
if flag_name == name.0.item {
|
if flag_name == name.0.item {
|
||||||
|
Loading…
Reference in New Issue
Block a user