subtraction occurs when no space between operands

This commit is contained in:
ConnorSkees 2020-04-20 01:56:53 -04:00
parent 9d9997432a
commit a8e97984d4
2 changed files with 51 additions and 6 deletions

View File

@ -193,6 +193,7 @@ fn eat_op<I: Iterator<Item = IntermediateValue>>(
super_selector: &Selector, super_selector: &Selector,
op: Spanned<Op>, op: Spanned<Op>,
space_separated: &mut Vec<Spanned<Value>>, space_separated: &mut Vec<Spanned<Value>>,
last_was_whitespace: bool,
) -> SassResult<()> { ) -> SassResult<()> {
match op.node { match op.node {
Op::Not => { Op::Not => {
@ -221,8 +222,14 @@ fn eat_op<I: Iterator<Item = IntermediateValue>>(
} }
} }
Op::Minus => { Op::Minus => {
if devour_whitespace(iter) { if devour_whitespace(iter) || !last_was_whitespace {
let right = single_value(iter, scope, super_selector, op.span)?; let right = single_value(iter, scope, super_selector, op.span)?;
if !last_was_whitespace && right.node == Value::Null {
space_separated.push(
right.map_node(|_| Value::Ident("-null".to_string(), QuoteKind::None)),
);
return Ok(());
}
if let Some(left) = space_separated.pop() { if let Some(left) = space_separated.pop() {
space_separated.push(Spanned { space_separated.push(Spanned {
node: Value::BinaryOp(Box::new(left.node), op.node, Box::new(right.node)), node: Value::BinaryOp(Box::new(left.node), op.node, Box::new(right.node)),
@ -331,20 +338,36 @@ impl Value {
Some(Token { pos, .. }) => *pos, Some(Token { pos, .. }) => *pos,
None => todo!("Expected expression."), None => todo!("Expected expression."),
}; };
devour_whitespace(toks);
while toks.peek().is_some() { while toks.peek().is_some() {
intermediate_values.push(Self::parse_intermediate_value(toks, scope, super_selector)?); intermediate_values.push(Self::parse_intermediate_value(toks, scope, super_selector)?);
} }
let mut last_was_whitespace = false;
let mut space_separated = Vec::new(); let mut space_separated = Vec::new();
let mut comma_separated = Vec::new(); let mut comma_separated = Vec::new();
let mut iter = intermediate_values.into_iter().peekable(); let mut iter = intermediate_values.into_iter().peekable();
while let Some(val) = iter.next() { while let Some(val) = iter.next() {
match val { match val {
IntermediateValue::Value(v) => space_separated.push(v), IntermediateValue::Value(v) => {
IntermediateValue::Op(op) => { last_was_whitespace = false;
eat_op(&mut iter, scope, super_selector, op, &mut space_separated)?; space_separated.push(v)
}
IntermediateValue::Op(op) => {
eat_op(
&mut iter,
scope,
super_selector,
op,
&mut space_separated,
last_was_whitespace,
)?;
}
IntermediateValue::Whitespace => {
last_was_whitespace = true;
continue;
} }
IntermediateValue::Whitespace => continue,
IntermediateValue::Comma => { IntermediateValue::Comma => {
last_was_whitespace = false;
if space_separated.len() == 1 { if space_separated.len() == 1 {
comma_separated.push(space_separated.pop().unwrap()); comma_separated.push(space_separated.pop().unwrap());
} else { } else {
@ -366,6 +389,7 @@ impl Value {
} }
} }
IntermediateValue::Bracketed(t) => { IntermediateValue::Bracketed(t) => {
last_was_whitespace = false;
if t.node.is_empty() { if t.node.is_empty() {
space_separated.push( space_separated.push(
Value::List(Vec::new(), ListSeparator::Space, Brackets::Bracketed) Value::List(Vec::new(), ListSeparator::Space, Brackets::Bracketed)
@ -384,6 +408,7 @@ impl Value {
) )
} }
IntermediateValue::Paren(t) => { IntermediateValue::Paren(t) => {
last_was_whitespace = false;
parse_paren(t, scope, super_selector, &mut space_separated)?; parse_paren(t, scope, super_selector, &mut space_separated)?;
} }
} }

View File

@ -170,6 +170,26 @@ test!(
); );
test!( test!(
number_minus_minus_number, number_minus_minus_number,
"a {\n color: 1 - - 2;;\n}\n", "a {\n color: 1 - - 2;\n}\n",
"a {\n color: 3;\n}\n" "a {\n color: 3;\n}\n"
); );
test!(
sub_no_space,
"a {\n color: 10-10;\n}\n",
"a {\n color: 0;\n}\n"
);
test!(
sub_space_on_left,
"a {\n color: 10 -10;\n}\n",
"a {\n color: 10 -10;\n}\n"
);
test!(
sub_space_on_right,
"a {\n color: 10- 10;\n}\n",
"a {\n color: 0;\n}\n"
);
test!(
sub_space_on_both,
"a {\n color: 10 - 10;\n}\n",
"a {\n color: 0;\n}\n"
);