mirror of
https://github.com/nushell/nushell.git
synced 2025-08-10 00:38:56 +02:00
Track call arguments in a single list (#5125)
* Initial implementation of ordered call args * Run cargo fmt * Fix some clippy lints * Add positional len and nth * Cargo fmt * Remove more old nth calls * Good ole rustfmt * Add named len Co-authored-by: Hristo Filaretov <h.filaretov@protonmail.com>
This commit is contained in:
@ -3,13 +3,18 @@ use serde::{Deserialize, Serialize};
|
||||
use super::Expression;
|
||||
use crate::{DeclId, Span, Spanned};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Argument {
|
||||
Positional(Expression),
|
||||
Named((Spanned<String>, Option<Expression>)),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Call {
|
||||
/// identifier of the declaration to call
|
||||
pub decl_id: DeclId,
|
||||
pub head: Span,
|
||||
pub positional: Vec<Expression>,
|
||||
pub named: Vec<(Spanned<String>, Option<Expression>)>,
|
||||
pub arguments: Vec<Argument>,
|
||||
pub redirect_stdout: bool,
|
||||
pub redirect_stderr: bool,
|
||||
}
|
||||
@ -19,15 +24,64 @@ impl Call {
|
||||
Self {
|
||||
decl_id: 0,
|
||||
head,
|
||||
positional: vec![],
|
||||
named: vec![],
|
||||
arguments: vec![],
|
||||
redirect_stdout: true,
|
||||
redirect_stderr: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn named_iter(&self) -> impl Iterator<Item = &(Spanned<String>, Option<Expression>)> {
|
||||
self.arguments.iter().filter_map(|arg| match arg {
|
||||
Argument::Named(named) => Some(named),
|
||||
Argument::Positional(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn named_iter_mut(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = &mut (Spanned<String>, Option<Expression>)> {
|
||||
self.arguments.iter_mut().filter_map(|arg| match arg {
|
||||
Argument::Named(named) => Some(named),
|
||||
Argument::Positional(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn named_len(&self) -> usize {
|
||||
self.named_iter().count()
|
||||
}
|
||||
|
||||
pub fn add_named(&mut self, named: (Spanned<String>, Option<Expression>)) {
|
||||
self.arguments.push(Argument::Named(named));
|
||||
}
|
||||
|
||||
pub fn add_positional(&mut self, positional: Expression) {
|
||||
self.arguments.push(Argument::Positional(positional));
|
||||
}
|
||||
|
||||
pub fn positional_iter(&self) -> impl Iterator<Item = &Expression> {
|
||||
self.arguments.iter().filter_map(|arg| match arg {
|
||||
Argument::Named(_) => None,
|
||||
Argument::Positional(positional) => Some(positional),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn positional_iter_mut(&mut self) -> impl Iterator<Item = &mut Expression> {
|
||||
self.arguments.iter_mut().filter_map(|arg| match arg {
|
||||
Argument::Named(_) => None,
|
||||
Argument::Positional(positional) => Some(positional),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn positional_nth(&self, i: usize) -> Option<&Expression> {
|
||||
self.positional_iter().nth(i)
|
||||
}
|
||||
|
||||
pub fn positional_len(&self) -> usize {
|
||||
self.positional_iter().count()
|
||||
}
|
||||
|
||||
pub fn has_flag(&self, flag_name: &str) -> bool {
|
||||
for name in &self.named {
|
||||
for name in self.named_iter() {
|
||||
if flag_name == name.0.item {
|
||||
return true;
|
||||
}
|
||||
@ -37,7 +91,7 @@ impl Call {
|
||||
}
|
||||
|
||||
pub fn get_flag_expr(&self, flag_name: &str) -> Option<Expression> {
|
||||
for name in &self.named {
|
||||
for name in self.named_iter() {
|
||||
if flag_name == name.0.item {
|
||||
return name.1.clone();
|
||||
}
|
||||
@ -47,7 +101,7 @@ impl Call {
|
||||
}
|
||||
|
||||
pub fn get_named_arg(&self, flag_name: &str) -> Option<Spanned<String>> {
|
||||
for name in &self.named {
|
||||
for name in self.named_iter() {
|
||||
if flag_name == name.0.item {
|
||||
return Some(name.0.clone());
|
||||
}
|
||||
@ -56,20 +110,16 @@ impl Call {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn nth(&self, pos: usize) -> Option<Expression> {
|
||||
self.positional.get(pos).cloned()
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
let mut span = self.head;
|
||||
|
||||
for positional in &self.positional {
|
||||
for positional in self.positional_iter() {
|
||||
if positional.span.end > span.end {
|
||||
span.end = positional.span.end;
|
||||
}
|
||||
}
|
||||
|
||||
for (named, val) in &self.named {
|
||||
for (named, val) in self.named_iter() {
|
||||
if named.span.end > span.end {
|
||||
span.end = named.span.end;
|
||||
}
|
||||
|
@ -133,12 +133,12 @@ impl Expression {
|
||||
Expr::Binary(_) => false,
|
||||
Expr::Bool(_) => false,
|
||||
Expr::Call(call) => {
|
||||
for positional in &call.positional {
|
||||
for positional in call.positional_iter() {
|
||||
if positional.has_in_variable(working_set) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for named in &call.named {
|
||||
for named in call.named_iter() {
|
||||
if let Some(expr) = &named.1 {
|
||||
if expr.has_in_variable(working_set) {
|
||||
return true;
|
||||
@ -302,10 +302,10 @@ impl Expression {
|
||||
Expr::Binary(_) => {}
|
||||
Expr::Bool(_) => {}
|
||||
Expr::Call(call) => {
|
||||
for positional in &mut call.positional {
|
||||
for positional in call.positional_iter_mut() {
|
||||
positional.replace_in_variable(working_set, new_var_id);
|
||||
}
|
||||
for named in &mut call.named {
|
||||
for named in call.named_iter_mut() {
|
||||
if let Some(expr) = &mut named.1 {
|
||||
expr.replace_in_variable(working_set, new_var_id)
|
||||
}
|
||||
@ -449,10 +449,10 @@ impl Expression {
|
||||
if replaced.contains_span(call.head) {
|
||||
call.head = new_span;
|
||||
}
|
||||
for positional in &mut call.positional {
|
||||
for positional in call.positional_iter_mut() {
|
||||
positional.replace_span(working_set, replaced, new_span);
|
||||
}
|
||||
for named in &mut call.named {
|
||||
for named in call.named_iter_mut() {
|
||||
if let Some(expr) = &mut named.1 {
|
||||
expr.replace_span(working_set, replaced, new_span)
|
||||
}
|
||||
|
Reference in New Issue
Block a user