forked from extern/nushell
Add an alias denylist for expansions (#4871)
This commit is contained in:
parent
5a1af4d661
commit
983d115bc0
@ -31,7 +31,7 @@ pub fn evaluate_commands(
|
||||
(commands.item.as_bytes(), commands.span.start)
|
||||
};
|
||||
|
||||
let (output, err) = parse(&mut working_set, None, input, false);
|
||||
let (output, err) = parse(&mut working_set, None, input, false, &[]);
|
||||
if let Some(err) = err {
|
||||
report_error(&working_set, &err);
|
||||
|
||||
|
@ -206,7 +206,13 @@ impl NuCompleter {
|
||||
let mut line = line.to_string();
|
||||
line.insert(pos, 'a');
|
||||
let pos = offset + pos;
|
||||
let (output, _err) = parse(&mut working_set, Some("completer"), line.as_bytes(), false);
|
||||
let (output, _err) = parse(
|
||||
&mut working_set,
|
||||
Some("completer"),
|
||||
line.as_bytes(),
|
||||
false,
|
||||
&[],
|
||||
);
|
||||
|
||||
for pipeline in output.pipelines.into_iter() {
|
||||
for expr in pipeline.expressions {
|
||||
|
@ -36,7 +36,7 @@ pub fn evaluate_file(
|
||||
let mut working_set = StateWorkingSet::new(engine_state);
|
||||
trace!("parsing file: {}", path);
|
||||
|
||||
let _ = parse(&mut working_set, Some(&path), &file, false);
|
||||
let _ = parse(&mut working_set, Some(&path), &file, false, &[]);
|
||||
|
||||
if working_set.find_decl(b"main").is_some() {
|
||||
let args = format!("main {}", args.join(" "));
|
||||
|
@ -104,7 +104,7 @@ fn get_prompt_string(
|
||||
}
|
||||
Value::String { val: source, .. } => {
|
||||
let mut working_set = StateWorkingSet::new(engine_state);
|
||||
let (block, _) = parse(&mut working_set, None, source.as_bytes(), true);
|
||||
let (block, _) = parse(&mut working_set, None, source.as_bytes(), true, &[]);
|
||||
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt
|
||||
let ret_val = eval_subexpression(
|
||||
engine_state,
|
||||
|
@ -17,7 +17,7 @@ impl Highlighter for NuHighlighter {
|
||||
|
||||
let (shapes, global_span_offset) = {
|
||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||
let (block, _) = parse(&mut working_set, None, line.as_bytes(), false);
|
||||
let (block, _) = parse(&mut working_set, None, line.as_bytes(), false, &[]);
|
||||
|
||||
let shapes = flatten_block(&working_set, &block);
|
||||
(shapes, self.engine_state.next_span_start())
|
||||
|
@ -287,6 +287,7 @@ pub fn eval_source(
|
||||
Some(fname), // format!("entry #{}", entry_num)
|
||||
source,
|
||||
false,
|
||||
&[],
|
||||
);
|
||||
if let Some(err) = err {
|
||||
report_error(&working_set, &err);
|
||||
|
@ -9,7 +9,7 @@ pub struct NuValidator {
|
||||
impl Validator for NuValidator {
|
||||
fn validate(&self, line: &str) -> ValidationResult {
|
||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||
let (_, err) = parse(&mut working_set, None, line.as_bytes(), false);
|
||||
let (_, err) = parse(&mut working_set, None, line.as_bytes(), false, &[]);
|
||||
|
||||
if matches!(err, Some(ParseError::UnexpectedEof(..))) {
|
||||
ValidationResult::Incomplete
|
||||
|
@ -44,7 +44,13 @@ pub fn test_dataframe(cmds: Vec<Box<dyn Command + 'static>>) {
|
||||
|
||||
let (block, delta) = {
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let (output, err) = parse(&mut working_set, None, example.example.as_bytes(), false);
|
||||
let (output, err) = parse(
|
||||
&mut working_set,
|
||||
None,
|
||||
example.example.as_bytes(),
|
||||
false,
|
||||
&[],
|
||||
);
|
||||
|
||||
if let Some(err) = err {
|
||||
panic!("test parse error in `{}`: {:?}", example.example, err)
|
||||
|
@ -84,7 +84,13 @@ pub fn test_examples(cmd: impl Command + 'static) {
|
||||
|
||||
let (block, delta) = {
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let (output, err) = parse(&mut working_set, None, example.example.as_bytes(), false);
|
||||
let (output, err) = parse(
|
||||
&mut working_set,
|
||||
None,
|
||||
example.example.as_bytes(),
|
||||
false,
|
||||
&[],
|
||||
);
|
||||
|
||||
if let Some(err) = err {
|
||||
panic!("test parse error in `{}`: {:?}", example.example, err)
|
||||
|
@ -89,7 +89,7 @@ impl Command for FromNuon {
|
||||
let (lite_block, err) = nu_parser::lite_parse(&lexed);
|
||||
error = error.or(err);
|
||||
|
||||
let (mut block, err) = nu_parser::parse_block(&mut working_set, &lite_block, true);
|
||||
let (mut block, err) = nu_parser::parse_block(&mut working_set, &lite_block, true, &[]);
|
||||
error = error.or(err);
|
||||
|
||||
if let Some(pipeline) = block.pipelines.get(1) {
|
||||
|
@ -19,7 +19,7 @@ fn quickcheck_parse(data: String) -> bool {
|
||||
let mut working_set = StateWorkingSet::new(&context);
|
||||
working_set.add_file("quickcheck".into(), data.as_bytes());
|
||||
|
||||
let _ = nu_parser::parse_block(&mut working_set, &lite_block, false);
|
||||
let _ = nu_parser::parse_block(&mut working_set, &lite_block, false, &[]);
|
||||
}
|
||||
}
|
||||
true
|
||||
|
@ -51,7 +51,7 @@ impl Command for KnownExternal {
|
||||
|
||||
let spans: Vec<_> = lexed.into_iter().map(|x| x.span).collect();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let (external_call, _) = crate::parse_external_call(&mut working_set, &spans);
|
||||
let (external_call, _) = crate::parse_external_call(&mut working_set, &spans, &[]);
|
||||
let delta = working_set.render();
|
||||
engine_state.merge_delta(delta, None, ".")?;
|
||||
|
||||
|
@ -26,7 +26,11 @@ use crate::{
|
||||
ParseError,
|
||||
};
|
||||
|
||||
pub fn parse_def_predecl(working_set: &mut StateWorkingSet, spans: &[Span]) -> Option<ParseError> {
|
||||
pub fn parse_def_predecl(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> Option<ParseError> {
|
||||
let name = working_set.get_span_contents(spans[0]);
|
||||
|
||||
// handle "export def" same as "def"
|
||||
@ -47,7 +51,7 @@ pub fn parse_def_predecl(working_set: &mut StateWorkingSet, spans: &[Span]) -> O
|
||||
// The second time is when we actually parse the body itworking_set.
|
||||
// We can't reuse the first time because the variables that are created during parse_signature
|
||||
// are lost when we exit the scope below.
|
||||
let (sig, ..) = parse_signature(working_set, spans[2]);
|
||||
let (sig, ..) = parse_signature(working_set, spans[2], expand_aliases_denylist);
|
||||
let signature = sig.as_signature();
|
||||
working_set.exit_scope();
|
||||
|
||||
@ -70,7 +74,7 @@ pub fn parse_def_predecl(working_set: &mut StateWorkingSet, spans: &[Span]) -> O
|
||||
// The second time is when we actually parse the body itworking_set.
|
||||
// We can't reuse the first time because the variables that are created during parse_signature
|
||||
// are lost when we exit the scope below.
|
||||
let (sig, ..) = parse_signature(working_set, spans[2]);
|
||||
let (sig, ..) = parse_signature(working_set, spans[2], expand_aliases_denylist);
|
||||
let signature = sig.as_signature();
|
||||
working_set.exit_scope();
|
||||
|
||||
@ -95,6 +99,7 @@ pub fn parse_def_predecl(working_set: &mut StateWorkingSet, spans: &[Span]) -> O
|
||||
pub fn parse_for(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
// Checking that the function is used with the correct name
|
||||
// Maybe this is not necessary but it is a sanity check
|
||||
@ -123,7 +128,13 @@ pub fn parse_for(
|
||||
}
|
||||
Some(decl_id) => {
|
||||
working_set.enter_scope();
|
||||
let (call, mut err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, mut err) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
working_set.exit_scope();
|
||||
|
||||
let call_span = span(spans);
|
||||
@ -251,6 +262,7 @@ fn build_usage(working_set: &StateWorkingSet, spans: &[Span]) -> String {
|
||||
pub fn parse_def(
|
||||
working_set: &mut StateWorkingSet,
|
||||
lite_command: &LiteCommand,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
let spans = &lite_command.parts[..];
|
||||
|
||||
@ -285,7 +297,13 @@ pub fn parse_def(
|
||||
}
|
||||
Some(decl_id) => {
|
||||
working_set.enter_scope();
|
||||
let (call, mut err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, mut err) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
working_set.exit_scope();
|
||||
|
||||
let call_span = span(spans);
|
||||
@ -385,6 +403,7 @@ pub fn parse_def(
|
||||
pub fn parse_extern(
|
||||
working_set: &mut StateWorkingSet,
|
||||
lite_command: &LiteCommand,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
let spans = &lite_command.parts[..];
|
||||
let mut error = None;
|
||||
@ -420,7 +439,13 @@ pub fn parse_extern(
|
||||
}
|
||||
Some(decl_id) => {
|
||||
working_set.enter_scope();
|
||||
let (call, err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, err) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
working_set.exit_scope();
|
||||
|
||||
error = error.or(err);
|
||||
@ -486,6 +511,7 @@ pub fn parse_extern(
|
||||
pub fn parse_alias(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
let name = working_set.get_span_contents(spans[0]);
|
||||
|
||||
@ -495,7 +521,13 @@ pub fn parse_alias(
|
||||
}
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(b"alias") {
|
||||
let (call, _) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, _) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
|
||||
if spans.len() >= 4 {
|
||||
let alias_name = working_set.get_span_contents(spans[1]);
|
||||
@ -539,6 +571,7 @@ pub fn parse_alias(
|
||||
pub fn parse_export(
|
||||
working_set: &mut StateWorkingSet,
|
||||
lite_command: &LiteCommand,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<Exportable>, Option<ParseError>) {
|
||||
let spans = &lite_command.parts[..];
|
||||
let mut error = None;
|
||||
@ -597,7 +630,8 @@ pub fn parse_export(
|
||||
comments: lite_command.comments.clone(),
|
||||
parts: spans[1..].to_vec(),
|
||||
};
|
||||
let (pipeline, err) = parse_def(working_set, &lite_command);
|
||||
let (pipeline, err) =
|
||||
parse_def(working_set, &lite_command, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
let export_def_decl_id = if let Some(id) = working_set.find_decl(b"export def") {
|
||||
@ -655,7 +689,8 @@ pub fn parse_export(
|
||||
comments: lite_command.comments.clone(),
|
||||
parts: spans[1..].to_vec(),
|
||||
};
|
||||
let (pipeline, err) = parse_def(working_set, &lite_command);
|
||||
let (pipeline, err) =
|
||||
parse_def(working_set, &lite_command, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
let export_def_decl_id = if let Some(id) = working_set.find_decl(b"export def-env")
|
||||
@ -738,6 +773,7 @@ pub fn parse_export(
|
||||
working_set,
|
||||
&SyntaxShape::Block(None),
|
||||
*block_span,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
@ -835,6 +871,7 @@ pub fn parse_export(
|
||||
pub fn parse_module_block(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Block, Overlay, Option<ParseError>) {
|
||||
let mut error = None;
|
||||
|
||||
@ -851,7 +888,11 @@ pub fn parse_module_block(
|
||||
for pipeline in &output.block {
|
||||
// TODO: Should we add export env predecls as well?
|
||||
if pipeline.commands.len() == 1 {
|
||||
parse_def_predecl(working_set, &pipeline.commands[0].parts);
|
||||
parse_def_predecl(
|
||||
working_set,
|
||||
&pipeline.commands[0].parts,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -866,12 +907,17 @@ pub fn parse_module_block(
|
||||
|
||||
let (pipeline, err) = match name {
|
||||
b"def" | b"def-env" => {
|
||||
let (pipeline, err) = parse_def(working_set, &pipeline.commands[0]);
|
||||
let (pipeline, err) =
|
||||
parse_def(working_set, &pipeline.commands[0], expand_aliases_denylist);
|
||||
|
||||
(pipeline, err)
|
||||
}
|
||||
b"extern" => {
|
||||
let (pipeline, err) = parse_extern(working_set, &pipeline.commands[0]);
|
||||
let (pipeline, err) = parse_extern(
|
||||
working_set,
|
||||
&pipeline.commands[0],
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
|
||||
(pipeline, err)
|
||||
}
|
||||
@ -884,8 +930,11 @@ pub fn parse_module_block(
|
||||
// will work only if you call `use foo *; b` but not with `use foo; foo b`
|
||||
// since in the second case, the name of the env var would be $env."foo a".
|
||||
b"export" => {
|
||||
let (pipe, exportable, err) =
|
||||
parse_export(working_set, &pipeline.commands[0]);
|
||||
let (pipe, exportable, err) = parse_export(
|
||||
working_set,
|
||||
&pipeline.commands[0],
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
|
||||
if err.is_none() {
|
||||
let name_span = pipeline.commands[0].parts[2];
|
||||
@ -934,6 +983,7 @@ pub fn parse_module_block(
|
||||
pub fn parse_module(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
// TODO: Currently, module is closing over its parent scope (i.e., defs in the parent scope are
|
||||
// visible and usable in this module's scope). We want to disable that for files.
|
||||
@ -972,7 +1022,8 @@ pub fn parse_module(
|
||||
|
||||
let block_span = Span { start, end };
|
||||
|
||||
let (block, overlay, err) = parse_module_block(working_set, block_span);
|
||||
let (block, overlay, err) =
|
||||
parse_module_block(working_set, block_span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
let block_id = working_set.add_block(block);
|
||||
@ -1021,6 +1072,7 @@ pub fn parse_module(
|
||||
pub fn parse_use(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
if working_set.get_span_contents(spans[0]) != b"use" {
|
||||
return (
|
||||
@ -1034,7 +1086,13 @@ pub fn parse_use(
|
||||
|
||||
let (call, call_span, use_decl_id) = match working_set.find_decl(b"use") {
|
||||
Some(decl_id) => {
|
||||
let (call, mut err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, mut err) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
let decl = working_set.get_decl(decl_id);
|
||||
|
||||
let call_span = span(spans);
|
||||
@ -1124,8 +1182,11 @@ pub fn parse_use(
|
||||
working_set.add_file(module_filename, &contents);
|
||||
let span_end = working_set.next_span_start();
|
||||
|
||||
let (block, overlay, err) =
|
||||
parse_module_block(working_set, Span::new(span_start, span_end));
|
||||
let (block, overlay, err) = parse_module_block(
|
||||
working_set,
|
||||
Span::new(span_start, span_end),
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
let _ = working_set.add_block(block);
|
||||
@ -1230,6 +1291,7 @@ pub fn parse_use(
|
||||
pub fn parse_hide(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
if working_set.get_span_contents(spans[0]) != b"hide" {
|
||||
return (
|
||||
@ -1243,7 +1305,13 @@ pub fn parse_hide(
|
||||
|
||||
let (call, call_span, hide_decl_id) = match working_set.find_decl(b"hide") {
|
||||
Some(decl_id) => {
|
||||
let (call, mut err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, mut err) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
let decl = working_set.get_decl(decl_id);
|
||||
|
||||
let call_span = span(spans);
|
||||
@ -1440,6 +1508,7 @@ pub fn parse_hide(
|
||||
pub fn parse_let(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
let name = working_set.get_span_contents(spans[0]);
|
||||
|
||||
@ -1466,6 +1535,7 @@ pub fn parse_let(
|
||||
spans,
|
||||
&mut idx,
|
||||
&SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)),
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
@ -1512,7 +1582,13 @@ pub fn parse_let(
|
||||
}
|
||||
}
|
||||
}
|
||||
let (call, err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, err) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
|
||||
return (
|
||||
Pipeline {
|
||||
@ -1539,6 +1615,7 @@ pub fn parse_let(
|
||||
pub fn parse_source(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
let mut error = None;
|
||||
let name = working_set.get_span_contents(spans[0]);
|
||||
@ -1548,7 +1625,13 @@ pub fn parse_source(
|
||||
let cwd = working_set.get_cwd();
|
||||
// Is this the right call to be using here?
|
||||
// Some of the others (`parse_let`) use it, some of them (`parse_hide`) don't.
|
||||
let (call, err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, err) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
if error.is_some() || call.has_flag("help") {
|
||||
@ -1577,6 +1660,7 @@ pub fn parse_source(
|
||||
path.file_name().and_then(|x| x.to_str()),
|
||||
&contents,
|
||||
false,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
|
||||
if err.is_some() {
|
||||
@ -1648,6 +1732,7 @@ pub fn parse_source(
|
||||
pub fn parse_register(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
use nu_plugin::{get_signature, EncodingType, PluginDeclaration};
|
||||
use nu_protocol::Signature;
|
||||
@ -1679,7 +1764,13 @@ pub fn parse_register(
|
||||
)
|
||||
}
|
||||
Some(decl_id) => {
|
||||
let (call, mut err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
let (call, mut err) = parse_internal_call(
|
||||
working_set,
|
||||
spans[0],
|
||||
&spans[1..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
let decl = working_set.get_decl(decl_id);
|
||||
|
||||
let call_span = span(spans);
|
||||
|
@ -208,6 +208,7 @@ pub fn check_name<'a>(
|
||||
pub fn parse_external_call(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let mut args = vec![];
|
||||
|
||||
@ -235,10 +236,17 @@ pub fn parse_external_call(
|
||||
new_spans.extend(&spans[1..])
|
||||
}
|
||||
|
||||
working_set.enter_scope();
|
||||
working_set.hide_alias(&head_contents);
|
||||
let (mut result, err) = parse_external_call(working_set, &new_spans);
|
||||
working_set.exit_scope();
|
||||
let expand_aliases_denylist = if let Some(alias_id) = working_set.find_alias(&head_contents)
|
||||
{
|
||||
let mut expand_aliases_denylist = expand_aliases_denylist.to_vec();
|
||||
expand_aliases_denylist.push(alias_id);
|
||||
expand_aliases_denylist
|
||||
} else {
|
||||
expand_aliases_denylist.to_vec()
|
||||
};
|
||||
|
||||
let (mut result, err) =
|
||||
parse_external_call(working_set, &new_spans, &expand_aliases_denylist);
|
||||
result.replace_span(working_set, expansion_span, orig_span);
|
||||
|
||||
return (result, err);
|
||||
@ -247,7 +255,7 @@ pub fn parse_external_call(
|
||||
let mut error = None;
|
||||
|
||||
let head = if head_contents.starts_with(b"$") || head_contents.starts_with(b"(") {
|
||||
let (arg, err) = parse_expression(working_set, &[head_span], true);
|
||||
let (arg, err) = parse_expression(working_set, &[head_span], expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
Box::new(arg)
|
||||
} else {
|
||||
@ -263,11 +271,12 @@ pub fn parse_external_call(
|
||||
let contents = working_set.get_span_contents(*span);
|
||||
|
||||
if contents.starts_with(b"$") || contents.starts_with(b"(") {
|
||||
let (arg, err) = parse_dollar_expr(working_set, *span);
|
||||
let (arg, err) = parse_dollar_expr(working_set, *span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
args.push(arg);
|
||||
} else if contents.starts_with(b"(") {
|
||||
let (arg, err) = parse_full_cell_path(working_set, None, *span);
|
||||
let (arg, err) =
|
||||
parse_full_cell_path(working_set, None, *span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
args.push(arg);
|
||||
} else {
|
||||
@ -295,6 +304,7 @@ fn parse_long_flag(
|
||||
spans: &[Span],
|
||||
spans_idx: &mut usize,
|
||||
sig: &Signature,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (
|
||||
Option<Spanned<String>>,
|
||||
Option<Expression>,
|
||||
@ -317,7 +327,8 @@ fn parse_long_flag(
|
||||
let mut span = arg_span;
|
||||
span.start += long_name_len + 3; //offset by long flag and '='
|
||||
|
||||
let (arg, err) = parse_value(working_set, span, arg_shape);
|
||||
let (arg, err) =
|
||||
parse_value(working_set, span, arg_shape, expand_aliases_denylist);
|
||||
|
||||
(
|
||||
Some(Spanned {
|
||||
@ -331,7 +342,8 @@ fn parse_long_flag(
|
||||
err,
|
||||
)
|
||||
} else if let Some(arg) = spans.get(*spans_idx + 1) {
|
||||
let (arg, err) = parse_value(working_set, *arg, arg_shape);
|
||||
let (arg, err) =
|
||||
parse_value(working_set, *arg, arg_shape, expand_aliases_denylist);
|
||||
|
||||
*spans_idx += 1;
|
||||
(
|
||||
@ -554,6 +566,7 @@ pub fn parse_multispan_value(
|
||||
spans: &[Span],
|
||||
spans_idx: &mut usize,
|
||||
shape: &SyntaxShape,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let mut error = None;
|
||||
|
||||
@ -568,7 +581,8 @@ pub fn parse_multispan_value(
|
||||
}
|
||||
SyntaxShape::RowCondition => {
|
||||
trace!("parsing: row condition");
|
||||
let (arg, err) = parse_row_condition(working_set, &spans[*spans_idx..]);
|
||||
let (arg, err) =
|
||||
parse_row_condition(working_set, &spans[*spans_idx..], expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
*spans_idx = spans.len() - 1;
|
||||
|
||||
@ -577,7 +591,12 @@ pub fn parse_multispan_value(
|
||||
SyntaxShape::MathExpression => {
|
||||
trace!("parsing: math expression");
|
||||
|
||||
let (arg, err) = parse_math_expression(working_set, &spans[*spans_idx..], None);
|
||||
let (arg, err) = parse_math_expression(
|
||||
working_set,
|
||||
&spans[*spans_idx..],
|
||||
None,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
*spans_idx = spans.len() - 1;
|
||||
|
||||
@ -586,7 +605,8 @@ pub fn parse_multispan_value(
|
||||
SyntaxShape::Expression => {
|
||||
trace!("parsing: expression");
|
||||
|
||||
let (arg, err) = parse_expression(working_set, &spans[*spans_idx..], true);
|
||||
let (arg, err) =
|
||||
parse_expression(working_set, &spans[*spans_idx..], expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
*spans_idx = spans.len() - 1;
|
||||
|
||||
@ -595,7 +615,8 @@ pub fn parse_multispan_value(
|
||||
SyntaxShape::ImportPattern => {
|
||||
trace!("parsing: import pattern");
|
||||
|
||||
let (arg, err) = parse_import_pattern(working_set, &spans[*spans_idx..]);
|
||||
let (arg, err) =
|
||||
parse_import_pattern(working_set, &spans[*spans_idx..], expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
*spans_idx = spans.len() - 1;
|
||||
|
||||
@ -649,7 +670,8 @@ pub fn parse_multispan_value(
|
||||
);
|
||||
}
|
||||
let keyword_span = spans[*spans_idx - 1];
|
||||
let (expr, err) = parse_multispan_value(working_set, spans, spans_idx, arg);
|
||||
let (expr, err) =
|
||||
parse_multispan_value(working_set, spans, spans_idx, arg, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
let ty = expr.ty.clone();
|
||||
|
||||
@ -667,7 +689,7 @@ pub fn parse_multispan_value(
|
||||
// All other cases are single-span values
|
||||
let arg_span = spans[*spans_idx];
|
||||
|
||||
let (arg, err) = parse_value(working_set, arg_span, shape);
|
||||
let (arg, err) = parse_value(working_set, arg_span, shape, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
(arg, error)
|
||||
@ -680,6 +702,7 @@ pub fn parse_internal_call(
|
||||
command_span: Span,
|
||||
spans: &[Span],
|
||||
decl_id: usize,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Box<Call>, Option<ParseError>) {
|
||||
trace!("parsing: internal call (decl id: {})", decl_id);
|
||||
|
||||
@ -706,7 +729,13 @@ pub fn parse_internal_call(
|
||||
let arg_span = spans[spans_idx];
|
||||
|
||||
// Check if we're on a long flag, if so, parse
|
||||
let (long_name, arg, err) = parse_long_flag(working_set, spans, &mut spans_idx, &signature);
|
||||
let (long_name, arg, err) = parse_long_flag(
|
||||
working_set,
|
||||
spans,
|
||||
&mut spans_idx,
|
||||
&signature,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
if let Some(long_name) = long_name {
|
||||
// We found a long flag, like --bar
|
||||
error = error.or(err);
|
||||
@ -729,7 +758,8 @@ pub fn parse_internal_call(
|
||||
for flag in short_flags {
|
||||
if let Some(arg_shape) = flag.arg {
|
||||
if let Some(arg) = spans.get(spans_idx + 1) {
|
||||
let (arg, err) = parse_value(working_set, *arg, &arg_shape);
|
||||
let (arg, err) =
|
||||
parse_value(working_set, *arg, &arg_shape, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
call.named.push((
|
||||
@ -793,6 +823,7 @@ pub fn parse_internal_call(
|
||||
&spans[..end],
|
||||
&mut spans_idx,
|
||||
&positional.shape,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
@ -839,8 +870,8 @@ pub fn parse_internal_call(
|
||||
pub fn parse_call(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases: bool,
|
||||
head: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
trace!("parsing: call");
|
||||
|
||||
@ -883,9 +914,9 @@ pub fn parse_call(
|
||||
name.extend(name_part);
|
||||
}
|
||||
|
||||
if expand_aliases {
|
||||
// If the word is an alias, expand it and re-parse the expression
|
||||
if let Some(alias_id) = working_set.find_alias(&name) {
|
||||
// If the word is an alias, expand it and re-parse the expression
|
||||
if let Some(alias_id) = working_set.find_alias(&name) {
|
||||
if !expand_aliases_denylist.contains(&alias_id) {
|
||||
trace!("expanding alias");
|
||||
|
||||
let expansion = working_set.get_alias(alias_id);
|
||||
@ -901,17 +932,15 @@ pub fn parse_call(
|
||||
new_spans.extend(&spans[(pos + 1)..]);
|
||||
}
|
||||
|
||||
let alias_id = working_set.hide_alias(&name);
|
||||
let mut expand_aliases_denylist = expand_aliases_denylist.to_vec();
|
||||
expand_aliases_denylist.push(alias_id);
|
||||
|
||||
let lite_command = LiteCommand {
|
||||
comments: vec![],
|
||||
parts: new_spans.clone(),
|
||||
};
|
||||
let (mut result, err) = parse_builtin_commands(working_set, &lite_command);
|
||||
if let Some(frame) = working_set.delta.scope.last_mut() {
|
||||
if let Some(alias_id) = alias_id {
|
||||
frame.aliases.insert(name.clone(), alias_id);
|
||||
}
|
||||
}
|
||||
let (mut result, err) =
|
||||
parse_builtin_commands(working_set, &lite_command, &expand_aliases_denylist);
|
||||
|
||||
let mut result = result.expressions.remove(0);
|
||||
|
||||
@ -976,6 +1005,7 @@ pub fn parse_call(
|
||||
span(&spans[cmd_start..pos]),
|
||||
&spans[pos..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
(
|
||||
Expression {
|
||||
@ -992,7 +1022,8 @@ pub fn parse_call(
|
||||
trace!("parsing: range {:?} ", bytes);
|
||||
if let (Some(b'.'), Some(b'.')) = (bytes.get(0), bytes.get(1)) {
|
||||
trace!("-- found leading range indicator");
|
||||
let (range_expr, range_err) = parse_range(working_set, spans[0]);
|
||||
let (range_expr, range_err) =
|
||||
parse_range(working_set, spans[0], expand_aliases_denylist);
|
||||
if range_err.is_none() {
|
||||
trace!("-- successfully parsed range");
|
||||
return (range_expr, range_err);
|
||||
@ -1001,7 +1032,7 @@ pub fn parse_call(
|
||||
trace!("parsing: external call");
|
||||
|
||||
// Otherwise, try external command
|
||||
parse_external_call(working_set, spans)
|
||||
parse_external_call(working_set, spans, expand_aliases_denylist)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1201,6 +1232,7 @@ pub fn parse_number(token: &[u8], span: Span) -> (Expression, Option<ParseError>
|
||||
pub fn parse_range(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
trace!("parsing: range");
|
||||
|
||||
@ -1279,7 +1311,12 @@ pub fn parse_range(
|
||||
None
|
||||
} else {
|
||||
let from_span = Span::new(span.start, span.start + dotdot_pos[0]);
|
||||
match parse_value(working_set, from_span, &SyntaxShape::Number) {
|
||||
match parse_value(
|
||||
working_set,
|
||||
from_span,
|
||||
&SyntaxShape::Number,
|
||||
expand_aliases_denylist,
|
||||
) {
|
||||
(expression, None) => Some(Box::new(expression)),
|
||||
_ => {
|
||||
return (
|
||||
@ -1294,7 +1331,12 @@ pub fn parse_range(
|
||||
None
|
||||
} else {
|
||||
let to_span = Span::new(range_op_span.end, span.end);
|
||||
match parse_value(working_set, to_span, &SyntaxShape::Number) {
|
||||
match parse_value(
|
||||
working_set,
|
||||
to_span,
|
||||
&SyntaxShape::Number,
|
||||
expand_aliases_denylist,
|
||||
) {
|
||||
(expression, None) => Some(Box::new(expression)),
|
||||
_ => {
|
||||
return (
|
||||
@ -1321,7 +1363,12 @@ pub fn parse_range(
|
||||
let next_op_span = Span::new(span.start + pos, span.start + pos + "..".len());
|
||||
let next_span = Span::new(next_op_span.end, range_op_span.start);
|
||||
|
||||
match parse_value(working_set, next_span, &SyntaxShape::Number) {
|
||||
match parse_value(
|
||||
working_set,
|
||||
next_span,
|
||||
&SyntaxShape::Number,
|
||||
expand_aliases_denylist,
|
||||
) {
|
||||
(expression, None) => (Some(Box::new(expression)), next_op_span),
|
||||
_ => {
|
||||
return (
|
||||
@ -1354,22 +1401,24 @@ pub fn parse_range(
|
||||
pub(crate) fn parse_dollar_expr(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
trace!("parsing: dollar expression");
|
||||
let contents = working_set.get_span_contents(span);
|
||||
|
||||
if contents.starts_with(b"$\"") || contents.starts_with(b"$'") {
|
||||
parse_string_interpolation(working_set, span)
|
||||
} else if let (expr, None) = parse_range(working_set, span) {
|
||||
parse_string_interpolation(working_set, span, expand_aliases_denylist)
|
||||
} else if let (expr, None) = parse_range(working_set, span, expand_aliases_denylist) {
|
||||
(expr, None)
|
||||
} else {
|
||||
parse_full_cell_path(working_set, None, span)
|
||||
parse_full_cell_path(working_set, None, span, expand_aliases_denylist)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_string_interpolation(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
enum InterpolationMode {
|
||||
@ -1469,7 +1518,8 @@ pub fn parse_string_interpolation(
|
||||
end: b + 1,
|
||||
};
|
||||
|
||||
let (expr, err) = parse_full_cell_path(working_set, None, span);
|
||||
let (expr, err) =
|
||||
parse_full_cell_path(working_set, None, span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
output.push(expr);
|
||||
}
|
||||
@ -1515,7 +1565,8 @@ pub fn parse_string_interpolation(
|
||||
end,
|
||||
};
|
||||
|
||||
let (expr, err) = parse_full_cell_path(working_set, None, span);
|
||||
let (expr, err) =
|
||||
parse_full_cell_path(working_set, None, span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
output.push(expr);
|
||||
}
|
||||
@ -1692,6 +1743,7 @@ pub fn parse_full_cell_path(
|
||||
working_set: &mut StateWorkingSet,
|
||||
implicit_head: Option<VarId>,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let full_cell_span = span;
|
||||
let source = working_set.get_span_contents(span);
|
||||
@ -1730,7 +1782,7 @@ pub fn parse_full_cell_path(
|
||||
let (output, err) = lite_parse(&output);
|
||||
error = error.or(err);
|
||||
|
||||
let (output, err) = parse_block(working_set, &output, true);
|
||||
let (output, err) = parse_block(working_set, &output, true, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
let block_id = working_set.add_block(output);
|
||||
@ -1748,7 +1800,8 @@ pub fn parse_full_cell_path(
|
||||
} else if bytes.starts_with(b"[") {
|
||||
trace!("parsing: table head of full cell path");
|
||||
|
||||
let (output, err) = parse_table_expression(working_set, head.span);
|
||||
let (output, err) =
|
||||
parse_table_expression(working_set, head.span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
tokens.next();
|
||||
@ -1756,7 +1809,7 @@ pub fn parse_full_cell_path(
|
||||
(output, true)
|
||||
} else if bytes.starts_with(b"{") {
|
||||
trace!("parsing: record head of full cell path");
|
||||
let (output, err) = parse_record(working_set, head.span);
|
||||
let (output, err) = parse_record(working_set, head.span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
tokens.next();
|
||||
@ -2519,6 +2572,7 @@ pub fn parse_type(_working_set: &StateWorkingSet, bytes: &[u8]) -> Type {
|
||||
pub fn parse_import_pattern(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let mut error = None;
|
||||
|
||||
@ -2553,8 +2607,12 @@ pub fn parse_import_pattern(
|
||||
None,
|
||||
)
|
||||
} else if tail.starts_with(b"[") {
|
||||
let (result, err) =
|
||||
parse_list_expression(working_set, *tail_span, &SyntaxShape::String);
|
||||
let (result, err) = parse_list_expression(
|
||||
working_set,
|
||||
*tail_span,
|
||||
&SyntaxShape::String,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
let mut output = vec![];
|
||||
@ -2725,6 +2783,7 @@ pub fn expand_to_cell_path(
|
||||
working_set: &mut StateWorkingSet,
|
||||
expression: &mut Expression,
|
||||
var_id: VarId,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) {
|
||||
if let Expression {
|
||||
expr: Expr::String(_),
|
||||
@ -2733,7 +2792,8 @@ pub fn expand_to_cell_path(
|
||||
} = expression
|
||||
{
|
||||
// Re-parse the string as if it were a cell-path
|
||||
let (new_expression, _err) = parse_full_cell_path(working_set, Some(var_id), *span);
|
||||
let (new_expression, _err) =
|
||||
parse_full_cell_path(working_set, Some(var_id), *span, expand_aliases_denylist);
|
||||
|
||||
*expression = new_expression;
|
||||
}
|
||||
@ -2742,9 +2802,11 @@ pub fn expand_to_cell_path(
|
||||
pub fn parse_row_condition(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let var_id = working_set.add_variable(b"$it".to_vec(), span(spans), Type::Unknown);
|
||||
let (expression, err) = parse_math_expression(working_set, spans, Some(var_id));
|
||||
let (expression, err) =
|
||||
parse_math_expression(working_set, spans, Some(var_id), expand_aliases_denylist);
|
||||
let span = span(spans);
|
||||
|
||||
let block_id = match expression.expr {
|
||||
@ -2783,6 +2845,7 @@ pub fn parse_row_condition(
|
||||
pub fn parse_signature(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let bytes = working_set.get_span_contents(span);
|
||||
|
||||
@ -2810,7 +2873,8 @@ pub fn parse_signature(
|
||||
error = error.or_else(|| Some(ParseError::Unclosed("]".into(), Span { start: end, end })));
|
||||
}
|
||||
|
||||
let (sig, err) = parse_signature_helper(working_set, Span { start, end });
|
||||
let (sig, err) =
|
||||
parse_signature_helper(working_set, Span { start, end }, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
(
|
||||
@ -2827,6 +2891,7 @@ pub fn parse_signature(
|
||||
pub fn parse_signature_helper(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Box<Signature>, Option<ParseError>) {
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
enum ParseMode {
|
||||
@ -3105,8 +3170,12 @@ pub fn parse_signature_helper(
|
||||
}
|
||||
ParseMode::DefaultValueMode => {
|
||||
if let Some(last) = args.last_mut() {
|
||||
let (expression, err) =
|
||||
parse_value(working_set, span, &SyntaxShape::Any);
|
||||
let (expression, err) = parse_value(
|
||||
working_set,
|
||||
span,
|
||||
&SyntaxShape::Any,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
//TODO check if we're replacing a custom parameter already
|
||||
@ -3279,6 +3348,7 @@ pub fn parse_list_expression(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
element_shape: &SyntaxShape,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let bytes = working_set.get_span_contents(span);
|
||||
|
||||
@ -3314,8 +3384,13 @@ pub fn parse_list_expression(
|
||||
let mut spans_idx = 0;
|
||||
|
||||
while spans_idx < arg.parts.len() {
|
||||
let (arg, err) =
|
||||
parse_multispan_value(working_set, &arg.parts, &mut spans_idx, element_shape);
|
||||
let (arg, err) = parse_multispan_value(
|
||||
working_set,
|
||||
&arg.parts,
|
||||
&mut spans_idx,
|
||||
element_shape,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
if let Some(ref ctype) = contained_type {
|
||||
@ -3351,6 +3426,7 @@ pub fn parse_list_expression(
|
||||
pub fn parse_table_expression(
|
||||
working_set: &mut StateWorkingSet,
|
||||
original_span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let bytes = working_set.get_span_contents(original_span);
|
||||
let mut error = None;
|
||||
@ -3389,7 +3465,12 @@ pub fn parse_table_expression(
|
||||
),
|
||||
1 => {
|
||||
// List
|
||||
parse_list_expression(working_set, original_span, &SyntaxShape::Any)
|
||||
parse_list_expression(
|
||||
working_set,
|
||||
original_span,
|
||||
&SyntaxShape::Any,
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
let mut table_headers = vec![];
|
||||
@ -3398,6 +3479,7 @@ pub fn parse_table_expression(
|
||||
working_set,
|
||||
output.block[0].commands[0].parts[0],
|
||||
&SyntaxShape::List(Box::new(SyntaxShape::Any)),
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
@ -3415,6 +3497,7 @@ pub fn parse_table_expression(
|
||||
working_set,
|
||||
*part,
|
||||
&SyntaxShape::List(Box::new(SyntaxShape::Any)),
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
if let Expression {
|
||||
@ -3460,6 +3543,7 @@ pub fn parse_block_expression(
|
||||
working_set: &mut StateWorkingSet,
|
||||
shape: &SyntaxShape,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
trace!("parsing: block expression");
|
||||
|
||||
@ -3526,7 +3610,8 @@ pub fn parse_block_expression(
|
||||
start: start_point,
|
||||
end: end_point,
|
||||
};
|
||||
let (signature, err) = parse_signature_helper(working_set, signature_span);
|
||||
let (signature, err) =
|
||||
parse_signature_helper(working_set, signature_span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
(Some((signature, signature_span)), amt_to_skip)
|
||||
@ -3584,7 +3669,7 @@ pub fn parse_block_expression(
|
||||
}
|
||||
}
|
||||
|
||||
let (mut output, err) = parse_block(working_set, &output, false);
|
||||
let (mut output, err) = parse_block(working_set, &output, false, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
if let Some(signature) = signature {
|
||||
@ -3626,6 +3711,7 @@ pub fn parse_value(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
shape: &SyntaxShape,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let bytes = working_set.get_span_contents(span);
|
||||
|
||||
@ -3699,24 +3785,26 @@ pub fn parse_value(
|
||||
}
|
||||
|
||||
match bytes[0] {
|
||||
b'$' => return parse_dollar_expr(working_set, span),
|
||||
b'$' => return parse_dollar_expr(working_set, span, expand_aliases_denylist),
|
||||
b'(' => {
|
||||
if let (expr, None) = parse_range(working_set, span) {
|
||||
if let (expr, None) = parse_range(working_set, span, expand_aliases_denylist) {
|
||||
return (expr, None);
|
||||
} else {
|
||||
return parse_full_cell_path(working_set, None, span);
|
||||
return parse_full_cell_path(working_set, None, span, expand_aliases_denylist);
|
||||
}
|
||||
}
|
||||
b'{' => {
|
||||
if !matches!(shape, SyntaxShape::Block(..)) {
|
||||
if let (expr, None) = parse_full_cell_path(working_set, None, span) {
|
||||
if let (expr, None) =
|
||||
parse_full_cell_path(working_set, None, span, expand_aliases_denylist)
|
||||
{
|
||||
return (expr, None);
|
||||
}
|
||||
}
|
||||
if matches!(shape, SyntaxShape::Block(_)) || matches!(shape, SyntaxShape::Any) {
|
||||
return parse_block_expression(working_set, shape, span);
|
||||
return parse_block_expression(working_set, shape, span, expand_aliases_denylist);
|
||||
} else if matches!(shape, SyntaxShape::Record) {
|
||||
return parse_record(working_set, span);
|
||||
return parse_record(working_set, span, expand_aliases_denylist);
|
||||
} else {
|
||||
return (
|
||||
Expression::garbage(span),
|
||||
@ -3741,7 +3829,8 @@ pub fn parse_value(
|
||||
|
||||
match shape {
|
||||
SyntaxShape::Custom(shape, custom_completion) => {
|
||||
let (mut expression, err) = parse_value(working_set, span, shape);
|
||||
let (mut expression, err) =
|
||||
parse_value(working_set, span, shape, expand_aliases_denylist);
|
||||
expression.custom_completion = Some(*custom_completion);
|
||||
(expression, err)
|
||||
}
|
||||
@ -3750,14 +3839,14 @@ pub fn parse_value(
|
||||
SyntaxShape::Duration => parse_duration(working_set, span),
|
||||
SyntaxShape::DateTime => parse_datetime(working_set, span),
|
||||
SyntaxShape::Filesize => parse_filesize(working_set, span),
|
||||
SyntaxShape::Range => parse_range(working_set, span),
|
||||
SyntaxShape::Range => parse_range(working_set, span, expand_aliases_denylist),
|
||||
SyntaxShape::Filepath => parse_filepath(working_set, span),
|
||||
SyntaxShape::GlobPattern => parse_glob_pattern(working_set, span),
|
||||
SyntaxShape::String => parse_string(working_set, span),
|
||||
SyntaxShape::Binary => parse_binary(working_set, span),
|
||||
SyntaxShape::Signature => {
|
||||
if bytes.starts_with(b"[") {
|
||||
parse_signature(working_set, span)
|
||||
parse_signature(working_set, span, expand_aliases_denylist)
|
||||
} else {
|
||||
(
|
||||
Expression::garbage(span),
|
||||
@ -3767,7 +3856,7 @@ pub fn parse_value(
|
||||
}
|
||||
SyntaxShape::List(elem) => {
|
||||
if bytes.starts_with(b"[") {
|
||||
parse_list_expression(working_set, span, elem)
|
||||
parse_list_expression(working_set, span, elem, expand_aliases_denylist)
|
||||
} else {
|
||||
(
|
||||
Expression::garbage(span),
|
||||
@ -3777,7 +3866,7 @@ pub fn parse_value(
|
||||
}
|
||||
SyntaxShape::Table => {
|
||||
if bytes.starts_with(b"[") {
|
||||
parse_table_expression(working_set, span)
|
||||
parse_table_expression(working_set, span, expand_aliases_denylist)
|
||||
} else {
|
||||
(
|
||||
Expression::garbage(span),
|
||||
@ -3829,7 +3918,7 @@ pub fn parse_value(
|
||||
SyntaxShape::Any => {
|
||||
if bytes.starts_with(b"[") {
|
||||
//parse_value(working_set, span, &SyntaxShape::Table)
|
||||
parse_full_cell_path(working_set, None, span)
|
||||
parse_full_cell_path(working_set, None, span, expand_aliases_denylist)
|
||||
} else {
|
||||
let shapes = [
|
||||
SyntaxShape::Binary,
|
||||
@ -3844,7 +3933,9 @@ pub fn parse_value(
|
||||
SyntaxShape::String,
|
||||
];
|
||||
for shape in shapes.iter() {
|
||||
if let (s, None) = parse_value(working_set, span, shape) {
|
||||
if let (s, None) =
|
||||
parse_value(working_set, span, shape, expand_aliases_denylist)
|
||||
{
|
||||
return (s, None);
|
||||
}
|
||||
}
|
||||
@ -3906,6 +3997,7 @@ pub fn parse_math_expression(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
lhs_row_var_id: Option<VarId>,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
// As the expr_stack grows, we increase the required precedence to grow larger
|
||||
// If, at any time, the operator we're looking at is the same or lower precedence
|
||||
@ -3923,7 +4015,12 @@ pub fn parse_math_expression(
|
||||
let mut last_prec = 1000000;
|
||||
|
||||
let mut error = None;
|
||||
let (lhs, err) = parse_value(working_set, spans[0], &SyntaxShape::Any);
|
||||
let (lhs, err) = parse_value(
|
||||
working_set,
|
||||
spans[0],
|
||||
&SyntaxShape::Any,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
idx += 1;
|
||||
|
||||
@ -3947,7 +4044,12 @@ pub fn parse_math_expression(
|
||||
break;
|
||||
}
|
||||
|
||||
let (rhs, err) = parse_value(working_set, spans[idx], &SyntaxShape::Any);
|
||||
let (rhs, err) = parse_value(
|
||||
working_set,
|
||||
spans[idx],
|
||||
&SyntaxShape::Any,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
if op_prec <= last_prec && expr_stack.len() > 1 {
|
||||
@ -3965,7 +4067,7 @@ pub fn parse_math_expression(
|
||||
.expect("internal error: expression stack empty");
|
||||
|
||||
if let Some(row_var_id) = lhs_row_var_id {
|
||||
expand_to_cell_path(working_set, &mut lhs, row_var_id);
|
||||
expand_to_cell_path(working_set, &mut lhs, row_var_id, expand_aliases_denylist);
|
||||
}
|
||||
|
||||
let (result_ty, err) = math_result_type(working_set, &mut lhs, &mut op, &mut rhs);
|
||||
@ -3999,7 +4101,7 @@ pub fn parse_math_expression(
|
||||
.expect("internal error: expression stack empty");
|
||||
|
||||
if let Some(row_var_id) = lhs_row_var_id {
|
||||
expand_to_cell_path(working_set, &mut lhs, row_var_id);
|
||||
expand_to_cell_path(working_set, &mut lhs, row_var_id, expand_aliases_denylist);
|
||||
}
|
||||
|
||||
let (result_ty, err) = math_result_type(working_set, &mut lhs, &mut op, &mut rhs);
|
||||
@ -4024,7 +4126,7 @@ pub fn parse_math_expression(
|
||||
pub fn parse_expression(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases: bool,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let mut pos = 0;
|
||||
let mut shorthand = vec![];
|
||||
@ -4092,56 +4194,110 @@ pub fn parse_expression(
|
||||
.iter()
|
||||
.any(|x| x == bytes)
|
||||
{
|
||||
parse_math_expression(working_set, &spans[pos..], None)
|
||||
parse_math_expression(working_set, &spans[pos..], None, expand_aliases_denylist)
|
||||
} else {
|
||||
// For now, check for special parses of certain keywords
|
||||
match bytes {
|
||||
b"def" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline("def".into(), spans[0])),
|
||||
),
|
||||
b"extern" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline(
|
||||
"extern".into(),
|
||||
spans[0],
|
||||
)),
|
||||
),
|
||||
b"let" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline("let".into(), spans[0])),
|
||||
),
|
||||
b"alias" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline(
|
||||
"alias".into(),
|
||||
spans[0],
|
||||
)),
|
||||
),
|
||||
b"module" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline(
|
||||
"module".into(),
|
||||
spans[0],
|
||||
)),
|
||||
),
|
||||
b"use" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline("use".into(), spans[0])),
|
||||
),
|
||||
b"source" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline(
|
||||
"source".into(),
|
||||
spans[0],
|
||||
)),
|
||||
),
|
||||
b"export" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::UnexpectedKeyword("export".into(), spans[0])),
|
||||
),
|
||||
b"hide" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline(
|
||||
"hide".into(),
|
||||
spans[0],
|
||||
@ -4149,15 +4305,26 @@ pub fn parse_expression(
|
||||
),
|
||||
#[cfg(feature = "plugin")]
|
||||
b"register" => (
|
||||
parse_call(working_set, &spans[pos..], expand_aliases, spans[0]).0,
|
||||
parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline(
|
||||
"plugin".into(),
|
||||
spans[0],
|
||||
)),
|
||||
),
|
||||
|
||||
b"for" => parse_for(working_set, spans),
|
||||
_ => parse_call(working_set, &spans[pos..], expand_aliases, spans[0]),
|
||||
b"for" => parse_for(working_set, spans, expand_aliases_denylist),
|
||||
_ => parse_call(
|
||||
working_set,
|
||||
&spans[pos..],
|
||||
spans[0],
|
||||
expand_aliases_denylist,
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
@ -4240,21 +4407,22 @@ pub fn parse_variable(
|
||||
pub fn parse_builtin_commands(
|
||||
working_set: &mut StateWorkingSet,
|
||||
lite_command: &LiteCommand,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
let name = working_set.get_span_contents(lite_command.parts[0]);
|
||||
|
||||
match name {
|
||||
b"def" | b"def-env" => parse_def(working_set, lite_command),
|
||||
b"extern" => parse_extern(working_set, lite_command),
|
||||
b"let" => parse_let(working_set, &lite_command.parts),
|
||||
b"def" | b"def-env" => parse_def(working_set, lite_command, expand_aliases_denylist),
|
||||
b"extern" => parse_extern(working_set, lite_command, expand_aliases_denylist),
|
||||
b"let" => parse_let(working_set, &lite_command.parts, expand_aliases_denylist),
|
||||
b"for" => {
|
||||
let (expr, err) = parse_for(working_set, &lite_command.parts);
|
||||
let (expr, err) = parse_for(working_set, &lite_command.parts, expand_aliases_denylist);
|
||||
(Pipeline::from_vec(vec![expr]), err)
|
||||
}
|
||||
b"alias" => parse_alias(working_set, &lite_command.parts),
|
||||
b"module" => parse_module(working_set, &lite_command.parts),
|
||||
b"use" => parse_use(working_set, &lite_command.parts),
|
||||
b"source" => parse_source(working_set, &lite_command.parts),
|
||||
b"alias" => parse_alias(working_set, &lite_command.parts, expand_aliases_denylist),
|
||||
b"module" => parse_module(working_set, &lite_command.parts, expand_aliases_denylist),
|
||||
b"use" => parse_use(working_set, &lite_command.parts, expand_aliases_denylist),
|
||||
b"source" => parse_source(working_set, &lite_command.parts, expand_aliases_denylist),
|
||||
b"export" => (
|
||||
garbage_pipeline(&lite_command.parts),
|
||||
Some(ParseError::UnexpectedKeyword(
|
||||
@ -4262,11 +4430,12 @@ pub fn parse_builtin_commands(
|
||||
lite_command.parts[0],
|
||||
)),
|
||||
),
|
||||
b"hide" => parse_hide(working_set, &lite_command.parts),
|
||||
b"hide" => parse_hide(working_set, &lite_command.parts, expand_aliases_denylist),
|
||||
#[cfg(feature = "plugin")]
|
||||
b"register" => parse_register(working_set, &lite_command.parts),
|
||||
b"register" => parse_register(working_set, &lite_command.parts, expand_aliases_denylist),
|
||||
_ => {
|
||||
let (expr, err) = parse_expression(working_set, &lite_command.parts, true);
|
||||
let (expr, err) =
|
||||
parse_expression(working_set, &lite_command.parts, expand_aliases_denylist);
|
||||
(Pipeline::from_vec(vec![expr]), err)
|
||||
}
|
||||
}
|
||||
@ -4275,6 +4444,7 @@ pub fn parse_builtin_commands(
|
||||
pub fn parse_record(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let bytes = working_set.get_span_contents(span);
|
||||
|
||||
@ -4312,7 +4482,12 @@ pub fn parse_record(
|
||||
let mut idx = 0;
|
||||
|
||||
while idx < tokens.len() {
|
||||
let (field, err) = parse_value(working_set, tokens[idx].span, &SyntaxShape::Any);
|
||||
let (field, err) = parse_value(
|
||||
working_set,
|
||||
tokens[idx].span,
|
||||
&SyntaxShape::Any,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
idx += 1;
|
||||
@ -4331,7 +4506,12 @@ pub fn parse_record(
|
||||
Some(ParseError::Expected("record".into(), span)),
|
||||
);
|
||||
}
|
||||
let (value, err) = parse_value(working_set, tokens[idx].span, &SyntaxShape::Any);
|
||||
let (value, err) = parse_value(
|
||||
working_set,
|
||||
tokens[idx].span,
|
||||
&SyntaxShape::Any,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
error = error.or(err);
|
||||
idx += 1;
|
||||
|
||||
@ -4353,6 +4533,7 @@ pub fn parse_block(
|
||||
working_set: &mut StateWorkingSet,
|
||||
lite_block: &LiteBlock,
|
||||
scoped: bool,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Block, Option<ParseError>) {
|
||||
trace!("parsing block: {:?}", lite_block);
|
||||
|
||||
@ -4366,7 +4547,11 @@ pub fn parse_block(
|
||||
// that share the same block can see each other
|
||||
for pipeline in &lite_block.block {
|
||||
if pipeline.commands.len() == 1 {
|
||||
if let Some(err) = parse_def_predecl(working_set, &pipeline.commands[0].parts) {
|
||||
if let Some(err) = parse_def_predecl(
|
||||
working_set,
|
||||
&pipeline.commands[0].parts,
|
||||
expand_aliases_denylist,
|
||||
) {
|
||||
error = error.or(Some(err));
|
||||
}
|
||||
}
|
||||
@ -4382,7 +4567,8 @@ pub fn parse_block(
|
||||
.commands
|
||||
.iter()
|
||||
.map(|command| {
|
||||
let (expr, err) = parse_expression(working_set, &command.parts, true);
|
||||
let (expr, err) =
|
||||
parse_expression(working_set, &command.parts, expand_aliases_denylist);
|
||||
|
||||
if error.is_none() {
|
||||
error = err;
|
||||
@ -4402,8 +4588,11 @@ pub fn parse_block(
|
||||
expressions: output,
|
||||
}
|
||||
} else {
|
||||
let (mut pipeline, err) =
|
||||
parse_builtin_commands(working_set, &pipeline.commands[0]);
|
||||
let (mut pipeline, err) = parse_builtin_commands(
|
||||
working_set,
|
||||
&pipeline.commands[0],
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
|
||||
if idx == 0 {
|
||||
if let Some(let_decl_id) = working_set.find_decl(b"let") {
|
||||
@ -4776,6 +4965,7 @@ pub fn parse(
|
||||
fname: Option<&str>,
|
||||
contents: &[u8],
|
||||
scoped: bool,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Block, Option<ParseError>) {
|
||||
trace!("starting top-level parse");
|
||||
|
||||
@ -4796,7 +4986,7 @@ pub fn parse(
|
||||
let (output, err) = lite_parse(&output);
|
||||
error = error.or(err);
|
||||
|
||||
let (mut output, err) = parse_block(working_set, &output, scoped);
|
||||
let (mut output, err) = parse_block(working_set, &output, scoped, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
let mut seen = vec![];
|
||||
|
@ -46,7 +46,7 @@ pub fn parse_int() {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"3", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"3", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -69,7 +69,7 @@ pub fn parse_call() {
|
||||
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||
working_set.add_decl(sig.predeclare());
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"foo", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"foo", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -94,7 +94,7 @@ pub fn parse_call_missing_flag_arg() {
|
||||
let sig = Signature::build("foo").named("jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||
working_set.add_decl(sig.predeclare());
|
||||
|
||||
let (_, err) = parse(&mut working_set, None, b"foo --jazz", true);
|
||||
let (_, err) = parse(&mut working_set, None, b"foo --jazz", true, &[]);
|
||||
assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ pub fn parse_call_missing_short_flag_arg() {
|
||||
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||
working_set.add_decl(sig.predeclare());
|
||||
|
||||
let (_, err) = parse(&mut working_set, None, b"foo -j", true);
|
||||
let (_, err) = parse(&mut working_set, None, b"foo -j", true, &[]);
|
||||
assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ pub fn parse_call_too_many_shortflag_args() {
|
||||
.named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'))
|
||||
.named("--math", SyntaxShape::Int, "math!!", Some('m'));
|
||||
working_set.add_decl(sig.predeclare());
|
||||
let (_, err) = parse(&mut working_set, None, b"foo -mj", true);
|
||||
let (_, err) = parse(&mut working_set, None, b"foo -mj", true, &[]);
|
||||
assert!(matches!(
|
||||
err,
|
||||
Some(ParseError::ShortFlagBatchCantTakeArg(..))
|
||||
@ -133,7 +133,7 @@ pub fn parse_call_unknown_shorthand() {
|
||||
|
||||
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
|
||||
working_set.add_decl(sig.predeclare());
|
||||
let (_, err) = parse(&mut working_set, None, b"foo -mj", true);
|
||||
let (_, err) = parse(&mut working_set, None, b"foo -mj", true, &[]);
|
||||
assert!(matches!(err, Some(ParseError::UnknownFlag(..))));
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ pub fn parse_call_extra_positional() {
|
||||
|
||||
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
|
||||
working_set.add_decl(sig.predeclare());
|
||||
let (_, err) = parse(&mut working_set, None, b"foo -j 100", true);
|
||||
let (_, err) = parse(&mut working_set, None, b"foo -j 100", true, &[]);
|
||||
assert!(matches!(err, Some(ParseError::ExtraPositional(..))));
|
||||
}
|
||||
|
||||
@ -155,7 +155,7 @@ pub fn parse_call_missing_req_positional() {
|
||||
|
||||
let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!");
|
||||
working_set.add_decl(sig.predeclare());
|
||||
let (_, err) = parse(&mut working_set, None, b"foo", true);
|
||||
let (_, err) = parse(&mut working_set, None, b"foo", true, &[]);
|
||||
assert!(matches!(err, Some(ParseError::MissingPositional(..))));
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ pub fn parse_call_missing_req_flag() {
|
||||
|
||||
let sig = Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None);
|
||||
working_set.add_decl(sig.predeclare());
|
||||
let (_, err) = parse(&mut working_set, None, b"foo", true);
|
||||
let (_, err) = parse(&mut working_set, None, b"foo", true, &[]);
|
||||
assert!(matches!(err, Some(ParseError::MissingRequiredFlag(..))));
|
||||
}
|
||||
|
||||
@ -174,7 +174,7 @@ pub fn parse_call_missing_req_flag() {
|
||||
fn test_nothing_comparisson_eq() {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let (block, err) = parse(&mut working_set, None, b"2 == $nothing", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"2 == $nothing", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -194,7 +194,7 @@ fn test_nothing_comparisson_eq() {
|
||||
fn test_nothing_comparisson_neq() {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let (block, err) = parse(&mut working_set, None, b"2 != $nothing", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"2 != $nothing", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -219,7 +219,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"0..10", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"0..10", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -248,7 +248,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"0..<10", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"0..<10", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -277,7 +277,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"10..0", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"10..0", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -306,7 +306,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"(3 - 3)..<(8 + 2)", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"(3 - 3)..<(8 + 2)", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -337,7 +337,7 @@ mod range {
|
||||
|
||||
working_set.add_decl(Box::new(Let));
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"let a = 2; $a..10", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"let a = 2; $a..10", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 2);
|
||||
@ -368,7 +368,13 @@ mod range {
|
||||
|
||||
working_set.add_decl(Box::new(Let));
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"let a = 2; $a..<($a + 10)", true);
|
||||
let (block, err) = parse(
|
||||
&mut working_set,
|
||||
None,
|
||||
b"let a = 2; $a..<($a + 10)",
|
||||
true,
|
||||
&[],
|
||||
);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 2);
|
||||
@ -397,7 +403,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"0..", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"0..", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -426,7 +432,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"..10", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"..10", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -455,7 +461,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"-10..-3", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"-10..-3", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -484,7 +490,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, b"2.0..4.0..10.0", true);
|
||||
let (block, err) = parse(&mut working_set, None, b"2.0..4.0..10.0", true, &[]);
|
||||
|
||||
assert!(err.is_none());
|
||||
assert!(block.len() == 1);
|
||||
@ -513,7 +519,7 @@ mod range {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
let (_, err) = parse(&mut working_set, None, b"(0)..\"a\"", true);
|
||||
let (_, err) = parse(&mut working_set, None, b"(0)..\"a\"", true, &[]);
|
||||
|
||||
assert!(err.is_some());
|
||||
}
|
||||
|
@ -844,10 +844,44 @@ impl<'a> StateWorkingSet<'a> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn use_alias(&mut self, alias_id: &AliasId) {
|
||||
let mut visibility: Visibility = Visibility::new();
|
||||
|
||||
// Since we can mutate scope frames in delta, remove the id directly
|
||||
for scope in self.delta.scope.iter_mut().rev() {
|
||||
visibility.append(&scope.visibility);
|
||||
|
||||
if !visibility.is_alias_id_visible(alias_id) {
|
||||
// Hide alias only if it's not already hidden
|
||||
scope.visibility.use_alias_id(alias_id);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot mutate the permanent state => store the information in the current scope frame
|
||||
let last_scope_frame = self
|
||||
.delta
|
||||
.scope
|
||||
.last_mut()
|
||||
.expect("internal error: missing required scope frame");
|
||||
|
||||
for scope in self.permanent_state.scope.iter().rev() {
|
||||
visibility.append(&scope.visibility);
|
||||
|
||||
if !visibility.is_alias_id_visible(alias_id) {
|
||||
// Hide alias only if it's not already hidden
|
||||
last_scope_frame.visibility.use_alias_id(alias_id);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hide_alias(&mut self, name: &[u8]) -> Option<AliasId> {
|
||||
let mut visibility: Visibility = Visibility::new();
|
||||
|
||||
// // Since we can mutate scope frames in delta, remove the id directly
|
||||
// Since we can mutate scope frames in delta, remove the id directly
|
||||
for scope in self.delta.scope.iter_mut().rev() {
|
||||
visibility.append(&scope.visibility);
|
||||
|
||||
|
@ -279,7 +279,13 @@ fn parse_commandline_args(
|
||||
let mut working_set = StateWorkingSet::new(engine_state);
|
||||
working_set.add_decl(Box::new(Nu));
|
||||
|
||||
let (output, err) = parse(&mut working_set, None, commandline_args.as_bytes(), false);
|
||||
let (output, err) = parse(
|
||||
&mut working_set,
|
||||
None,
|
||||
commandline_args.as_bytes(),
|
||||
false,
|
||||
&[],
|
||||
);
|
||||
if let Some(err) = err {
|
||||
report_error(&working_set, &err);
|
||||
|
||||
|
@ -581,6 +581,17 @@ fn block_params_override() {
|
||||
assert!(actual.err.contains("variable not found"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alias_reuse() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"alias foo = echo bob; foo; foo"#
|
||||
);
|
||||
|
||||
assert!(actual.out.contains("bob"));
|
||||
assert!(actual.err.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_params_override_correct() {
|
||||
let actual = nu!(
|
||||
|
Loading…
Reference in New Issue
Block a user