properly evaluate equality between lists
This commit is contained in:
parent
0bc6445ebf
commit
3c1a9a99b7
@ -8,14 +8,22 @@ use crate::unit::{Unit, UNIT_CONVERSION_TABLE};
|
|||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn equals(self, mut other: Value, span: Span) -> SassResult<Spanned<Value>> {
|
pub fn equals(mut self, mut other: Value, span: Span) -> SassResult<Spanned<Value>> {
|
||||||
|
if let Self::Paren(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
}
|
||||||
if let Self::Paren(..) = other {
|
if let Self::Paren(..) = other {
|
||||||
other = other.eval(span)?.node
|
other = other.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = other {
|
||||||
|
other = other.eval(span)?.node
|
||||||
}
|
}
|
||||||
|
|
||||||
let precedence = Op::Equal.precedence();
|
let precedence = Op::Equal.precedence();
|
||||||
|
|
||||||
Ok(Value::bool(match self {
|
Ok(Value::bool(match self {
|
||||||
|
// todo: why don't we eval the other?
|
||||||
Self::String(s1, ..) => match other {
|
Self::String(s1, ..) => match other {
|
||||||
Self::String(s2, ..) => s1 == s2,
|
Self::String(s2, ..) => s1 == s2,
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -53,14 +61,38 @@ impl Value {
|
|||||||
.eval(span);
|
.eval(span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Self::List(list1, sep1, brackets1) => match other.eval(span)?.node {
|
||||||
|
Self::List(list2, sep2, brackets2) => {
|
||||||
|
if sep1 != sep2 || brackets1 != brackets2 || list1.len() != list2.len() {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
let mut equals = true;
|
||||||
|
for (a, b) in list1.into_iter().zip(list2) {
|
||||||
|
if !a.equals(b, span)?.node.is_true(span)? {
|
||||||
|
equals = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
equals
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
s => s == other.eval(span)?.node,
|
s => s == other.eval(span)?.node,
|
||||||
})
|
})
|
||||||
.span(span))
|
.span(span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_equals(self, mut other: Value, span: Span) -> SassResult<Spanned<Value>> {
|
pub fn not_equals(mut self, mut other: Value, span: Span) -> SassResult<Spanned<Value>> {
|
||||||
|
if let Self::Paren(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
}
|
||||||
if let Self::Paren(..) = other {
|
if let Self::Paren(..) = other {
|
||||||
other = other.eval(span)?.node
|
other = other.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = other {
|
||||||
|
other = other.eval(span)?.node
|
||||||
}
|
}
|
||||||
|
|
||||||
let precedence = Op::Equal.precedence();
|
let precedence = Op::Equal.precedence();
|
||||||
@ -103,6 +135,23 @@ impl Value {
|
|||||||
.eval(span);
|
.eval(span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Self::List(list1, sep1, brackets1) => match other.eval(span)?.node {
|
||||||
|
Self::List(list2, sep2, brackets2) => {
|
||||||
|
if sep1 != sep2 || brackets1 != brackets2 || list1.len() != list2.len() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
let mut equals = false;
|
||||||
|
for (a, b) in list1.into_iter().zip(list2) {
|
||||||
|
if a.not_equals(b, span)?.node.is_true(span)? {
|
||||||
|
equals = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
equals
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
s => s != other.eval(span)?.node,
|
s => s != other.eval(span)?.node,
|
||||||
})
|
})
|
||||||
.span(span))
|
.span(span))
|
||||||
@ -159,6 +208,8 @@ impl Value {
|
|||||||
pub fn cmp(self, mut other: Self, op: Op, span: Span) -> SassResult<Spanned<Value>> {
|
pub fn cmp(self, mut other: Self, op: Op, span: Span) -> SassResult<Spanned<Value>> {
|
||||||
if let Self::Paren(..) = other {
|
if let Self::Paren(..) = other {
|
||||||
other = other.eval(span)?.node
|
other = other.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = other {
|
||||||
|
other = other.eval(span)?.node
|
||||||
}
|
}
|
||||||
let precedence = op.precedence();
|
let precedence = op.precedence();
|
||||||
let ordering = match self {
|
let ordering = match self {
|
||||||
@ -247,12 +298,17 @@ impl Value {
|
|||||||
.span(span))
|
.span(span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(self, mut other: Self, span: Span) -> SassResult<Self> {
|
pub fn add(mut self, mut other: Self, span: Span) -> SassResult<Self> {
|
||||||
if let Self::Paren(..) = other {
|
if let Self::Paren(..) = other {
|
||||||
other = other.eval(span)?.node
|
other = other.eval(span)?.node
|
||||||
} else if let Self::UnaryOp(..) = other {
|
} else if let Self::UnaryOp(..) = other {
|
||||||
other = other.eval(span)?.node
|
other = other.eval(span)?.node
|
||||||
}
|
}
|
||||||
|
if let Self::Paren(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
}
|
||||||
let precedence = Op::Plus.precedence();
|
let precedence = Op::Plus.precedence();
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
Self::Map(..) | Self::Function(..) => {
|
Self::Map(..) | Self::Function(..) => {
|
||||||
@ -392,10 +448,15 @@ impl Value {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub(self, mut other: Self, span: Span) -> SassResult<Self> {
|
pub fn sub(mut self, mut other: Self, span: Span) -> SassResult<Self> {
|
||||||
if let Self::Paren(..) = other {
|
if let Self::Paren(..) = other {
|
||||||
other = other.eval(span)?.node
|
other = other.eval(span)?.node
|
||||||
}
|
}
|
||||||
|
if let Self::Paren(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
}
|
||||||
let precedence = Op::Mul.precedence();
|
let precedence = Op::Mul.precedence();
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
Self::Null => {
|
Self::Null => {
|
||||||
@ -521,10 +582,15 @@ impl Value {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mul(self, mut other: Self, span: Span) -> SassResult<Self> {
|
pub fn mul(mut self, mut other: Self, span: Span) -> SassResult<Self> {
|
||||||
if let Self::Paren(..) = other {
|
if let Self::Paren(..) = other {
|
||||||
other = other.eval(span)?.node
|
other = other.eval(span)?.node
|
||||||
}
|
}
|
||||||
|
if let Self::Paren(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
}
|
||||||
let precedence = Op::Mul.precedence();
|
let precedence = Op::Mul.precedence();
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
Self::Null => todo!(),
|
Self::Null => todo!(),
|
||||||
@ -593,7 +659,12 @@ impl Value {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn div(self, other: Self, span: Span) -> SassResult<Self> {
|
pub fn div(mut self, other: Self, span: Span) -> SassResult<Self> {
|
||||||
|
if let Self::Paren(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
} else if let Self::UnaryOp(..) = self {
|
||||||
|
self = self.eval(span)?.node
|
||||||
|
}
|
||||||
let precedence = Op::Div.precedence();
|
let precedence = Op::Div.precedence();
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
Self::Null => todo!(),
|
Self::Null => todo!(),
|
||||||
|
@ -48,3 +48,13 @@ test!(
|
|||||||
"a {\n color: 1rem==1;\n}\n",
|
"a {\n color: 1rem==1;\n}\n",
|
||||||
"a {\n color: false;\n}\n"
|
"a {\n color: false;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
different_quoting_inside_list_eq,
|
||||||
|
"a {\n color: ("foo",) == (foo,);\n}\n",
|
||||||
|
"a {\n color: true;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
different_quoting_inside_list_ne,
|
||||||
|
"a {\n color: ("foo",) != (foo,);\n}\n",
|
||||||
|
"a {\n color: false;\n}\n"
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user