properly evaluate equality between lists

This commit is contained in:
ConnorSkees 2020-05-28 01:48:46 -04:00
parent 0bc6445ebf
commit 3c1a9a99b7
2 changed files with 87 additions and 6 deletions

View File

@ -8,14 +8,22 @@ use crate::unit::{Unit, UNIT_CONVERSION_TABLE};
use crate::value::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 {
other = other.eval(span)?.node
} else if let Self::UnaryOp(..) = other {
other = other.eval(span)?.node
}
let precedence = Op::Equal.precedence();
Ok(Value::bool(match self {
// todo: why don't we eval the other?
Self::String(s1, ..) => match other {
Self::String(s2, ..) => s1 == s2,
_ => false,
@ -53,14 +61,38 @@ impl Value {
.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,
})
.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 {
other = other.eval(span)?.node
} else if let Self::UnaryOp(..) = other {
other = other.eval(span)?.node
}
let precedence = Op::Equal.precedence();
@ -103,6 +135,23 @@ impl Value {
.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,
})
.span(span))
@ -159,6 +208,8 @@ impl Value {
pub fn cmp(self, mut other: Self, op: Op, span: Span) -> SassResult<Spanned<Value>> {
if let Self::Paren(..) = other {
other = other.eval(span)?.node
} else if let Self::UnaryOp(..) = other {
other = other.eval(span)?.node
}
let precedence = op.precedence();
let ordering = match self {
@ -247,12 +298,17 @@ impl Value {
.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 {
other = other.eval(span)?.node
} else if let Self::UnaryOp(..) = other {
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();
Ok(match self {
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 {
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();
Ok(match self {
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 {
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();
Ok(match self {
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();
Ok(match self {
Self::Null => todo!(),

View File

@ -48,3 +48,13 @@ test!(
"a {\n color: 1rem==1;\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"
);