forked from extern/nushell
Remove it expansion (#2701)
* Remove it-expansion, take 2 * Cleanup * silly update to test CI
This commit is contained in:
@ -40,14 +40,6 @@ impl InternalCommand {
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_it_usage(&mut self) {
|
||||
if let Some(positionals) = &mut self.args.positional {
|
||||
for arg in positionals {
|
||||
arg.expand_it_usage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
@ -84,42 +76,6 @@ pub enum ClassifiedCommand {
|
||||
Error(ParseError),
|
||||
}
|
||||
|
||||
impl ClassifiedCommand {
|
||||
pub fn has_it_iteration(&self) -> bool {
|
||||
match self {
|
||||
ClassifiedCommand::Internal(command) => {
|
||||
let mut result = command.args.head.has_shallow_it_usage();
|
||||
|
||||
if let Some(positionals) = &command.args.positional {
|
||||
for arg in positionals {
|
||||
result = result || arg.has_shallow_it_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(named) = &command.args.named {
|
||||
for arg in named.iter() {
|
||||
if let NamedValue::Value(_, value) = arg.1 {
|
||||
result = result || value.has_shallow_it_usage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
ClassifiedCommand::Expr(expr) => expr.has_shallow_it_usage(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_it_usage(&mut self) {
|
||||
match self {
|
||||
ClassifiedCommand::Internal(command) => command.expand_it_usage(),
|
||||
ClassifiedCommand::Expr(expr) => expr.expand_it_usage(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct Commands {
|
||||
pub list: Vec<ClassifiedCommand>,
|
||||
@ -134,55 +90,28 @@ impl Commands {
|
||||
pub fn push(&mut self, command: ClassifiedCommand) {
|
||||
self.list.push(command);
|
||||
}
|
||||
|
||||
/// Convert all shallow uses of $it to `each { use of $it }`, converting each to a per-row command
|
||||
pub fn expand_it_usage(&mut self) {
|
||||
for idx in 0..self.list.len() {
|
||||
self.list[idx].expand_it_usage();
|
||||
}
|
||||
for idx in 1..self.list.len() {
|
||||
if self.list[idx].has_it_iteration() {
|
||||
self.list[idx] = ClassifiedCommand::Internal(InternalCommand {
|
||||
name: "each".to_string(),
|
||||
name_span: self.span,
|
||||
args: hir::Call {
|
||||
head: Box::new(SpannedExpression {
|
||||
expr: Expression::Synthetic(Synthetic::String(
|
||||
"expanded-each".to_string(),
|
||||
)),
|
||||
span: self.span,
|
||||
}),
|
||||
named: None,
|
||||
span: self.span,
|
||||
positional: Some(vec![SpannedExpression {
|
||||
expr: Expression::Block(Block {
|
||||
block: vec![Commands {
|
||||
list: vec![self.list[idx].clone()],
|
||||
span: self.span,
|
||||
}],
|
||||
span: self.span,
|
||||
}),
|
||||
span: self.span,
|
||||
}]),
|
||||
external_redirection: ExternalRedirection::Stdout, // FIXME
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct Block {
|
||||
pub params: Vec<String>,
|
||||
pub block: Vec<Commands>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn new(span: Span) -> Block {
|
||||
Block {
|
||||
block: vec![],
|
||||
span,
|
||||
pub fn new(params: Option<Vec<String>>, block: Vec<Commands>, span: Span) -> Block {
|
||||
match params {
|
||||
Some(params) => Block {
|
||||
params,
|
||||
block,
|
||||
span,
|
||||
},
|
||||
None => Block {
|
||||
params: vec!["$it".into()],
|
||||
block,
|
||||
span,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,13 +119,6 @@ impl Block {
|
||||
self.block.push(commands);
|
||||
}
|
||||
|
||||
/// Convert all shallow uses of $it to `each { use of $it }`, converting each to a per-row command
|
||||
pub fn expand_it_usage(&mut self) {
|
||||
for commands in &mut self.block {
|
||||
commands.expand_it_usage();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_redirect(&mut self, external_redirection: ExternalRedirection) {
|
||||
if let Some(pipeline) = self.block.last_mut() {
|
||||
if let Some(command) = pipeline.list.last_mut() {
|
||||
@ -250,7 +172,7 @@ impl ExternalCommand {
|
||||
..
|
||||
} => {
|
||||
let Path { head, .. } = &**path;
|
||||
matches!(head, SpannedExpression{expr: Expression::Variable(Variable::It(_)), ..})
|
||||
matches!(head, SpannedExpression{expr: Expression::Variable(x, ..), ..} if x == "$it")
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
@ -594,118 +516,6 @@ impl SpannedExpression {
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_shallow_it_usage(&self) -> bool {
|
||||
match &self.expr {
|
||||
Expression::Binary(binary) => {
|
||||
binary.left.has_shallow_it_usage() || binary.right.has_shallow_it_usage()
|
||||
}
|
||||
Expression::Range(range) => {
|
||||
let left = if let Some(left) = &range.left {
|
||||
left.has_shallow_it_usage()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let right = if let Some(right) = &range.right {
|
||||
right.has_shallow_it_usage()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
left || right
|
||||
}
|
||||
Expression::Variable(Variable::It(_)) => true,
|
||||
Expression::Path(path) => path.head.has_shallow_it_usage(),
|
||||
Expression::List(list) => {
|
||||
for l in list {
|
||||
if l.has_shallow_it_usage() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
Expression::Table(headers, cells) => {
|
||||
for l in headers {
|
||||
if l.has_shallow_it_usage() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for row in cells {
|
||||
for cell in row {
|
||||
if cell.has_shallow_it_usage() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
Expression::Invocation(block) => {
|
||||
for commands in block.block.iter() {
|
||||
for command in commands.list.iter() {
|
||||
if command.has_it_iteration() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_it_usage(&mut self) {
|
||||
match self {
|
||||
SpannedExpression {
|
||||
expr: Expression::Block(block),
|
||||
..
|
||||
} => {
|
||||
block.expand_it_usage();
|
||||
}
|
||||
SpannedExpression {
|
||||
expr: Expression::Invocation(block),
|
||||
..
|
||||
} => {
|
||||
block.expand_it_usage();
|
||||
}
|
||||
SpannedExpression {
|
||||
expr: Expression::List(list),
|
||||
..
|
||||
} => {
|
||||
for item in list.iter_mut() {
|
||||
item.expand_it_usage();
|
||||
}
|
||||
}
|
||||
SpannedExpression {
|
||||
expr: Expression::Table(headers, cells),
|
||||
..
|
||||
} => {
|
||||
for header in headers.iter_mut() {
|
||||
header.expand_it_usage();
|
||||
}
|
||||
|
||||
for row in cells.iter_mut() {
|
||||
for cell in row {
|
||||
cell.expand_it_usage()
|
||||
}
|
||||
}
|
||||
}
|
||||
SpannedExpression {
|
||||
expr: Expression::Path(path),
|
||||
..
|
||||
} => {
|
||||
if let SpannedExpression {
|
||||
expr: Expression::Invocation(block),
|
||||
..
|
||||
} = &mut path.head
|
||||
{
|
||||
block.expand_it_usage();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for SpannedExpression {
|
||||
@ -745,8 +555,7 @@ impl PrettyDebugWithSource for SpannedExpression {
|
||||
b::delimit("s\"", b::primitive(self.span.slice(source)), "\"").group()
|
||||
}
|
||||
},
|
||||
Expression::Variable(Variable::Other(_, _)) => b::keyword(self.span.slice(source)),
|
||||
Expression::Variable(Variable::It(_)) => b::keyword("$it"),
|
||||
Expression::Variable(_, _) => b::keyword(self.span.slice(source)),
|
||||
Expression::Binary(binary) => binary.pretty_debug(source),
|
||||
Expression::Range(range) => range.pretty_debug(source),
|
||||
Expression::Block(_) => b::opaque("block"),
|
||||
@ -800,8 +609,7 @@ impl PrettyDebugWithSource for SpannedExpression {
|
||||
Expression::Synthetic(s) => match s {
|
||||
Synthetic::String(s) => b::typed("synthetic", b::primitive(format!("{:?}", s))),
|
||||
},
|
||||
Expression::Variable(Variable::Other(_, _)) => b::keyword(self.span.slice(source)),
|
||||
Expression::Variable(Variable::It(_)) => b::keyword("$it"),
|
||||
Expression::Variable(_, _) => b::keyword(self.span.slice(source)),
|
||||
Expression::Binary(binary) => binary.pretty_debug(source),
|
||||
Expression::Range(range) => range.pretty_debug(source),
|
||||
Expression::Block(_) => b::opaque("block"),
|
||||
@ -841,12 +649,6 @@ impl PrettyDebugWithSource for SpannedExpression {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash, Deserialize, Serialize)]
|
||||
pub enum Variable {
|
||||
It(Span),
|
||||
Other(String, Span),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialOrd, Ord, Eq, Hash, PartialEq, Deserialize, Serialize)]
|
||||
pub enum Operator {
|
||||
Equal,
|
||||
@ -1039,7 +841,7 @@ pub enum Expression {
|
||||
Literal(Literal),
|
||||
ExternalWord,
|
||||
Synthetic(Synthetic),
|
||||
Variable(Variable),
|
||||
Variable(String, Span),
|
||||
Binary(Box<Binary>),
|
||||
Range(Box<Range>),
|
||||
Block(hir::Block),
|
||||
@ -1148,11 +950,7 @@ impl Expression {
|
||||
}
|
||||
|
||||
pub fn variable(v: String, span: Span) -> Expression {
|
||||
if v == "$it" {
|
||||
Expression::Variable(Variable::It(span))
|
||||
} else {
|
||||
Expression::Variable(Variable::Other(v, span))
|
||||
}
|
||||
Expression::Variable(v, span)
|
||||
}
|
||||
|
||||
pub fn boolean(b: bool) -> Expression {
|
||||
|
@ -5,8 +5,6 @@ use std::fmt::Debug;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// An evaluation scope. Scopes map variable names to Values and aid in evaluating blocks and expressions.
|
||||
/// Additionally, holds the value for the special $it variable, a variable used to refer to the value passing
|
||||
/// through the pipeline at that moment
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
pub struct Scope {
|
||||
vars: IndexMap<String, Value>,
|
||||
@ -63,10 +61,6 @@ impl Scope {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn it(&self) -> Option<Value> {
|
||||
self.var("$it")
|
||||
}
|
||||
|
||||
pub fn from_env(env: IndexMap<String, String>) -> Arc<Scope> {
|
||||
Arc::new(Scope {
|
||||
vars: IndexMap::new(),
|
||||
@ -75,19 +69,9 @@ impl Scope {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn append_it(this: Arc<Self>, it: Value) -> Arc<Scope> {
|
||||
pub fn append_var(this: Arc<Self>, name: impl Into<String>, value: Value) -> Arc<Scope> {
|
||||
let mut vars = IndexMap::new();
|
||||
vars.insert("$it".into(), it);
|
||||
Arc::new(Scope {
|
||||
vars,
|
||||
env: IndexMap::new(),
|
||||
parent: Some(this),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn append_var(this: Arc<Self>, name: String, value: Value) -> Arc<Scope> {
|
||||
let mut vars = IndexMap::new();
|
||||
vars.insert(name, value);
|
||||
vars.insert(name.into(), value);
|
||||
Arc::new(Scope {
|
||||
vars,
|
||||
env: IndexMap::new(),
|
||||
|
Reference in New Issue
Block a user