forked from extern/nushell
Add explicit block params (#3444)
* Add explicit block params * Add explicit block params
This commit is contained in:
parent
0ff08bb63a
commit
e2973d2176
@ -37,7 +37,7 @@ impl<'s> Flatten<'s> {
|
|||||||
)
|
)
|
||||||
.collect(),
|
.collect(),
|
||||||
Expression::Command => vec![LocationType::Command.spanned(e.span)],
|
Expression::Command => vec![LocationType::Command.spanned(e.span)],
|
||||||
Expression::Path(path) => self.expression(&path.head),
|
Expression::FullColumnPath(path) => self.expression(&path.head),
|
||||||
Expression::Variable(_, _) => vec![LocationType::Variable.spanned(e.span)],
|
Expression::Variable(_, _) => vec![LocationType::Variable.spanned(e.span)],
|
||||||
|
|
||||||
Expression::Boolean(_)
|
Expression::Boolean(_)
|
||||||
|
@ -296,7 +296,7 @@ fn get_shape_of_expr(expr: &SpannedExpression) -> Option<SyntaxShape> {
|
|||||||
Expression::List(_) => Some(SyntaxShape::Table),
|
Expression::List(_) => Some(SyntaxShape::Table),
|
||||||
Expression::Boolean(_) => Some(SyntaxShape::String),
|
Expression::Boolean(_) => Some(SyntaxShape::String),
|
||||||
|
|
||||||
Expression::Path(_) => Some(SyntaxShape::ColumnPath),
|
Expression::FullColumnPath(_) => Some(SyntaxShape::ColumnPath),
|
||||||
Expression::FilePath(_) => Some(SyntaxShape::FilePath),
|
Expression::FilePath(_) => Some(SyntaxShape::FilePath),
|
||||||
Expression::Block(_) => Some(SyntaxShape::Block),
|
Expression::Block(_) => Some(SyntaxShape::Block),
|
||||||
Expression::ExternalCommand(_) => Some(SyntaxShape::String),
|
Expression::ExternalCommand(_) => Some(SyntaxShape::String),
|
||||||
@ -539,7 +539,7 @@ impl VarSyntaxShapeDeductor {
|
|||||||
trace!("Inferring vars in block");
|
trace!("Inferring vars in block");
|
||||||
self.infer_shape(&b, scope)?;
|
self.infer_shape(&b, scope)?;
|
||||||
}
|
}
|
||||||
Expression::Path(path) => {
|
Expression::FullColumnPath(path) => {
|
||||||
trace!("Inferring vars in path");
|
trace!("Inferring vars in path");
|
||||||
match &path.head.expr {
|
match &path.head.expr {
|
||||||
//PathMember can't be var yet (?)
|
//PathMember can't be var yet (?)
|
||||||
@ -790,7 +790,7 @@ impl VarSyntaxShapeDeductor {
|
|||||||
| Expression::Binary(_)
|
| Expression::Binary(_)
|
||||||
| Expression::Range(_)
|
| Expression::Range(_)
|
||||||
| Expression::Block(_)
|
| Expression::Block(_)
|
||||||
| Expression::Path(_)
|
| Expression::FullColumnPath(_)
|
||||||
| Expression::FilePath(_)
|
| Expression::FilePath(_)
|
||||||
| Expression::ExternalCommand(_)
|
| Expression::ExternalCommand(_)
|
||||||
| Expression::Command
|
| Expression::Command
|
||||||
|
@ -55,6 +55,15 @@ impl WholeStreamCommand for Each {
|
|||||||
"echo ['bob' 'fred'] | each --numbered { echo $\"{$it.index} is {$it.item}\" }",
|
"echo ['bob' 'fred'] | each --numbered { echo $\"{$it.index} is {$it.item}\" }",
|
||||||
result: Some(vec![Value::from("0 is bob"), Value::from("1 is fred")]),
|
result: Some(vec![Value::from("0 is bob"), Value::from("1 is fred")]),
|
||||||
},
|
},
|
||||||
|
Example {
|
||||||
|
description: "Name the block variable that each uses",
|
||||||
|
example: "[1, 2, 3] | each {|x| $x + 100}",
|
||||||
|
result: Some(vec![
|
||||||
|
UntaggedValue::int(101).into(),
|
||||||
|
UntaggedValue::int(102).into(),
|
||||||
|
UntaggedValue::int(103).into(),
|
||||||
|
]),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ pub fn evaluate_baseline_expr(
|
|||||||
.into_value(&tag),
|
.into_value(&tag),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Expression::Path(path) => {
|
Expression::FullColumnPath(path) => {
|
||||||
let value = evaluate_baseline_expr(&path.head, ctx)?;
|
let value = evaluate_baseline_expr(&path.head, ctx)?;
|
||||||
let mut item = value;
|
let mut item = value;
|
||||||
|
|
||||||
|
@ -13,12 +13,18 @@ use nu_protocol::{NamedType, PositionalType, Signature, SyntaxShape, UnspannedPa
|
|||||||
use nu_source::{HasSpan, Span, Spanned, SpannedItem};
|
use nu_source::{HasSpan, Span, Spanned, SpannedItem};
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
use crate::lex::tokens::{LiteBlock, LiteCommand, LitePipeline};
|
|
||||||
use crate::path::expand_path;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lex::lexer::{lex, parse_block},
|
lex::lexer::{lex, parse_block},
|
||||||
ParserScope,
|
ParserScope,
|
||||||
};
|
};
|
||||||
|
use crate::{
|
||||||
|
lex::{
|
||||||
|
lexer::Token,
|
||||||
|
tokens::{LiteBlock, LiteCommand, LitePipeline, TokenContents},
|
||||||
|
},
|
||||||
|
parse::def::lex_split_baseline_tokens_on,
|
||||||
|
};
|
||||||
|
use crate::{parse::def::parse_parameter, path::expand_path};
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
def::{parse_definition, parse_definition_prototype},
|
def::{parse_definition, parse_definition_prototype},
|
||||||
@ -919,20 +925,78 @@ fn parse_arg(
|
|||||||
let string: String = chars.collect();
|
let string: String = chars.collect();
|
||||||
|
|
||||||
// We haven't done much with the inner string, so let's go ahead and work with it
|
// We haven't done much with the inner string, so let's go ahead and work with it
|
||||||
let (tokens, err) = lex(&string, lite_arg.span.start() + 1);
|
let (mut tokens, err) = lex(&string, lite_arg.span.start() + 1);
|
||||||
if err.is_some() {
|
if err.is_some() {
|
||||||
return (garbage(lite_arg.span), err);
|
return (garbage(lite_arg.span), err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check to see if we have parameters
|
||||||
|
let params = if matches!(
|
||||||
|
tokens.first(),
|
||||||
|
Some(Token {
|
||||||
|
contents: TokenContents::Pipe,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
// We've found a parameter list
|
||||||
|
let mut param_tokens = vec![];
|
||||||
|
let mut token_iter = tokens.into_iter().skip(1);
|
||||||
|
while let Some(token) = token_iter.next() {
|
||||||
|
if matches!(
|
||||||
|
token,
|
||||||
|
Token {
|
||||||
|
contents: TokenContents::Pipe,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
param_tokens.push(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let split_tokens =
|
||||||
|
lex_split_baseline_tokens_on(param_tokens, &[',', ':', '?']);
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
let mut params = vec![];
|
||||||
|
|
||||||
|
while i < split_tokens.len() {
|
||||||
|
let (parameter, advance_by, error) =
|
||||||
|
parse_parameter(&split_tokens[i..], split_tokens[i].span);
|
||||||
|
|
||||||
|
if error.is_some() {
|
||||||
|
return (garbage(lite_arg.span), error);
|
||||||
|
}
|
||||||
|
i += advance_by;
|
||||||
|
params.push(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens = token_iter.collect();
|
||||||
|
params
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
let (lite_block, err) = parse_block(tokens);
|
let (lite_block, err) = parse_block(tokens);
|
||||||
if err.is_some() {
|
if err.is_some() {
|
||||||
return (garbage(lite_arg.span), err);
|
return (garbage(lite_arg.span), err);
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.enter_scope();
|
scope.enter_scope();
|
||||||
let (classified_block, err) = classify_block(&lite_block, scope);
|
let (mut classified_block, err) = classify_block(&lite_block, scope);
|
||||||
scope.exit_scope();
|
scope.exit_scope();
|
||||||
|
|
||||||
|
if !params.is_empty() && classified_block.params.positional.is_empty() {
|
||||||
|
if let Some(classified_block) = Arc::get_mut(&mut classified_block) {
|
||||||
|
for param in params {
|
||||||
|
classified_block
|
||||||
|
.params
|
||||||
|
.positional
|
||||||
|
.push((param.pos_type, param.desc.unwrap_or_default()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
SpannedExpression::new(Expression::Block(classified_block), lite_arg.span),
|
SpannedExpression::new(Expression::Block(classified_block), lite_arg.span),
|
||||||
err,
|
err,
|
||||||
@ -1600,16 +1664,11 @@ fn parse_call(
|
|||||||
})),
|
})),
|
||||||
error,
|
error,
|
||||||
);
|
);
|
||||||
// } else if lite_cmd.parts[0].item.starts_with('(') {
|
|
||||||
// let (expr, err) = parse_simple_invocation(&lite_cmd.parts[0], scope);
|
|
||||||
// error = error.or(err);
|
|
||||||
// return (Some(ClassifiedCommand::Expr(Box::new(expr))), error);
|
|
||||||
} else if lite_cmd.parts[0].item.starts_with('{') {
|
} else if lite_cmd.parts[0].item.starts_with('{') {
|
||||||
return parse_value_call(lite_cmd, scope);
|
return parse_value_call(lite_cmd, scope);
|
||||||
} else if lite_cmd.parts[0].item.starts_with('$')
|
} else if lite_cmd.parts[0].item.starts_with('$')
|
||||||
|| lite_cmd.parts[0].item.starts_with('\"')
|
|| lite_cmd.parts[0].item.starts_with('\"')
|
||||||
|| lite_cmd.parts[0].item.starts_with('\'')
|
|| lite_cmd.parts[0].item.starts_with('\'')
|
||||||
|| lite_cmd.parts[0].item.starts_with('`')
|
|
||||||
|| lite_cmd.parts[0].item.starts_with('-')
|
|| lite_cmd.parts[0].item.starts_with('-')
|
||||||
|| lite_cmd.parts[0].item.starts_with('0')
|
|| lite_cmd.parts[0].item.starts_with('0')
|
||||||
|| lite_cmd.parts[0].item.starts_with('1')
|
|| lite_cmd.parts[0].item.starts_with('1')
|
||||||
|
@ -16,6 +16,7 @@ use crate::lex::lexer::{lex, parse_block};
|
|||||||
use crate::ParserScope;
|
use crate::ParserScope;
|
||||||
|
|
||||||
use self::signature::parse_signature;
|
use self::signature::parse_signature;
|
||||||
|
pub use self::signature::{lex_split_baseline_tokens_on, parse_parameter};
|
||||||
|
|
||||||
mod data_structs;
|
mod data_structs;
|
||||||
mod primitives;
|
mod primitives;
|
||||||
|
@ -87,7 +87,7 @@ pub fn parse_signature(
|
|||||||
i += advanced_by;
|
i += advanced_by;
|
||||||
rest = rest_;
|
rest = rest_;
|
||||||
} else {
|
} else {
|
||||||
let (parameter, advanced_by, error) = parse_parameter(&tokens[i..], signature_vec);
|
let (parameter, advanced_by, error) = parse_parameter(&tokens[i..], signature_vec.span);
|
||||||
err = err.or(error);
|
err = err.or(error);
|
||||||
i += advanced_by;
|
i += advanced_by;
|
||||||
parameters.push(parameter);
|
parameters.push(parameter);
|
||||||
@ -100,16 +100,13 @@ pub fn parse_signature(
|
|||||||
(signature, err)
|
(signature, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_parameter(
|
pub fn parse_parameter(tokens: &[Token], span: Span) -> (Parameter, usize, Option<ParseError>) {
|
||||||
tokens: &[Token],
|
|
||||||
tokens_as_str: &Spanned<String>,
|
|
||||||
) -> (Parameter, usize, Option<ParseError>) {
|
|
||||||
if tokens.is_empty() {
|
if tokens.is_empty() {
|
||||||
//TODO fix span
|
//TODO fix span
|
||||||
return (
|
return (
|
||||||
Parameter::error(),
|
Parameter::error(),
|
||||||
0,
|
0,
|
||||||
Some(ParseError::unexpected_eof("parameter", tokens_as_str.span)),
|
Some(ParseError::unexpected_eof("parameter", span)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,9 +142,15 @@ fn parse_parameter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pos_type = if optional {
|
let pos_type = if optional {
|
||||||
PositionalType::optional(&name.item, type_)
|
if name.item.starts_with('$') {
|
||||||
} else {
|
PositionalType::optional(&name.item, type_)
|
||||||
|
} else {
|
||||||
|
PositionalType::optional(&format!("${}", name.item), type_)
|
||||||
|
}
|
||||||
|
} else if name.item.starts_with('$') {
|
||||||
PositionalType::mandatory(&name.item, type_)
|
PositionalType::mandatory(&name.item, type_)
|
||||||
|
} else {
|
||||||
|
PositionalType::mandatory(&format!("${}", name.item), type_)
|
||||||
};
|
};
|
||||||
|
|
||||||
let parameter = Parameter::new(pos_type, comment, name.span);
|
let parameter = Parameter::new(pos_type, comment, name.span);
|
||||||
@ -402,7 +405,7 @@ fn lex_split_shortflag_from_longflag(tokens: Vec<Token>) -> Vec<Token> {
|
|||||||
}
|
}
|
||||||
//Currently the lexer does not split baselines on ',' ':' '?'
|
//Currently the lexer does not split baselines on ',' ':' '?'
|
||||||
//The parameter list requires this. Therefore here is a hacky method doing this.
|
//The parameter list requires this. Therefore here is a hacky method doing this.
|
||||||
fn lex_split_baseline_tokens_on(
|
pub fn lex_split_baseline_tokens_on(
|
||||||
tokens: Vec<Token>,
|
tokens: Vec<Token>,
|
||||||
extra_baseline_terminal_tokens: &[char],
|
extra_baseline_terminal_tokens: &[char],
|
||||||
) -> Vec<Token> {
|
) -> Vec<Token> {
|
||||||
|
@ -19,11 +19,11 @@ fn simple_def_with_params() {
|
|||||||
sign.positional,
|
sign.positional,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
PositionalType::Optional("param1".into(), SyntaxShape::Int),
|
PositionalType::Optional("$param1".into(), SyntaxShape::Int),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param2".into(), SyntaxShape::String),
|
PositionalType::Mandatory("$param2".into(), SyntaxShape::String),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -40,11 +40,11 @@ fn simple_def_with_optional_param_without_type() {
|
|||||||
sign.positional,
|
sign.positional,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
PositionalType::Optional("param1".into(), SyntaxShape::Any),
|
PositionalType::Optional("$param1".into(), SyntaxShape::Any),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Optional("param2".into(), SyntaxShape::Any),
|
PositionalType::Optional("$param2".into(), SyntaxShape::Any),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -64,11 +64,11 @@ fn simple_def_with_params_with_comment() {
|
|||||||
sign.positional,
|
sign.positional,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param1".into(), SyntaxShape::FilePath),
|
PositionalType::Mandatory("$param1".into(), SyntaxShape::FilePath),
|
||||||
"My first param".into()
|
"My first param".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param2".into(), SyntaxShape::Number),
|
PositionalType::Mandatory("$param2".into(), SyntaxShape::Number),
|
||||||
"My second param".into()
|
"My second param".into()
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -88,11 +88,11 @@ fn simple_def_with_params_without_type() {
|
|||||||
sign.positional,
|
sign.positional,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param1".into(), SyntaxShape::Any),
|
PositionalType::Mandatory("$param1".into(), SyntaxShape::Any),
|
||||||
"My first param".into()
|
"My first param".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param2".into(), SyntaxShape::Number),
|
PositionalType::Mandatory("$param2".into(), SyntaxShape::Number),
|
||||||
"My second param".into()
|
"My second param".into()
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -116,23 +116,23 @@ fn oddly_but_correct_written_params() {
|
|||||||
sign.positional,
|
sign.positional,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param1".into(), SyntaxShape::Int),
|
PositionalType::Mandatory("$param1".into(), SyntaxShape::Int),
|
||||||
"param1".into()
|
"param1".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param2".into(), SyntaxShape::Number),
|
PositionalType::Mandatory("$param2".into(), SyntaxShape::Number),
|
||||||
"My second param".into()
|
"My second param".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param4".into(), SyntaxShape::Any),
|
PositionalType::Mandatory("$param4".into(), SyntaxShape::Any),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param5".into(), SyntaxShape::FilePath),
|
PositionalType::Mandatory("$param5".into(), SyntaxShape::FilePath),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param6".into(), SyntaxShape::Any),
|
PositionalType::Mandatory("$param6".into(), SyntaxShape::Any),
|
||||||
"param6".into()
|
"param6".into()
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -225,19 +225,19 @@ fn simple_def_with_params_and_flags() {
|
|||||||
sign.positional,
|
sign.positional,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param1".into(), SyntaxShape::Any),
|
PositionalType::Mandatory("$param1".into(), SyntaxShape::Any),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param2".into(), SyntaxShape::Table),
|
PositionalType::Mandatory("$param2".into(), SyntaxShape::Table),
|
||||||
"Param2 Doc".into()
|
"Param2 Doc".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param3".into(), SyntaxShape::Number),
|
PositionalType::Mandatory("$param3".into(), SyntaxShape::Number),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Optional("param4".into(), SyntaxShape::Table),
|
PositionalType::Optional("$param4".into(), SyntaxShape::Table),
|
||||||
"Optional Param".into()
|
"Optional Param".into()
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -262,15 +262,15 @@ fn simple_def_with_parameters_and_flags_no_delimiter() {
|
|||||||
// --flag3 # Third flag
|
// --flag3 # Third flag
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param1".into(), SyntaxShape::Int),
|
PositionalType::Mandatory("$param1".into(), SyntaxShape::Int),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param2".into(), SyntaxShape::Any),
|
PositionalType::Mandatory("$param2".into(), SyntaxShape::Any),
|
||||||
"".into()
|
"".into()
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PositionalType::Mandatory("param3".into(), SyntaxShape::Any),
|
PositionalType::Mandatory("$param3".into(), SyntaxShape::Any),
|
||||||
"Param3".into()
|
"Param3".into()
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -302,7 +302,7 @@ fn simple_example_signature() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
sign.positional,
|
sign.positional,
|
||||||
vec![(
|
vec![(
|
||||||
PositionalType::Mandatory("d".into(), SyntaxShape::Int),
|
PositionalType::Mandatory("$d".into(), SyntaxShape::Int),
|
||||||
"The required d parameter".into()
|
"The required d parameter".into()
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
@ -374,7 +374,7 @@ fn simple_def_with_param_flag_and_rest() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
sign.positional,
|
sign.positional,
|
||||||
vec![(
|
vec![(
|
||||||
PositionalType::Mandatory("d".into(), SyntaxShape::String),
|
PositionalType::Mandatory("$d".into(), SyntaxShape::String),
|
||||||
"The required d parameter".into()
|
"The required d parameter".into()
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
@ -28,7 +28,7 @@ pub fn expression_to_flat_shape(e: &SpannedExpression) -> Vec<Spanned<FlatShape>
|
|||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
Expression::Path(exprs) => {
|
Expression::FullColumnPath(exprs) => {
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
output.append(&mut expression_to_flat_shape(&exprs.head));
|
output.append(&mut expression_to_flat_shape(&exprs.head));
|
||||||
for member in exprs.tail.iter() {
|
for member in exprs.tail.iter() {
|
||||||
@ -119,6 +119,30 @@ pub fn shapes(commands: &Block) -> Vec<Spanned<FlatShape>> {
|
|||||||
ClassifiedCommand::Expr(expr) => {
|
ClassifiedCommand::Expr(expr) => {
|
||||||
output.append(&mut expression_to_flat_shape(expr))
|
output.append(&mut expression_to_flat_shape(expr))
|
||||||
}
|
}
|
||||||
|
ClassifiedCommand::Dynamic(call) => {
|
||||||
|
output.append(&mut expression_to_flat_shape(&call.head));
|
||||||
|
|
||||||
|
if let Some(positionals) = &call.positional {
|
||||||
|
for positional_arg in positionals {
|
||||||
|
output.append(&mut expression_to_flat_shape(positional_arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(named) = &call.named {
|
||||||
|
for (_, named_arg) in named.iter() {
|
||||||
|
match named_arg {
|
||||||
|
NamedValue::PresentSwitch(span) => {
|
||||||
|
output.push(FlatShape::Flag.spanned(*span));
|
||||||
|
}
|
||||||
|
NamedValue::Value(span, expr) => {
|
||||||
|
output.push(FlatShape::Flag.spanned(*span));
|
||||||
|
output.append(&mut expression_to_flat_shape(expr));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,10 +315,10 @@ impl ExternalCommand {
|
|||||||
pub fn has_it_usage(&self) -> bool {
|
pub fn has_it_usage(&self) -> bool {
|
||||||
self.args.iter().any(|arg| match arg {
|
self.args.iter().any(|arg| match arg {
|
||||||
SpannedExpression {
|
SpannedExpression {
|
||||||
expr: Expression::Path(path),
|
expr: Expression::FullColumnPath(path),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let Path { head, .. } = &**path;
|
let FullColumnPath { head, .. } = &**path;
|
||||||
matches!(head, SpannedExpression{expr: Expression::Variable(x, ..), ..} if x == "$it")
|
matches!(head, SpannedExpression{expr: Expression::Variable(x, ..), ..} if x == "$it")
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -753,7 +753,7 @@ impl PrettyDebugWithSource for SpannedExpression {
|
|||||||
),
|
),
|
||||||
"]",
|
"]",
|
||||||
),
|
),
|
||||||
Expression::Path(path) => path.pretty_debug(source),
|
Expression::FullColumnPath(path) => path.pretty_debug(source),
|
||||||
Expression::FilePath(path) => {
|
Expression::FilePath(path) => {
|
||||||
DbgDocBldr::typed("path", DbgDocBldr::primitive(path.display()))
|
DbgDocBldr::typed("path", DbgDocBldr::primitive(path.display()))
|
||||||
}
|
}
|
||||||
@ -808,7 +808,7 @@ impl PrettyDebugWithSource for SpannedExpression {
|
|||||||
),
|
),
|
||||||
"]",
|
"]",
|
||||||
),
|
),
|
||||||
Expression::Path(path) => path.pretty_debug(source),
|
Expression::FullColumnPath(path) => path.pretty_debug(source),
|
||||||
Expression::FilePath(path) => {
|
Expression::FilePath(path) => {
|
||||||
DbgDocBldr::typed("path", DbgDocBldr::primitive(path.display()))
|
DbgDocBldr::typed("path", DbgDocBldr::primitive(path.display()))
|
||||||
}
|
}
|
||||||
@ -1006,12 +1006,12 @@ impl PrettyDebugWithSource for SpannedLiteral {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash, new, Deserialize, Serialize)]
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash, new, Deserialize, Serialize)]
|
||||||
pub struct Path {
|
pub struct FullColumnPath {
|
||||||
pub head: SpannedExpression,
|
pub head: SpannedExpression,
|
||||||
pub tail: Vec<PathMember>,
|
pub tail: Vec<PathMember>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrettyDebugWithSource for Path {
|
impl PrettyDebugWithSource for FullColumnPath {
|
||||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
||||||
self.head.pretty_debug(source)
|
self.head.pretty_debug(source)
|
||||||
+ DbgDocBldr::operator(".")
|
+ DbgDocBldr::operator(".")
|
||||||
@ -1033,7 +1033,7 @@ pub enum Expression {
|
|||||||
Block(Arc<hir::Block>),
|
Block(Arc<hir::Block>),
|
||||||
List(Vec<SpannedExpression>),
|
List(Vec<SpannedExpression>),
|
||||||
Table(Vec<SpannedExpression>, Vec<Vec<SpannedExpression>>),
|
Table(Vec<SpannedExpression>, Vec<Vec<SpannedExpression>>),
|
||||||
Path(Box<Path>),
|
FullColumnPath(Box<FullColumnPath>),
|
||||||
|
|
||||||
FilePath(PathBuf),
|
FilePath(PathBuf),
|
||||||
ExternalCommand(ExternalStringCommand),
|
ExternalCommand(ExternalStringCommand),
|
||||||
@ -1063,7 +1063,7 @@ impl ShellTypeName for Expression {
|
|||||||
Expression::Range(..) => "range",
|
Expression::Range(..) => "range",
|
||||||
Expression::Block(..) => "block",
|
Expression::Block(..) => "block",
|
||||||
Expression::Invocation(..) => "command invocation",
|
Expression::Invocation(..) => "command invocation",
|
||||||
Expression::Path(..) => "variable path",
|
Expression::FullColumnPath(..) => "variable path",
|
||||||
Expression::Boolean(..) => "boolean",
|
Expression::Boolean(..) => "boolean",
|
||||||
Expression::ExternalCommand(..) => "external",
|
Expression::ExternalCommand(..) => "external",
|
||||||
Expression::Garbage => "garbage",
|
Expression::Garbage => "garbage",
|
||||||
@ -1129,7 +1129,7 @@ impl Expression {
|
|||||||
|
|
||||||
pub fn path(head: SpannedExpression, tail: Vec<impl Into<PathMember>>) -> Expression {
|
pub fn path(head: SpannedExpression, tail: Vec<impl Into<PathMember>>) -> Expression {
|
||||||
let tail = tail.into_iter().map(|t| t.into()).collect();
|
let tail = tail.into_iter().map(|t| t.into()).collect();
|
||||||
Expression::Path(Box::new(Path::new(head, tail)))
|
Expression::FullColumnPath(Box::new(FullColumnPath::new(head, tail)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unit(i: Spanned<i64>, unit: Spanned<Unit>) -> Expression {
|
pub fn unit(i: Spanned<i64>, unit: Spanned<Unit>) -> Expression {
|
||||||
@ -1157,7 +1157,7 @@ impl Expression {
|
|||||||
Expression::List(list) => list.iter().any(|se| se.has_it_usage()),
|
Expression::List(list) => list.iter().any(|se| se.has_it_usage()),
|
||||||
Expression::Invocation(block) => block.has_it_usage(),
|
Expression::Invocation(block) => block.has_it_usage(),
|
||||||
Expression::Binary(binary) => binary.left.has_it_usage() || binary.right.has_it_usage(),
|
Expression::Binary(binary) => binary.left.has_it_usage() || binary.right.has_it_usage(),
|
||||||
Expression::Path(path) => path.head.has_it_usage(),
|
Expression::FullColumnPath(path) => path.head.has_it_usage(),
|
||||||
Expression::Range(range) => {
|
Expression::Range(range) => {
|
||||||
(if let Some(left) = &range.left {
|
(if let Some(left) = &range.left {
|
||||||
left.has_it_usage()
|
left.has_it_usage()
|
||||||
@ -1203,7 +1203,7 @@ impl Expression {
|
|||||||
output.extend(binary.left.get_free_variables(known_variables));
|
output.extend(binary.left.get_free_variables(known_variables));
|
||||||
output.extend(binary.right.get_free_variables(known_variables));
|
output.extend(binary.right.get_free_variables(known_variables));
|
||||||
}
|
}
|
||||||
Expression::Path(path) => {
|
Expression::FullColumnPath(path) => {
|
||||||
output.extend(path.head.get_free_variables(known_variables));
|
output.extend(path.head.get_free_variables(known_variables));
|
||||||
}
|
}
|
||||||
Expression::Range(range) => {
|
Expression::Range(range) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user