mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 08:06:03 +02:00
Fix known externals, fix operator spans (#5140)
This commit is contained in:
@ -6,7 +6,7 @@ use crate::{DeclId, Span, Spanned};
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Argument {
|
||||
Positional(Expression),
|
||||
Named((Spanned<String>, Option<Expression>)),
|
||||
Named((Spanned<String>, Option<Spanned<String>>, Option<Expression>)),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
@ -30,7 +30,9 @@ impl Call {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn named_iter(&self) -> impl Iterator<Item = &(Spanned<String>, Option<Expression>)> {
|
||||
pub fn named_iter(
|
||||
&self,
|
||||
) -> impl Iterator<Item = &(Spanned<String>, Option<Spanned<String>>, Option<Expression>)> {
|
||||
self.arguments.iter().filter_map(|arg| match arg {
|
||||
Argument::Named(named) => Some(named),
|
||||
Argument::Positional(_) => None,
|
||||
@ -39,7 +41,8 @@ impl Call {
|
||||
|
||||
pub fn named_iter_mut(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = &mut (Spanned<String>, Option<Expression>)> {
|
||||
) -> impl Iterator<Item = &mut (Spanned<String>, Option<Spanned<String>>, Option<Expression>)>
|
||||
{
|
||||
self.arguments.iter_mut().filter_map(|arg| match arg {
|
||||
Argument::Named(named) => Some(named),
|
||||
Argument::Positional(_) => None,
|
||||
@ -50,7 +53,10 @@ impl Call {
|
||||
self.named_iter().count()
|
||||
}
|
||||
|
||||
pub fn add_named(&mut self, named: (Spanned<String>, Option<Expression>)) {
|
||||
pub fn add_named(
|
||||
&mut self,
|
||||
named: (Spanned<String>, Option<Spanned<String>>, Option<Expression>),
|
||||
) {
|
||||
self.arguments.push(Argument::Named(named));
|
||||
}
|
||||
|
||||
@ -93,7 +99,7 @@ impl Call {
|
||||
pub fn get_flag_expr(&self, flag_name: &str) -> Option<Expression> {
|
||||
for name in self.named_iter() {
|
||||
if flag_name == name.0.item {
|
||||
return name.1.clone();
|
||||
return name.2.clone();
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +125,7 @@ impl Call {
|
||||
}
|
||||
}
|
||||
|
||||
for (named, val) in self.named_iter() {
|
||||
for (named, _, val) in self.named_iter() {
|
||||
if named.span.end > span.end {
|
||||
span.end = named.span.end;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ impl Expression {
|
||||
}
|
||||
}
|
||||
for named in call.named_iter() {
|
||||
if let Some(expr) = &named.1 {
|
||||
if let Some(expr) = &named.2 {
|
||||
if expr.has_in_variable(working_set) {
|
||||
return true;
|
||||
}
|
||||
@ -306,7 +306,7 @@ impl Expression {
|
||||
positional.replace_in_variable(working_set, new_var_id);
|
||||
}
|
||||
for named in call.named_iter_mut() {
|
||||
if let Some(expr) = &mut named.1 {
|
||||
if let Some(expr) = &mut named.2 {
|
||||
expr.replace_in_variable(working_set, new_var_id)
|
||||
}
|
||||
}
|
||||
@ -453,7 +453,7 @@ impl Expression {
|
||||
positional.replace_span(working_set, replaced, new_span);
|
||||
}
|
||||
for named in call.named_iter_mut() {
|
||||
if let Some(expr) = &mut named.1 {
|
||||
if let Some(expr) = &mut named.2 {
|
||||
expr.replace_span(working_set, replaced, new_span)
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use std::path::PathBuf;
|
||||
use std::{cmp::Ordering, fmt::Debug};
|
||||
|
||||
use crate::ast::{CellPath, PathMember};
|
||||
use crate::{did_you_mean, span, BlockId, Config, Span, Spanned, Type, VarId};
|
||||
use crate::{did_you_mean, BlockId, Config, Span, Spanned, Type, VarId};
|
||||
|
||||
use crate::ast::Operator;
|
||||
pub use custom_value::CustomValue;
|
||||
@ -1413,9 +1413,7 @@ impl PartialEq for Value {
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn add(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn add(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if let Some(val) = lhs.checked_add(*rhs) {
|
||||
@ -1486,9 +1484,7 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn sub(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn sub(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if let Some(val) = lhs.checked_sub(*rhs) {
|
||||
@ -1566,9 +1562,7 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn mul(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn mul(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if let Some(val) = lhs.checked_mul(*rhs) {
|
||||
@ -1629,9 +1623,7 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn div(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn div(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if *rhs != 0 {
|
||||
@ -1747,9 +1739,7 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn lt(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn lt(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
|
||||
return lhs.operation(*span, Operator::LessThan, op, rhs);
|
||||
}
|
||||
@ -1775,9 +1765,7 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn lte(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn lte(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
|
||||
return lhs.operation(*span, Operator::LessThanOrEqual, op, rhs);
|
||||
}
|
||||
@ -1803,9 +1791,7 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn gt(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn gt(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
|
||||
return lhs.operation(*span, Operator::GreaterThan, op, rhs);
|
||||
}
|
||||
@ -1831,9 +1817,7 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn gte(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn gte(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
|
||||
return lhs.operation(*span, Operator::GreaterThanOrEqual, op, rhs);
|
||||
}
|
||||
@ -1859,9 +1843,7 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn eq(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn eq(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
|
||||
return lhs.operation(*span, Operator::Equal, op, rhs);
|
||||
}
|
||||
@ -1885,9 +1867,7 @@ impl Value {
|
||||
},
|
||||
}
|
||||
}
|
||||
pub fn ne(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn ne(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
|
||||
return lhs.operation(*span, Operator::NotEqual, op, rhs);
|
||||
}
|
||||
@ -1912,9 +1892,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn r#in(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn r#in(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool {
|
||||
val: rhs.contains(lhs),
|
||||
@ -1971,9 +1949,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn not_in(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn not_in(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool {
|
||||
val: !rhs.contains(lhs),
|
||||
@ -2030,9 +2006,13 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn regex_match(&self, op: Span, rhs: &Value, invert: bool) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn regex_match(
|
||||
&self,
|
||||
op: Span,
|
||||
rhs: &Value,
|
||||
invert: bool,
|
||||
span: Span,
|
||||
) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(
|
||||
Value::String { val: lhs, .. },
|
||||
@ -2072,9 +2052,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn starts_with(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn starts_with(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::Bool {
|
||||
val: lhs.starts_with(rhs),
|
||||
@ -2093,9 +2071,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modulo(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn modulo(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if *rhs != 0 {
|
||||
@ -2151,9 +2127,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn and(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn and(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => Ok(Value::Bool {
|
||||
val: *lhs && *rhs,
|
||||
@ -2172,9 +2146,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn or(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn or(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => Ok(Value::Bool {
|
||||
val: *lhs || *rhs,
|
||||
@ -2193,9 +2165,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pow(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||
let span = span(&[self.span()?, rhs.span()?]);
|
||||
|
||||
pub fn pow(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if let Some(val) = lhs.checked_pow(*rhs as u32) {
|
||||
|
@ -38,7 +38,7 @@ impl Range {
|
||||
};
|
||||
|
||||
let to = if let Value::Nothing { .. } = to {
|
||||
if let Ok(Value::Bool { val: true, .. }) = next.lt(expr_span, &from) {
|
||||
if let Ok(Value::Bool { val: true, .. }) = next.lt(expr_span, &from, expr_span) {
|
||||
Value::Int {
|
||||
val: i64::MIN,
|
||||
span: expr_span,
|
||||
@ -54,7 +54,10 @@ impl Range {
|
||||
};
|
||||
|
||||
// Check if the range counts up or down
|
||||
let moves_up = matches!(from.lte(expr_span, &to), Ok(Value::Bool { val: true, .. }));
|
||||
let moves_up = matches!(
|
||||
from.lte(expr_span, &to, expr_span),
|
||||
Ok(Value::Bool { val: true, .. })
|
||||
);
|
||||
|
||||
// Convert the next value into the inctement
|
||||
let incr = if let Value::Nothing { .. } = next {
|
||||
@ -70,7 +73,7 @@ impl Range {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
next.sub(operator.next_op_span, &from)?
|
||||
next.sub(operator.next_op_span, &from, expr_span)?
|
||||
};
|
||||
|
||||
let zero = Value::Int {
|
||||
@ -79,22 +82,25 @@ impl Range {
|
||||
};
|
||||
|
||||
// Increment must be non-zero, otherwise we iterate forever
|
||||
if matches!(incr.eq(expr_span, &zero), Ok(Value::Bool { val: true, .. })) {
|
||||
if matches!(
|
||||
incr.eq(expr_span, &zero, expr_span),
|
||||
Ok(Value::Bool { val: true, .. })
|
||||
) {
|
||||
return Err(ShellError::CannotCreateRange(expr_span));
|
||||
}
|
||||
|
||||
// If to > from, then incr > 0, otherwise we iterate forever
|
||||
if let (Value::Bool { val: true, .. }, Value::Bool { val: false, .. }) = (
|
||||
to.gt(operator.span, &from)?,
|
||||
incr.gt(operator.next_op_span, &zero)?,
|
||||
to.gt(operator.span, &from, expr_span)?,
|
||||
incr.gt(operator.next_op_span, &zero, expr_span)?,
|
||||
) {
|
||||
return Err(ShellError::CannotCreateRange(expr_span));
|
||||
}
|
||||
|
||||
// If to < from, then incr < 0, otherwise we iterate forever
|
||||
if let (Value::Bool { val: true, .. }, Value::Bool { val: false, .. }) = (
|
||||
to.lt(operator.span, &from)?,
|
||||
incr.lt(operator.next_op_span, &zero)?,
|
||||
to.lt(operator.span, &from, expr_span)?,
|
||||
incr.lt(operator.next_op_span, &zero, expr_span)?,
|
||||
) {
|
||||
return Err(ShellError::CannotCreateRange(expr_span));
|
||||
}
|
||||
@ -231,7 +237,7 @@ impl Iterator for RangeIterator {
|
||||
|
||||
if (ordering == desired_ordering) || (self.is_end_inclusive && ordering == Ordering::Equal)
|
||||
{
|
||||
let next_value = self.curr.add(self.span, &self.incr);
|
||||
let next_value = self.curr.add(self.span, &self.incr, self.span);
|
||||
|
||||
let mut next = match next_value {
|
||||
Ok(result) => result,
|
||||
|
Reference in New Issue
Block a user