clippy
This commit is contained in:
parent
b631ad78bc
commit
150ba14b74
@ -71,7 +71,7 @@ impl CallArgs {
|
|||||||
|
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
return Ok(Spanned {
|
return Ok(Spanned {
|
||||||
node: "()".to_string(),
|
node: "()".to_owned(),
|
||||||
span,
|
span,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -181,9 +181,9 @@ impl CallArgs {
|
|||||||
err.push_str(&len.to_string());
|
err.push_str(&len.to_string());
|
||||||
err.push(' ');
|
err.push(' ');
|
||||||
if len == 1 {
|
if len == 1 {
|
||||||
err.push_str("was passed.")
|
err.push_str("was passed.");
|
||||||
} else {
|
} else {
|
||||||
err.push_str("were passed.")
|
err.push_str("were passed.");
|
||||||
}
|
}
|
||||||
return Err((err, self.span()).into());
|
return Err((err, self.span()).into());
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ pub(crate) struct Function {
|
|||||||
|
|
||||||
impl Hash for Function {
|
impl Hash for Function {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.pos.hash(state)
|
self.pos.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +31,8 @@ impl Function {
|
|||||||
Function {
|
Function {
|
||||||
args,
|
args,
|
||||||
body,
|
body,
|
||||||
pos,
|
|
||||||
declared_at_root,
|
declared_at_root,
|
||||||
|
pos,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ impl TryFrom<&Spanned<String>> for AtRuleKind {
|
|||||||
|
|
||||||
Ok(match unvendor(&c.node) {
|
Ok(match unvendor(&c.node) {
|
||||||
"keyframes" => Self::Keyframes,
|
"keyframes" => Self::Keyframes,
|
||||||
_ => Self::Unknown(c.node.to_owned()),
|
_ => Self::Unknown(c.node.clone()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ pub(crate) fn selector_nest(args: CallArgs, parser: &mut Parser<'_>) -> SassResu
|
|||||||
.try_fold(
|
.try_fold(
|
||||||
Selector::new(span),
|
Selector::new(span),
|
||||||
|parent, child| -> SassResult<Selector> {
|
|parent, child| -> SassResult<Selector> {
|
||||||
Ok(child.resolve_parent_selectors(&parent, true)?)
|
child.resolve_parent_selectors(&parent, true)
|
||||||
},
|
},
|
||||||
)?
|
)?
|
||||||
.into_value())
|
.into_value())
|
||||||
@ -97,7 +97,7 @@ pub(crate) fn selector_append(args: CallArgs, parser: &mut Parser<'_>) -> SassRe
|
|||||||
Ok(parsed_selectors
|
Ok(parsed_selectors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.try_fold(first, |parent, child| -> SassResult<Selector> {
|
.try_fold(first, |parent, child| -> SassResult<Selector> {
|
||||||
Ok(Selector(SelectorList {
|
Selector(SelectorList {
|
||||||
components: child
|
components: child
|
||||||
.0
|
.0
|
||||||
.components
|
.components
|
||||||
@ -127,7 +127,7 @@ pub(crate) fn selector_append(args: CallArgs, parser: &mut Parser<'_>) -> SassRe
|
|||||||
.collect::<SassResult<Vec<ComplexSelector>>>()?,
|
.collect::<SassResult<Vec<ComplexSelector>>>()?,
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
.resolve_parent_selectors(&parent, false)?)
|
.resolve_parent_selectors(&parent, false)
|
||||||
})?
|
})?
|
||||||
.into_value())
|
.into_value())
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,7 @@ pub(crate) fn str_insert(mut args: CallArgs, parser: &mut Parser<'_>) -> SassRes
|
|||||||
if i + 1 == idx {
|
if i + 1 == idx {
|
||||||
c.to_string() + s2
|
c.to_string() + s2
|
||||||
} else if idx == 0 && i == 0 {
|
} else if idx == 0 && i == 0 {
|
||||||
s2.to_string() + &c.to_string()
|
s2.to_owned() + &c.to_string()
|
||||||
} else {
|
} else {
|
||||||
c.to_string()
|
c.to_string()
|
||||||
}
|
}
|
||||||
|
@ -533,7 +533,7 @@ fn repr(red: &Number, green: &Number, blue: &Number, alpha: &Number) -> String {
|
|||||||
if alpha < &Number::one() {
|
if alpha < &Number::one() {
|
||||||
format!("rgba({}, {}, {}, {})", red_u8, green_u8, blue_u8, alpha)
|
format!("rgba({}, {}, {}, {})", red_u8, green_u8, blue_u8, alpha)
|
||||||
} else if let Some(c) = NAMED_COLORS.get_by_rgba([red_u8, green_u8, blue_u8]) {
|
} else if let Some(c) = NAMED_COLORS.get_by_rgba([red_u8, green_u8, blue_u8]) {
|
||||||
(*c).to_string()
|
(*c).to_owned()
|
||||||
} else {
|
} else {
|
||||||
format!("#{:0>2x}{:0>2x}{:0>2x}", red_u8, green_u8, blue_u8)
|
format!("#{:0>2x}{:0>2x}{:0>2x}", red_u8, green_u8, blue_u8)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ impl InternedString {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn resolve(self) -> String {
|
pub fn resolve(self) -> String {
|
||||||
STRINGS.with(|interner| interner.borrow().resolve(&self.0).to_string())
|
STRINGS.with(|interner| interner.borrow().resolve(&self.0).to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -33,7 +33,7 @@ impl<'a> Iterator for Lexer<'a> {
|
|||||||
.span
|
.span
|
||||||
.subspan(self.pos as u64, (self.pos + len) as u64);
|
.subspan(self.pos as u64, (self.pos + len) as u64);
|
||||||
self.pos += len;
|
self.pos += len;
|
||||||
Some(Token { kind, pos })
|
Some(Token { pos, kind })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,8 @@ grass input.scss
|
|||||||
clippy::panic_in_result_fn,
|
clippy::panic_in_result_fn,
|
||||||
clippy::unwrap_in_result,
|
clippy::unwrap_in_result,
|
||||||
clippy::map_err_ignore,
|
clippy::map_err_ignore,
|
||||||
|
clippy::default_numeric_fallback,
|
||||||
|
clippy::if_then_some_else_none,
|
||||||
|
|
||||||
// temporarily allowed while under heavy development.
|
// temporarily allowed while under heavy development.
|
||||||
// eventually these allows should be refactored away
|
// eventually these allows should be refactored away
|
||||||
|
@ -68,7 +68,7 @@ impl Toplevel {
|
|||||||
if let Toplevel::RuleSet(_, entries) | Toplevel::KeyframesRuleSet(_, entries) = self {
|
if let Toplevel::RuleSet(_, entries) | Toplevel::KeyframesRuleSet(_, entries) = self {
|
||||||
entries.push(BlockEntry::Style(s));
|
entries.push(BlockEntry::Style(s));
|
||||||
} else {
|
} else {
|
||||||
panic!()
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ impl Toplevel {
|
|||||||
if let Toplevel::RuleSet(_, entries) | Toplevel::KeyframesRuleSet(_, entries) = self {
|
if let Toplevel::RuleSet(_, entries) | Toplevel::KeyframesRuleSet(_, entries) = self {
|
||||||
entries.push(BlockEntry::MultilineComment(s));
|
entries.push(BlockEntry::MultilineComment(s));
|
||||||
} else {
|
} else {
|
||||||
panic!()
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,28 +125,28 @@ impl Css {
|
|||||||
Stmt::Comment(s) => vals.first_mut().unwrap().push_comment(s),
|
Stmt::Comment(s) => vals.first_mut().unwrap().push_comment(s),
|
||||||
Stmt::Media(m) => {
|
Stmt::Media(m) => {
|
||||||
let MediaRule { query, body, .. } = *m;
|
let MediaRule { query, body, .. } = *m;
|
||||||
vals.push(Toplevel::Media { query, body })
|
vals.push(Toplevel::Media { query, body });
|
||||||
}
|
}
|
||||||
Stmt::Supports(s) => {
|
Stmt::Supports(s) => {
|
||||||
let SupportsRule { params, body } = *s;
|
let SupportsRule { params, body } = *s;
|
||||||
vals.push(Toplevel::Supports { params, body })
|
vals.push(Toplevel::Supports { params, body });
|
||||||
}
|
}
|
||||||
Stmt::UnknownAtRule(u) => {
|
Stmt::UnknownAtRule(u) => {
|
||||||
let UnknownAtRule {
|
let UnknownAtRule {
|
||||||
params, body, name, ..
|
params, body, name, ..
|
||||||
} = *u;
|
} = *u;
|
||||||
vals.push(Toplevel::UnknownAtRule(Box::new(ToplevelUnknownAtRule {
|
vals.push(Toplevel::UnknownAtRule(Box::new(ToplevelUnknownAtRule {
|
||||||
|
name,
|
||||||
params,
|
params,
|
||||||
body,
|
body,
|
||||||
name,
|
})));
|
||||||
})))
|
|
||||||
}
|
}
|
||||||
Stmt::Return(..) => unreachable!(),
|
Stmt::Return(..) => unreachable!(),
|
||||||
Stmt::AtRoot { body } => {
|
Stmt::AtRoot { body } => {
|
||||||
body.into_iter().try_for_each(|r| -> SassResult<()> {
|
body.into_iter().try_for_each(|r| -> SassResult<()> {
|
||||||
vals.append(&mut self.parse_stmt(r)?);
|
vals.append(&mut self.parse_stmt(r)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
})?
|
})?;
|
||||||
}
|
}
|
||||||
Stmt::Keyframes(k) => {
|
Stmt::Keyframes(k) => {
|
||||||
let Keyframes { rule, name, body } = *k;
|
let Keyframes { rule, name, body } = *k;
|
||||||
@ -154,10 +154,10 @@ impl Css {
|
|||||||
rule,
|
rule,
|
||||||
name,
|
name,
|
||||||
body,
|
body,
|
||||||
})))
|
})));
|
||||||
}
|
}
|
||||||
k @ Stmt::KeyframesRuleSet(..) => {
|
k @ Stmt::KeyframesRuleSet(..) => {
|
||||||
unreachable!("@keyframes ruleset {:?}", k)
|
unreachable!("@keyframes ruleset {:?}", k);
|
||||||
}
|
}
|
||||||
Stmt::Import(s) => self.plain_imports.push(Toplevel::Import(s)),
|
Stmt::Import(s) => self.plain_imports.push(Toplevel::Import(s)),
|
||||||
};
|
};
|
||||||
@ -183,8 +183,8 @@ impl Css {
|
|||||||
params, body, name, ..
|
params, body, name, ..
|
||||||
} = *u;
|
} = *u;
|
||||||
vec![Toplevel::UnknownAtRule(Box::new(ToplevelUnknownAtRule {
|
vec![Toplevel::UnknownAtRule(Box::new(ToplevelUnknownAtRule {
|
||||||
params,
|
|
||||||
name,
|
name,
|
||||||
|
params,
|
||||||
body,
|
body,
|
||||||
}))]
|
}))]
|
||||||
}
|
}
|
||||||
@ -316,10 +316,10 @@ impl Css {
|
|||||||
if body.is_empty() {
|
if body.is_empty() {
|
||||||
writeln!(buf, ";")?;
|
writeln!(buf, ";")?;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
writeln!(buf, " {{")?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeln!(buf, " {{")?;
|
||||||
|
|
||||||
Css::from_stmts(body, true, self.allows_charset)?._inner_pretty_print(
|
Css::from_stmts(body, true, self.allows_charset)?._inner_pretty_print(
|
||||||
buf,
|
buf,
|
||||||
map,
|
map,
|
||||||
@ -343,10 +343,10 @@ impl Css {
|
|||||||
if body.is_empty() {
|
if body.is_empty() {
|
||||||
writeln!(buf, " {{}}")?;
|
writeln!(buf, " {{}}")?;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
writeln!(buf, " {{")?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeln!(buf, " {{")?;
|
||||||
|
|
||||||
Css::from_stmts(body, true, self.allows_charset)?._inner_pretty_print(
|
Css::from_stmts(body, true, self.allows_charset)?._inner_pretty_print(
|
||||||
buf,
|
buf,
|
||||||
map,
|
map,
|
||||||
@ -369,10 +369,10 @@ impl Css {
|
|||||||
if body.is_empty() {
|
if body.is_empty() {
|
||||||
writeln!(buf, ";")?;
|
writeln!(buf, ";")?;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
writeln!(buf, " {{")?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeln!(buf, " {{")?;
|
||||||
|
|
||||||
Css::from_stmts(body, true, self.allows_charset)?._inner_pretty_print(
|
Css::from_stmts(body, true, self.allows_charset)?._inner_pretty_print(
|
||||||
buf,
|
buf,
|
||||||
map,
|
map,
|
||||||
|
@ -188,22 +188,16 @@ impl<'a> Parser<'a> {
|
|||||||
let value = self.parse_value(true, &|c| match c.peek() {
|
let value = self.parse_value(true, &|c| match c.peek() {
|
||||||
Some(Token { kind: ')', .. }) | Some(Token { kind: ',', .. }) => true,
|
Some(Token { kind: ')', .. }) | Some(Token { kind: ',', .. }) => true,
|
||||||
Some(Token { kind: '.', .. }) => {
|
Some(Token { kind: '.', .. }) => {
|
||||||
if matches!(c.peek_next(), Some(Token { kind: '.', .. })) {
|
let next_is_dot = matches!(c.peek_next(), Some(Token { kind: '.', .. }));
|
||||||
c.reset_cursor();
|
c.reset_cursor();
|
||||||
true
|
|
||||||
} else {
|
next_is_dot
|
||||||
c.reset_cursor();
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(Token { kind: '=', .. }) => {
|
Some(Token { kind: '=', .. }) => {
|
||||||
if matches!(c.peek_next(), Some(Token { kind: '=', .. })) {
|
let next_is_eq = matches!(c.peek_next(), Some(Token { kind: '=', .. }));
|
||||||
c.reset_cursor();
|
c.reset_cursor();
|
||||||
false
|
|
||||||
} else {
|
!next_is_eq
|
||||||
c.reset_cursor();
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(..) | None => false,
|
Some(..) | None => false,
|
||||||
});
|
});
|
||||||
@ -297,13 +291,11 @@ impl<'a> Parser<'a> {
|
|||||||
let right = self.parse_value(true, &|c| match c.peek() {
|
let right = self.parse_value(true, &|c| match c.peek() {
|
||||||
Some(Token { kind: ')', .. }) | Some(Token { kind: ',', .. }) => true,
|
Some(Token { kind: ')', .. }) | Some(Token { kind: ',', .. }) => true,
|
||||||
Some(Token { kind: '.', .. }) => {
|
Some(Token { kind: '.', .. }) => {
|
||||||
if matches!(c.peek_next(), Some(Token { kind: '.', .. })) {
|
let next_is_dot =
|
||||||
|
matches!(c.peek_next(), Some(Token { kind: '.', .. }));
|
||||||
c.reset_cursor();
|
c.reset_cursor();
|
||||||
true
|
|
||||||
} else {
|
next_is_dot
|
||||||
c.reset_cursor();
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(..) | None => false,
|
Some(..) | None => false,
|
||||||
})?;
|
})?;
|
||||||
|
@ -23,7 +23,7 @@ impl<T> NeverEmptyVec<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, value: T) {
|
pub fn push(&mut self, value: T) {
|
||||||
self.rest.push(value)
|
self.rest.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) -> Option<T> {
|
pub fn pop(&mut self) -> Option<T> {
|
||||||
|
@ -122,7 +122,8 @@ impl<'a> Parser<'a> {
|
|||||||
if found_true {
|
if found_true {
|
||||||
self.throw_away_until_closing_curly_brace()?;
|
self.throw_away_until_closing_curly_brace()?;
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
self.scopes.enter_new_scope();
|
self.scopes.enter_new_scope();
|
||||||
let tmp = Parser {
|
let tmp = Parser {
|
||||||
toks: self.toks,
|
toks: self.toks,
|
||||||
@ -146,7 +147,6 @@ impl<'a> Parser<'a> {
|
|||||||
self.scopes.exit_scope();
|
self.scopes.exit_scope();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(("expected \"{\".", tok.pos()).into());
|
return Err(("expected \"{\".", tok.pos()).into());
|
||||||
}
|
}
|
||||||
|
@ -272,11 +272,11 @@ impl<'a> Parser<'a> {
|
|||||||
v => s.push_str(v.to_css_string(interpolation.span)?.borrow()),
|
v => s.push_str(v.to_css_string(interpolation.span)?.borrow()),
|
||||||
};
|
};
|
||||||
continue;
|
continue;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
s.push('#');
|
s.push('#');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
'\n' => return Err(("Expected \".", tok.pos()).into()),
|
'\n' => return Err(("Expected \".", tok.pos()).into()),
|
||||||
'\\' => {
|
'\\' => {
|
||||||
let first = match self.toks.peek() {
|
let first = match self.toks.peek() {
|
||||||
|
@ -13,15 +13,18 @@ use crate::{
|
|||||||
|
|
||||||
use super::{Parser, Stmt};
|
use super::{Parser, Stmt};
|
||||||
|
|
||||||
|
#[allow(clippy::case_sensitive_file_extension_comparisons)]
|
||||||
fn is_plain_css_import(url: &str) -> bool {
|
fn is_plain_css_import(url: &str) -> bool {
|
||||||
if url.len() < 5 {
|
if url.len() < 5 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
url.ends_with(".css")
|
let lower = url.to_ascii_lowercase();
|
||||||
|| url.starts_with("http://")
|
|
||||||
|| url.starts_with("https://")
|
lower.ends_with(".css")
|
||||||
|| url.starts_with("//")
|
|| lower.starts_with("http://")
|
||||||
|
|| lower.starts_with("https://")
|
||||||
|
|| lower.starts_with("//")
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
@ -55,7 +58,7 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
for name in &paths {
|
for name in &paths {
|
||||||
if name.is_file() {
|
if name.is_file() {
|
||||||
return Some(name.to_path_buf());
|
return Some(name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,10 +168,12 @@ impl<'a> Parser<'a> {
|
|||||||
let mut list_of_imports: Vec<Stmt> = Vec::new();
|
let mut list_of_imports: Vec<Stmt> = Vec::new();
|
||||||
for file_name_element in v {
|
for file_name_element in v {
|
||||||
match file_name_element {
|
match file_name_element {
|
||||||
|
#[allow(clippy::case_sensitive_file_extension_comparisons)]
|
||||||
Value::String(s, QuoteKind::Quoted) => {
|
Value::String(s, QuoteKind::Quoted) => {
|
||||||
if s.ends_with(".css")
|
let lower = s.to_ascii_lowercase();
|
||||||
|| s.starts_with("http://")
|
if lower.ends_with(".css")
|
||||||
|| s.starts_with("https://")
|
|| lower.starts_with("http://")
|
||||||
|
|| lower.starts_with("https://")
|
||||||
{
|
{
|
||||||
list_of_imports.push(Stmt::Import(format!("\"{}\"", s)));
|
list_of_imports.push(Stmt::Import(format!("\"{}\"", s)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,7 +40,7 @@ impl<'a, 'b> KeyframesSelectorParser<'a, 'b> {
|
|||||||
let mut ident = self.parser.parse_identifier()?;
|
let mut ident = self.parser.parse_identifier()?;
|
||||||
ident.node.make_ascii_lowercase();
|
ident.node.make_ascii_lowercase();
|
||||||
if ident.node == "to" {
|
if ident.node == "to" {
|
||||||
selectors.push(KeyframesSelector::To)
|
selectors.push(KeyframesSelector::To);
|
||||||
} else {
|
} else {
|
||||||
return Err(("Expected \"to\" or \"from\".", tok.pos).into());
|
return Err(("Expected \"to\" or \"from\".", tok.pos).into());
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ impl<'a, 'b> KeyframesSelectorParser<'a, 'b> {
|
|||||||
let mut ident = self.parser.parse_identifier()?;
|
let mut ident = self.parser.parse_identifier()?;
|
||||||
ident.node.make_ascii_lowercase();
|
ident.node.make_ascii_lowercase();
|
||||||
if ident.node == "from" {
|
if ident.node == "from" {
|
||||||
selectors.push(KeyframesSelector::From)
|
selectors.push(KeyframesSelector::From);
|
||||||
} else {
|
} else {
|
||||||
return Err(("Expected \"to\" or \"from\".", tok.pos).into());
|
return Err(("Expected \"to\" or \"from\".", tok.pos).into());
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ impl<'a> Parser<'a> {
|
|||||||
'{' => {
|
'{' => {
|
||||||
// todo: we can avoid the reallocation by trimming before emitting
|
// todo: we can avoid the reallocation by trimming before emitting
|
||||||
// (in `output.rs`)
|
// (in `output.rs`)
|
||||||
return Ok(name.trim().to_string());
|
return Ok(name.trim().to_owned());
|
||||||
}
|
}
|
||||||
_ => name.push(tok.kind),
|
_ => name.push(tok.kind),
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,8 @@ impl<'a> Parser<'a> {
|
|||||||
self.whitespace_or_comment();
|
self.whitespace_or_comment();
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
return Ok(buf);
|
return Ok(buf);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
let next_tok = self.toks.peek().cloned();
|
let next_tok = self.toks.peek().cloned();
|
||||||
let is_angle = next_tok.map_or(false, |t| t.kind == '<' || t.kind == '>');
|
let is_angle = next_tok.map_or(false, |t| t.kind == '<' || t.kind == '>');
|
||||||
if is_angle || matches!(next_tok, Some(Token { kind: '=', .. })) {
|
if is_angle || matches!(next_tok, Some(Token { kind: '=', .. })) {
|
||||||
@ -108,7 +109,6 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
buf.push_str(&self.expression_until_comparison()?);
|
buf.push_str(&self.expression_until_comparison()?);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
self.expect_char(')')?;
|
self.expect_char(')')?;
|
||||||
self.whitespace_or_comment();
|
self.whitespace_or_comment();
|
||||||
|
@ -165,13 +165,11 @@ impl<'a> Parser<'a> {
|
|||||||
AtRuleKind::Return => {
|
AtRuleKind::Return => {
|
||||||
if self.flags.in_function() {
|
if self.flags.in_function() {
|
||||||
return Ok(vec![Stmt::Return(self.parse_return()?)]);
|
return Ok(vec![Stmt::Return(self.parse_return()?)]);
|
||||||
} else {
|
|
||||||
return Err((
|
|
||||||
"This at-rule is not allowed here.",
|
|
||||||
kind_string.span,
|
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Err(
|
||||||
|
("This at-rule is not allowed here.", kind_string.span).into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
AtRuleKind::AtRoot => {
|
AtRuleKind::AtRoot => {
|
||||||
if self.flags.in_function() {
|
if self.flags.in_function() {
|
||||||
@ -215,7 +213,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.warn(&Spanned {
|
self.warn(&Spanned {
|
||||||
node: message.to_css_string(span)?,
|
node: message.to_css_string(span)?,
|
||||||
span,
|
span,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
AtRuleKind::Debug => {
|
AtRuleKind::Debug => {
|
||||||
let Spanned {
|
let Spanned {
|
||||||
@ -230,7 +228,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.debug(&Spanned {
|
self.debug(&Spanned {
|
||||||
node: message.inspect(span)?,
|
node: message.inspect(span)?,
|
||||||
span,
|
span,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
AtRuleKind::If => stmts.append(&mut self.parse_if()?),
|
AtRuleKind::If => stmts.append(&mut self.parse_if()?),
|
||||||
AtRuleKind::Each => stmts.append(&mut self.parse_each()?),
|
AtRuleKind::Each => stmts.append(&mut self.parse_each()?),
|
||||||
@ -253,7 +251,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
AtRuleKind::Media => stmts.push(self.parse_media()?),
|
AtRuleKind::Media => stmts.push(self.parse_media()?),
|
||||||
AtRuleKind::Unknown(_) => {
|
AtRuleKind::Unknown(_) => {
|
||||||
stmts.push(self.parse_unknown_at_rule(kind_string.node)?)
|
stmts.push(self.parse_unknown_at_rule(kind_string.node)?);
|
||||||
}
|
}
|
||||||
AtRuleKind::Use => {
|
AtRuleKind::Use => {
|
||||||
return Err((
|
return Err((
|
||||||
@ -266,7 +264,7 @@ impl<'a> Parser<'a> {
|
|||||||
AtRuleKind::Extend => self.parse_extend()?,
|
AtRuleKind::Extend => self.parse_extend()?,
|
||||||
AtRuleKind::Supports => stmts.push(self.parse_supports()?),
|
AtRuleKind::Supports => stmts.push(self.parse_supports()?),
|
||||||
AtRuleKind::Keyframes => {
|
AtRuleKind::Keyframes => {
|
||||||
stmts.push(self.parse_keyframes(kind_string.node)?)
|
stmts.push(self.parse_keyframes(kind_string.node)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,7 +306,7 @@ impl<'a> Parser<'a> {
|
|||||||
if self.flags.in_keyframes() {
|
if self.flags.in_keyframes() {
|
||||||
match self.is_selector_or_style()? {
|
match self.is_selector_or_style()? {
|
||||||
SelectorOrStyle::ModuleVariableRedeclaration(module) => {
|
SelectorOrStyle::ModuleVariableRedeclaration(module) => {
|
||||||
self.parse_module_variable_redeclaration(module)?
|
self.parse_module_variable_redeclaration(module)?;
|
||||||
}
|
}
|
||||||
SelectorOrStyle::Style(property, value) => {
|
SelectorOrStyle::Style(property, value) => {
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
@ -338,7 +336,7 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
match self.is_selector_or_style()? {
|
match self.is_selector_or_style()? {
|
||||||
SelectorOrStyle::ModuleVariableRedeclaration(module) => {
|
SelectorOrStyle::ModuleVariableRedeclaration(module) => {
|
||||||
self.parse_module_variable_redeclaration(module)?
|
self.parse_module_variable_redeclaration(module)?;
|
||||||
}
|
}
|
||||||
SelectorOrStyle::Style(property, value) => {
|
SelectorOrStyle::Style(property, value) => {
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
@ -422,11 +420,11 @@ impl<'a> Parser<'a> {
|
|||||||
'{' => {
|
'{' => {
|
||||||
if from_fn {
|
if from_fn {
|
||||||
return Err(("Expected selector.", pos).into());
|
return Err(("Expected selector.", pos).into());
|
||||||
} else {
|
}
|
||||||
|
|
||||||
found_curly = true;
|
found_curly = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
'\\' => {
|
'\\' => {
|
||||||
string.push('\\');
|
string.push('\\');
|
||||||
if let Some(Token { kind, .. }) = self.toks.next() {
|
if let Some(Token { kind, .. }) = self.toks.next() {
|
||||||
@ -835,7 +833,7 @@ impl<'a> Parser<'a> {
|
|||||||
&extend_rule,
|
&extend_rule,
|
||||||
&None,
|
&None,
|
||||||
self.span_before,
|
self.span_before,
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -893,9 +891,9 @@ impl<'a> Parser<'a> {
|
|||||||
let interpolation = self.parse_interpolation()?;
|
let interpolation = self.parse_interpolation()?;
|
||||||
params.push_str(&interpolation.node.to_css_string(interpolation.span)?);
|
params.push_str(&interpolation.node.to_css_string(interpolation.span)?);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
params.push(tok.kind);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params.push(tok.kind);
|
||||||
}
|
}
|
||||||
'\n' | ' ' | '\t' => {
|
'\n' | ' ' | '\t' => {
|
||||||
self.whitespace();
|
self.whitespace();
|
||||||
|
@ -32,12 +32,12 @@ impl<'a> Parser<'a> {
|
|||||||
if let Some(Token { kind: '*', .. }) = self.toks.peek() {
|
if let Some(Token { kind: '*', .. }) = self.toks.peek() {
|
||||||
self.toks.next();
|
self.toks.next();
|
||||||
return Ok(Some('*'.to_string()));
|
return Ok(Some('*'.to_string()));
|
||||||
} else {
|
}
|
||||||
|
|
||||||
let name = self.parse_identifier_no_interpolation(false)?;
|
let name = self.parse_identifier_no_interpolation(false)?;
|
||||||
|
|
||||||
return Ok(Some(name.node));
|
return Ok(Some(name.node));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,12 @@ impl<'a> Parser<'a> {
|
|||||||
toks.push(*tok);
|
toks.push(*tok);
|
||||||
self.toks.peek_forward(1);
|
self.toks.peek_forward(1);
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
scope -= 1;
|
scope -= 1;
|
||||||
toks.push(*tok);
|
toks.push(*tok);
|
||||||
self.toks.peek_forward(1);
|
self.toks.peek_forward(1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
'(' => {
|
'(' => {
|
||||||
toks.push(*tok);
|
toks.push(*tok);
|
||||||
self.toks.peek_forward(1);
|
self.toks.peek_forward(1);
|
||||||
@ -154,13 +154,13 @@ impl<'a> Parser<'a> {
|
|||||||
return Ok(SelectorOrStyle::ModuleVariableRedeclaration(
|
return Ok(SelectorOrStyle::ModuleVariableRedeclaration(
|
||||||
property.into(),
|
property.into(),
|
||||||
));
|
));
|
||||||
} else {
|
}
|
||||||
|
|
||||||
if whitespace_after_property {
|
if whitespace_after_property {
|
||||||
property.push(' ');
|
property.push(' ');
|
||||||
}
|
}
|
||||||
return Ok(SelectorOrStyle::Selector(property));
|
return Ok(SelectorOrStyle::Selector(property));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
if whitespace_after_property {
|
if whitespace_after_property {
|
||||||
property.push(' ');
|
property.push(' ');
|
||||||
@ -219,9 +219,9 @@ impl<'a> Parser<'a> {
|
|||||||
self.toks.next();
|
self.toks.next();
|
||||||
self.whitespace();
|
self.whitespace();
|
||||||
return Ok(styles);
|
return Ok(styles);
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -78,9 +78,9 @@ impl<'a> Parser<'a> {
|
|||||||
'}' => {
|
'}' => {
|
||||||
if nesting == 0 {
|
if nesting == 0 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
|
||||||
nesting -= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nesting -= 1;
|
||||||
}
|
}
|
||||||
'/' => match self.toks.peek() {
|
'/' => match self.toks.peek() {
|
||||||
Some(Token { kind: '/', .. }) => {
|
Some(Token { kind: '/', .. }) => {
|
||||||
@ -107,9 +107,9 @@ impl<'a> Parser<'a> {
|
|||||||
')' => {
|
')' => {
|
||||||
if scope < 1 {
|
if scope < 1 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
|
||||||
scope -= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope -= 1;
|
||||||
}
|
}
|
||||||
'(' => scope += 1,
|
'(' => scope += 1,
|
||||||
'"' | '\'' => {
|
'"' | '\'' => {
|
||||||
|
@ -42,11 +42,11 @@ impl<'a> Parser<'a> {
|
|||||||
')' => {
|
')' => {
|
||||||
if nesting == 0 {
|
if nesting == 0 {
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
nesting -= 1;
|
nesting -= 1;
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
q @ '\'' | q @ '"' => {
|
q @ '\'' | q @ '"' => {
|
||||||
buf.push('"');
|
buf.push('"');
|
||||||
match self.parse_quoted_string(q)?.node {
|
match self.parse_quoted_string(q)?.node {
|
||||||
@ -123,9 +123,9 @@ impl<'a> Parser<'a> {
|
|||||||
buf.push(')');
|
buf.push(')');
|
||||||
self.toks.truncate_iterator_to_cursor();
|
self.toks.truncate_iterator_to_cursor();
|
||||||
return Ok(Some(buf));
|
return Ok(Some(buf));
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -211,7 +211,7 @@ impl<'a> Parser<'a> {
|
|||||||
) {
|
) {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
buf.push_str("min(")
|
buf.push_str("min(");
|
||||||
}
|
}
|
||||||
Some(Token { kind: 'a', .. }) | Some(Token { kind: 'A', .. }) => {
|
Some(Token { kind: 'a', .. }) | Some(Token { kind: 'A', .. }) => {
|
||||||
self.toks.advance_cursor();
|
self.toks.advance_cursor();
|
||||||
@ -221,7 +221,7 @@ impl<'a> Parser<'a> {
|
|||||||
) {
|
) {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
buf.push_str("max(")
|
buf.push_str("max(");
|
||||||
}
|
}
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,8 @@ impl<'a, 'b: 'a> ValueVisitor<'a, 'b> {
|
|||||||
Op::Mul => self.mul(val1, val2)?,
|
Op::Mul => self.mul(val1, val2)?,
|
||||||
Op::Div => self.div(val1, val2, in_parens)?,
|
Op::Div => self.div(val1, val2, in_parens)?,
|
||||||
Op::Rem => self.rem(val1, val2)?,
|
Op::Rem => self.rem(val1, val2)?,
|
||||||
Op::And => Self::and(val1, val2)?,
|
Op::And => Self::and(val1, val2),
|
||||||
Op::Or => Self::or(val1, val2)?,
|
Op::Or => Self::or(val1, val2),
|
||||||
Op::Equal => Self::equal(val1, val2),
|
Op::Equal => Self::equal(val1, val2),
|
||||||
Op::NotEqual => Self::not_equal(val1, val2),
|
Op::NotEqual => Self::not_equal(val1, val2),
|
||||||
Op::GreaterThan => self.greater_than(val1, val2)?,
|
Op::GreaterThan => self.greater_than(val1, val2)?,
|
||||||
@ -110,7 +110,7 @@ impl<'a, 'b: 'a> ValueVisitor<'a, 'b> {
|
|||||||
let val = self.eval(val, in_parens)?;
|
let val = self.eval(val, in_parens)?;
|
||||||
match op {
|
match op {
|
||||||
Op::Minus => self.unary_minus(val),
|
Op::Minus => self.unary_minus(val),
|
||||||
Op::Not => Self::unary_not(&val),
|
Op::Not => Ok(Self::unary_not(&val)),
|
||||||
Op::Plus => self.unary_plus(val),
|
Op::Plus => self.unary_plus(val),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@ -133,8 +133,8 @@ impl<'a, 'b: 'a> ValueVisitor<'a, 'b> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unary_not(val: &Value) -> SassResult<Value> {
|
fn unary_not(val: &Value) -> Value {
|
||||||
Ok(Value::bool(!val.is_true()))
|
Value::bool(!val.is_true())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unary(
|
fn unary(
|
||||||
@ -697,7 +697,7 @@ impl<'a, 'b: 'a> ValueVisitor<'a, 'b> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn and(left: HigherIntermediateValue, right: HigherIntermediateValue) -> SassResult<Value> {
|
fn and(left: HigherIntermediateValue, right: HigherIntermediateValue) -> Value {
|
||||||
let left = match left {
|
let left = match left {
|
||||||
HigherIntermediateValue::Literal(v) => v,
|
HigherIntermediateValue::Literal(v) => v,
|
||||||
v => panic!("{:?}", v),
|
v => panic!("{:?}", v),
|
||||||
@ -706,10 +706,14 @@ impl<'a, 'b: 'a> ValueVisitor<'a, 'b> {
|
|||||||
HigherIntermediateValue::Literal(v) => v,
|
HigherIntermediateValue::Literal(v) => v,
|
||||||
v => panic!("{:?}", v),
|
v => panic!("{:?}", v),
|
||||||
};
|
};
|
||||||
Ok(if left.is_true() { right } else { left })
|
if left.is_true() {
|
||||||
|
right
|
||||||
|
} else {
|
||||||
|
left
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn or(left: HigherIntermediateValue, right: HigherIntermediateValue) -> SassResult<Value> {
|
fn or(left: HigherIntermediateValue, right: HigherIntermediateValue) -> Value {
|
||||||
let left = match left {
|
let left = match left {
|
||||||
HigherIntermediateValue::Literal(v) => v,
|
HigherIntermediateValue::Literal(v) => v,
|
||||||
v => panic!("{:?}", v),
|
v => panic!("{:?}", v),
|
||||||
@ -718,7 +722,11 @@ impl<'a, 'b: 'a> ValueVisitor<'a, 'b> {
|
|||||||
HigherIntermediateValue::Literal(v) => v,
|
HigherIntermediateValue::Literal(v) => v,
|
||||||
v => panic!("{:?}", v),
|
v => panic!("{:?}", v),
|
||||||
};
|
};
|
||||||
Ok(if left.is_true() { left } else { right })
|
if left.is_true() {
|
||||||
|
left
|
||||||
|
} else {
|
||||||
|
right
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn equal(left: HigherIntermediateValue, right: HigherIntermediateValue) -> Value {
|
pub fn equal(left: HigherIntermediateValue, right: HigherIntermediateValue) -> Value {
|
||||||
|
@ -78,7 +78,7 @@ impl<'a> Parser<'a> {
|
|||||||
match val.node {
|
match val.node {
|
||||||
IntermediateValue::Value(v) => {
|
IntermediateValue::Value(v) => {
|
||||||
last_was_whitespace = false;
|
last_was_whitespace = false;
|
||||||
space_separated.push(v.span(val.span))
|
space_separated.push(v.span(val.span));
|
||||||
}
|
}
|
||||||
IntermediateValue::Op(op) => {
|
IntermediateValue::Op(op) => {
|
||||||
iter.parse_op(
|
iter.parse_op(
|
||||||
@ -260,7 +260,8 @@ impl<'a> Parser<'a> {
|
|||||||
self.parse_call_args()?,
|
self.parse_call_args()?,
|
||||||
))
|
))
|
||||||
.span(self.span_before));
|
.span(self.span_before));
|
||||||
} else {
|
}
|
||||||
|
|
||||||
// check for special cased CSS functions
|
// check for special cased CSS functions
|
||||||
match unvendor(&lower) {
|
match unvendor(&lower) {
|
||||||
"calc" | "element" | "expression" => {
|
"calc" | "element" | "expression" => {
|
||||||
@ -279,7 +280,6 @@ impl<'a> Parser<'a> {
|
|||||||
))
|
))
|
||||||
.span(self.span_before));
|
.span(self.span_before));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let call_args = self.parse_call_args()?;
|
let call_args = self.parse_call_args()?;
|
||||||
@ -804,9 +804,9 @@ impl<'a> Parser<'a> {
|
|||||||
self.toks.next();
|
self.toks.next();
|
||||||
self.toks.next();
|
self.toks.next();
|
||||||
return Some(self.parse_unicode_range(kind));
|
return Some(self.parse_unicode_range(kind));
|
||||||
} else {
|
|
||||||
self.toks.reset_cursor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.toks.reset_cursor();
|
||||||
}
|
}
|
||||||
return Some(self.parse_ident_value(predicate));
|
return Some(self.parse_ident_value(predicate));
|
||||||
}
|
}
|
||||||
@ -1157,8 +1157,10 @@ impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Op::Minus => {
|
Op::Minus => {
|
||||||
if self.whitespace() || !last_was_whitespace {
|
let may_be_subtraction = self.whitespace() || !last_was_whitespace;
|
||||||
let right = self.single_value(in_paren)?;
|
let right = self.single_value(in_paren)?;
|
||||||
|
|
||||||
|
if may_be_subtraction {
|
||||||
if let Some(left) = space_separated.pop() {
|
if let Some(left) = space_separated.pop() {
|
||||||
space_separated.push(Spanned {
|
space_separated.push(Spanned {
|
||||||
node: HigherIntermediateValue::BinaryOp(
|
node: HigherIntermediateValue::BinaryOp(
|
||||||
@ -1176,7 +1178,6 @@ impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let right = self.single_value(in_paren)?;
|
|
||||||
space_separated.push(
|
space_separated.push(
|
||||||
right.map_node(|n| HigherIntermediateValue::UnaryOp(op.node, Box::new(n))),
|
right.map_node(|n| HigherIntermediateValue::UnaryOp(op.node, Box::new(n))),
|
||||||
);
|
);
|
||||||
|
@ -157,7 +157,7 @@ impl<'a> Parser<'a> {
|
|||||||
Some(..) | None => {
|
Some(..) | None => {
|
||||||
value?;
|
value?;
|
||||||
self.expect_char(';')?;
|
self.expect_char(';')?;
|
||||||
unreachable!()
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +170,7 @@ impl Attribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Attribute {
|
impl Display for Attribute {
|
||||||
|
#[allow(clippy::branches_sharing_code)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
write!(f, "{}", self.attr)?;
|
write!(f, "{}", self.attr)?;
|
||||||
@ -249,16 +250,17 @@ enum AttributeOp {
|
|||||||
Contains,
|
Contains,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<&'static str> for AttributeOp {
|
impl From<AttributeOp> for &'static str {
|
||||||
fn into(self) -> &'static str {
|
#[inline]
|
||||||
match self {
|
fn from(op: AttributeOp) -> Self {
|
||||||
Self::Any => "",
|
match op {
|
||||||
Self::Equals => "=",
|
AttributeOp::Any => "",
|
||||||
Self::Include => "~=",
|
AttributeOp::Equals => "=",
|
||||||
Self::Dash => "|=",
|
AttributeOp::Include => "~=",
|
||||||
Self::Prefix => "^=",
|
AttributeOp::Dash => "|=",
|
||||||
Self::Suffix => "$=",
|
AttributeOp::Prefix => "^=",
|
||||||
Self::Contains => "*=",
|
AttributeOp::Suffix => "$=",
|
||||||
|
AttributeOp::Contains => "*=",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ impl Hash for ExtendedSelector {
|
|||||||
// but I haven't managed to find a test case
|
// but I haven't managed to find a test case
|
||||||
// that exhibits it.
|
// that exhibits it.
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
ptr::hash(&*self.0, state)
|
ptr::hash(&*self.0, state);
|
||||||
// in case we need to hash the actual value:
|
// in case we need to hash the actual value:
|
||||||
// self.0.borrow().hash(state);
|
// self.0.borrow().hash(state);
|
||||||
}
|
}
|
||||||
@ -66,8 +66,13 @@ impl SelectorHashSet {
|
|||||||
pub fn insert(&mut self, selector: ExtendedSelector) {
|
pub fn insert(&mut self, selector: ExtendedSelector) {
|
||||||
self.0.insert(selector);
|
self.0.insert(selector);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn into_iter(self) -> IntoIter<ExtendedSelector> {
|
impl IntoIterator for SelectorHashSet {
|
||||||
|
type Item = ExtendedSelector;
|
||||||
|
type IntoIter = IntoIter<ExtendedSelector>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
self.0.into_iter()
|
self.0.into_iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ impl Extension {
|
|||||||
// todo: this should return a `Result`. it currently does not because the cascade effect
|
// todo: this should return a `Result`. it currently does not because the cascade effect
|
||||||
// from this returning a `Result` will make some code returning `Option`s much uglier (we can't
|
// from this returning a `Result` will make some code returning `Option`s much uglier (we can't
|
||||||
// use `?` to return both `Option` and `Result` from the same function)
|
// use `?` to return both `Option` and `Result` from the same function)
|
||||||
|
#[allow(clippy::needless_return)]
|
||||||
pub fn assert_compatible_media_context(&self, media_context: &Option<Vec<CssMediaQuery>>) {
|
pub fn assert_compatible_media_context(&self, media_context: &Option<Vec<CssMediaQuery>>) {
|
||||||
if &self.media_context == media_context {
|
if &self.media_context == media_context {
|
||||||
return;
|
return;
|
||||||
|
@ -416,12 +416,12 @@ fn merge_final_combinators(
|
|||||||
result.push_front(vec![vec![
|
result.push_front(vec![vec![
|
||||||
ComplexSelectorComponent::Compound(compound_two),
|
ComplexSelectorComponent::Compound(compound_two),
|
||||||
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
|
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
|
||||||
]])
|
]]);
|
||||||
} else if compound_two.is_super_selector(&compound_one, &None) {
|
} else if compound_two.is_super_selector(&compound_one, &None) {
|
||||||
result.push_front(vec![vec![
|
result.push_front(vec![vec![
|
||||||
ComplexSelectorComponent::Compound(compound_one),
|
ComplexSelectorComponent::Compound(compound_one),
|
||||||
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
|
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
|
||||||
]])
|
]]);
|
||||||
} else {
|
} else {
|
||||||
let mut choices = vec![
|
let mut choices = vec![
|
||||||
vec![
|
vec![
|
||||||
@ -442,7 +442,7 @@ fn merge_final_combinators(
|
|||||||
choices.push(vec![
|
choices.push(vec![
|
||||||
ComplexSelectorComponent::Compound(unified),
|
ComplexSelectorComponent::Compound(unified),
|
||||||
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
|
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
|
||||||
])
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push_front(choices);
|
result.push_front(choices);
|
||||||
|
@ -527,13 +527,7 @@ impl Extender {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Some(
|
Some(unified_paths.into_iter().flatten().flatten().collect())
|
||||||
unified_paths
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|complexes| complexes)
|
|
||||||
.flatten()
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_simple(
|
fn extend_simple(
|
||||||
@ -837,7 +831,7 @@ impl Extender {
|
|||||||
let mut max_specificity = 0;
|
let mut max_specificity = 0;
|
||||||
for component in &complex1.components {
|
for component in &complex1.components {
|
||||||
if let ComplexSelectorComponent::Compound(compound) = component {
|
if let ComplexSelectorComponent::Compound(compound) = component {
|
||||||
max_specificity = max_specificity.max(self.source_specificity_for(compound))
|
max_specificity = max_specificity.max(self.source_specificity_for(compound));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -920,7 +914,7 @@ impl Extender {
|
|||||||
// clone in cases where we have already seen a simple selector (common in
|
// clone in cases where we have already seen a simple selector (common in
|
||||||
// scenarios in which there is a lot of nesting)
|
// scenarios in which there is a lot of nesting)
|
||||||
if let Some(entry) = self.selectors.get_mut(&simple) {
|
if let Some(entry) = self.selectors.get_mut(&simple) {
|
||||||
entry.insert(selector.clone())
|
entry.insert(selector.clone());
|
||||||
} else {
|
} else {
|
||||||
self.selectors
|
self.selectors
|
||||||
.entry(simple.clone())
|
.entry(simple.clone())
|
||||||
@ -1146,7 +1140,7 @@ impl Extender {
|
|||||||
selectors: SelectorHashSet,
|
selectors: SelectorHashSet,
|
||||||
new_extensions: &HashMap<SimpleSelector, IndexMap<ComplexSelector, Extension>>,
|
new_extensions: &HashMap<SimpleSelector, IndexMap<ComplexSelector, Extension>>,
|
||||||
) {
|
) {
|
||||||
for mut selector in selectors.into_iter() {
|
for mut selector in selectors {
|
||||||
let old_value = selector.clone().into_selector().0;
|
let old_value = selector.clone().into_selector().0;
|
||||||
selector.set_inner(self.extend_list(
|
selector.set_inner(self.extend_list(
|
||||||
old_value.clone(),
|
old_value.clone(),
|
||||||
@ -1193,7 +1187,7 @@ fn map_add_all_2<K1: Hash + Eq, K2: Hash + Eq, V>(
|
|||||||
destination: &mut HashMap<K1, IndexMap<K2, V>>,
|
destination: &mut HashMap<K1, IndexMap<K2, V>>,
|
||||||
source: HashMap<K1, IndexMap<K2, V>>,
|
source: HashMap<K1, IndexMap<K2, V>>,
|
||||||
) {
|
) {
|
||||||
source.into_iter().for_each(|(key, mut inner)| {
|
for (key, mut inner) in source {
|
||||||
if destination.contains_key(&key) {
|
if destination.contains_key(&key) {
|
||||||
destination
|
destination
|
||||||
.get_mut(&key)
|
.get_mut(&key)
|
||||||
@ -1202,5 +1196,5 @@ fn map_add_all_2<K1: Hash + Eq, K2: Hash + Eq, V>(
|
|||||||
} else {
|
} else {
|
||||||
destination.get_mut(&key).replace(&mut inner);
|
destination.get_mut(&key).replace(&mut inner);
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,9 +69,9 @@ impl<'a, 'b> SelectorParser<'a, 'b> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
parser,
|
|
||||||
allows_parent,
|
allows_parent,
|
||||||
allows_placeholder,
|
allows_placeholder,
|
||||||
|
parser,
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ impl<'a, 'b> SelectorParser<'a, 'b> {
|
|||||||
}
|
}
|
||||||
Some(Token { kind: '>', .. }) => {
|
Some(Token { kind: '>', .. }) => {
|
||||||
self.parser.toks.next();
|
self.parser.toks.next();
|
||||||
components.push(ComplexSelectorComponent::Combinator(Combinator::Child))
|
components.push(ComplexSelectorComponent::Combinator(Combinator::Child));
|
||||||
}
|
}
|
||||||
Some(Token { kind: '~', .. }) => {
|
Some(Token { kind: '~', .. }) => {
|
||||||
self.parser.toks.next();
|
self.parser.toks.next();
|
||||||
@ -350,7 +350,7 @@ impl<'a, 'b> SelectorParser<'a, 'b> {
|
|||||||
argument = Some(
|
argument = Some(
|
||||||
self.declaration_value()?
|
self.declaration_value()?
|
||||||
.trim_end()
|
.trim_end()
|
||||||
.to_string()
|
.to_owned()
|
||||||
.into_boxed_str(),
|
.into_boxed_str(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -397,16 +397,16 @@ impl<'a, 'b> SelectorParser<'a, 'b> {
|
|||||||
if let Some(Token { kind: '*', .. }) = self.parser.toks.peek() {
|
if let Some(Token { kind: '*', .. }) = self.parser.toks.peek() {
|
||||||
self.parser.toks.next();
|
self.parser.toks.next();
|
||||||
return Ok(SimpleSelector::Universal(Namespace::Asterisk));
|
return Ok(SimpleSelector::Universal(Namespace::Asterisk));
|
||||||
} else {
|
}
|
||||||
|
|
||||||
return Ok(SimpleSelector::Type(QualifiedName {
|
return Ok(SimpleSelector::Type(QualifiedName {
|
||||||
ident: self.parser.parse_identifier()?.node,
|
ident: self.parser.parse_identifier()?.node,
|
||||||
namespace: Namespace::Asterisk,
|
namespace: Namespace::Asterisk,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return Ok(SimpleSelector::Universal(Namespace::None));
|
return Ok(SimpleSelector::Universal(Namespace::None));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Some(Token { kind: '|', pos }) => {
|
Some(Token { kind: '|', pos }) => {
|
||||||
self.parser.span_before = self.parser.span_before.merge(*pos);
|
self.parser.span_before = self.parser.span_before.merge(*pos);
|
||||||
self.parser.toks.next();
|
self.parser.toks.next();
|
||||||
@ -457,11 +457,11 @@ impl<'a, 'b> SelectorParser<'a, 'b> {
|
|||||||
match self.parser.toks.peek() {
|
match self.parser.toks.peek() {
|
||||||
Some(Token { kind: 'e', .. }) | Some(Token { kind: 'E', .. }) => {
|
Some(Token { kind: 'e', .. }) | Some(Token { kind: 'E', .. }) => {
|
||||||
self.expect_identifier("even")?;
|
self.expect_identifier("even")?;
|
||||||
return Ok("even".to_string());
|
return Ok("even".to_owned());
|
||||||
}
|
}
|
||||||
Some(Token { kind: 'o', .. }) | Some(Token { kind: 'O', .. }) => {
|
Some(Token { kind: 'o', .. }) | Some(Token { kind: 'O', .. }) => {
|
||||||
self.expect_identifier("odd")?;
|
self.expect_identifier("odd")?;
|
||||||
return Ok("odd".to_string());
|
return Ok("odd".to_owned());
|
||||||
}
|
}
|
||||||
Some(t @ Token { kind: '+', .. }) | Some(t @ Token { kind: '-', .. }) => {
|
Some(t @ Token { kind: '+', .. }) | Some(t @ Token { kind: '-', .. }) => {
|
||||||
buf.push(t.kind);
|
buf.push(t.kind);
|
||||||
|
@ -28,12 +28,12 @@ pub(crate) fn peek_until_closing_curly_brace(
|
|||||||
'}' => {
|
'}' => {
|
||||||
if nesting == 0 {
|
if nesting == 0 {
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
nesting -= 1;
|
nesting -= 1;
|
||||||
t.push(tok);
|
t.push(tok);
|
||||||
toks.advance_cursor();
|
toks.advance_cursor();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
'/' => {
|
'/' => {
|
||||||
let next = *toks
|
let next = *toks
|
||||||
.peek_forward(1)
|
.peek_forward(1)
|
||||||
|
@ -67,11 +67,11 @@ pub(crate) fn read_until_closing_curly_brace(
|
|||||||
'}' => {
|
'}' => {
|
||||||
if nesting == 0 {
|
if nesting == 0 {
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
nesting -= 1;
|
nesting -= 1;
|
||||||
buf.push(toks.next().unwrap());
|
buf.push(toks.next().unwrap());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
'/' => {
|
'/' => {
|
||||||
let next = toks.next().unwrap();
|
let next = toks.next().unwrap();
|
||||||
match toks.peek() {
|
match toks.peek() {
|
||||||
@ -179,11 +179,11 @@ pub(crate) fn read_until_semicolon_or_closing_curly_brace(
|
|||||||
'}' => {
|
'}' => {
|
||||||
if nesting == 0 {
|
if nesting == 0 {
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
nesting -= 1;
|
nesting -= 1;
|
||||||
t.push(toks.next().unwrap());
|
t.push(toks.next().unwrap());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
'/' => {
|
'/' => {
|
||||||
let next = toks.next().unwrap();
|
let next = toks.next().unwrap();
|
||||||
match toks.peek() {
|
match toks.peek() {
|
||||||
@ -213,9 +213,9 @@ pub(crate) fn read_until_closing_paren(
|
|||||||
if scope < 1 {
|
if scope < 1 {
|
||||||
t.push(tok);
|
t.push(tok);
|
||||||
return Ok(t);
|
return Ok(t);
|
||||||
} else {
|
|
||||||
scope -= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope -= 1;
|
||||||
}
|
}
|
||||||
'(' => scope += 1,
|
'(' => scope += 1,
|
||||||
'"' | '\'' => {
|
'"' | '\'' => {
|
||||||
@ -231,7 +231,7 @@ pub(crate) fn read_until_closing_paren(
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
t.push(tok)
|
t.push(tok);
|
||||||
}
|
}
|
||||||
Ok(t)
|
Ok(t)
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ fn visit_quoted_string(buf: &mut String, force_double_quote: bool, string: &str)
|
|||||||
'\x00'..='\x08' | '\x0A'..='\x1F' => {
|
'\x00'..='\x08' | '\x0A'..='\x1F' => {
|
||||||
buffer.push('\\');
|
buffer.push('\\');
|
||||||
if c as u32 > 0xF {
|
if c as u32 > 0xF {
|
||||||
buffer.push(hex_char_for(c as u32 >> 4))
|
buffer.push(hex_char_for(c as u32 >> 4));
|
||||||
}
|
}
|
||||||
buffer.push(hex_char_for(c as u32 & 0xF));
|
buffer.push(hex_char_for(c as u32 & 0xF));
|
||||||
|
|
||||||
@ -205,9 +205,9 @@ impl Value {
|
|||||||
return Err(
|
return Err(
|
||||||
(format!("{}{} isn't a valid CSS value.", num, unit), span).into()
|
(format!("{}{} isn't a valid CSS value.", num, unit), span).into()
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
return Err((format!("NaN{} isn't a valid CSS value.", unit), span).into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Err((format!("NaN{} isn't a valid CSS value.", unit), span).into());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(num) = num {
|
if let Some(num) = num {
|
||||||
@ -278,7 +278,7 @@ impl Value {
|
|||||||
Value::ArgList(args) => Cow::owned(
|
Value::ArgList(args) => Cow::owned(
|
||||||
args.iter()
|
args.iter()
|
||||||
.filter(|x| !x.is_null())
|
.filter(|x| !x.is_null())
|
||||||
.map(|a| Ok(a.node.to_css_string(span)?))
|
.map(|a| a.node.to_css_string(span))
|
||||||
.collect::<SassResult<Vec<Cow<'static, str>>>>()?
|
.collect::<SassResult<Vec<Cow<'static, str>>>>()?
|
||||||
.join(", "),
|
.join(", "),
|
||||||
),
|
),
|
||||||
@ -464,14 +464,14 @@ impl Value {
|
|||||||
"({},)",
|
"({},)",
|
||||||
args.iter()
|
args.iter()
|
||||||
.filter(|x| !x.is_null())
|
.filter(|x| !x.is_null())
|
||||||
.map(|a| Ok(a.node.inspect(span)?))
|
.map(|a| a.node.inspect(span))
|
||||||
.collect::<SassResult<Vec<Cow<'static, str>>>>()?
|
.collect::<SassResult<Vec<Cow<'static, str>>>>()?
|
||||||
.join(", "),
|
.join(", "),
|
||||||
)),
|
)),
|
||||||
Value::ArgList(args) => Cow::owned(
|
Value::ArgList(args) => Cow::owned(
|
||||||
args.iter()
|
args.iter()
|
||||||
.filter(|x| !x.is_null())
|
.filter(|x| !x.is_null())
|
||||||
.map(|a| Ok(a.node.inspect(span)?))
|
.map(|a| a.node.inspect(span))
|
||||||
.collect::<SassResult<Vec<Cow<'static, str>>>>()?
|
.collect::<SassResult<Vec<Cow<'static, str>>>>()?
|
||||||
.join(", "),
|
.join(", "),
|
||||||
),
|
),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user