improve handling of newlines for @at-root

This commit is contained in:
Connor Skees 2021-07-24 17:42:40 -04:00
parent 3ea5dd48b3
commit 5acbc71071
3 changed files with 85 additions and 17 deletions

View File

@ -80,6 +80,17 @@ impl Toplevel {
}
}
fn set_group_end(group: &mut [Toplevel]) {
match group.last_mut() {
Some(Toplevel::RuleSet { is_group_end, .. })
| Some(Toplevel::Supports { is_group_end, .. })
| Some(Toplevel::Media { is_group_end, .. }) => {
*is_group_end = true;
}
_ => {}
}
}
#[derive(Debug, Clone)]
enum BlockEntry {
Style(Style),
@ -206,7 +217,11 @@ impl Css {
Stmt::Return(..) => unreachable!(),
Stmt::AtRoot { body } => {
body.into_iter().try_for_each(|r| -> SassResult<()> {
vals.append(&mut self.parse_stmt(r)?);
let mut stmts = self.parse_stmt(r)?;
set_group_end(&mut stmts);
vals.append(&mut stmts);
Ok(())
})?;
}
@ -285,14 +300,7 @@ impl Css {
for stmt in stmts {
let mut v = self.parse_stmt(stmt)?;
match v.last_mut() {
Some(Toplevel::RuleSet { is_group_end, .. })
| Some(Toplevel::Supports { is_group_end, .. })
| Some(Toplevel::Media { is_group_end, .. }) => {
*is_group_end = true;
}
_ => {}
}
set_group_end(&mut v);
self.blocks.extend(v);
}

View File

@ -184,9 +184,8 @@ impl<'a> Parser<'a> {
if self.at_root {
stmts.append(&mut self.parse_at_root()?);
} else {
stmts.push(Stmt::AtRoot {
body: self.parse_at_root()?,
});
let body = self.parse_at_root()?;
stmts.push(Stmt::AtRoot { body });
}
}
AtRuleKind::Error => {
@ -780,11 +779,27 @@ impl<'a> Parser<'a> {
_ => Some(Ok(s)),
})
.collect::<SassResult<Vec<Stmt>>>()?;
let mut stmts = vec![Stmt::RuleSet {
selector: at_rule_selector,
body: styles,
}];
stmts.extend(raw_stmts);
let stmts = if at_root_has_selector {
let mut body = styles;
body.extend(raw_stmts);
vec![Stmt::RuleSet {
body,
selector: at_rule_selector,
}]
} else {
if !styles.is_empty() {
return Err((
"Found style at the toplevel inside @at-root.",
self.span_before,
)
.into());
}
raw_stmts
};
Ok(stmts)
}

View File

@ -66,8 +66,53 @@ test!(
"a {}\n\n@at-root {\n @-ms-viewport { width: device-width; }\n}\n",
"@-ms-viewport {\n width: device-width;\n}\n"
);
test!(
newline_between_style_rules_with_same_parent_but_first_is_in_at_root,
"a {
@at-root {
b {
color: red;
}
}
b {
color: red;
}
}",
"b {\n color: red;\n}\n\na b {\n color: red;\n}\n"
);
test!(
no_newline_between_style_rules_when_there_exists_a_selector,
"@at-root a {
a {
color: red;
}
a {
color: red;
}
}",
"a a {\n color: red;\n}\na a {\n color: red;\n}\n"
);
test!(
newline_between_style_rules_when_there_does_not_exist_a_selector,
"@at-root {
a {
color: red;
}
a {
color: red;
}
}",
"a {\n color: red;\n}\n\na {\n color: red;\n}\n"
);
error!(
#[ignore = "we do not currently validate missing closing curly braces"]
missing_closing_curly_brace,
"@at-root {", "Error: expected \"}\"."
);
error!(
style_at_toplevel_without_selector,
"@at-root { color: red; }", "Error: Found style at the toplevel inside @at-root."
);