resolve clippy lints

This commit is contained in:
ConnorSkees 2020-05-31 15:48:11 -04:00
parent b4ef2a6fb4
commit 8390fd8354
14 changed files with 263 additions and 251 deletions

View File

@ -156,7 +156,7 @@ impl Mixin {
} }
Expr::Selector(selector) => { Expr::Selector(selector) => {
let rules = self.eval( let rules = self.eval(
&selector.resolve_parent_selectors(&super_selector, true), &selector.resolve_parent_selectors(super_selector, true),
content, content,
)?; )?;
stmts.push(Spanned { stmts.push(Spanned {

View File

@ -33,7 +33,7 @@ pub(crate) fn eat_stmts<I: Iterator<Item = Token>>(
let rules = eat_stmts( let rules = eat_stmts(
toks, toks,
scope, scope,
&selector.resolve_parent_selectors(&super_selector, true), &selector.resolve_parent_selectors(super_selector, true),
at_root, at_root,
content, content,
)?; )?;
@ -82,7 +82,7 @@ pub(crate) fn eat_stmts_at_root<I: Iterator<Item = Token>>(
Expr::MixinDecl(..) | Expr::FunctionDecl(..) => todo!(), Expr::MixinDecl(..) | Expr::FunctionDecl(..) => todo!(),
Expr::Selector(mut selector) => { Expr::Selector(mut selector) => {
if nesting > 1 || is_some { if nesting > 1 || is_some {
selector = selector.resolve_parent_selectors(&super_selector, true); selector = selector.resolve_parent_selectors(super_selector, true);
} else { } else {
selector = Selector::replace(super_selector, selector); selector = Selector::replace(super_selector, selector);
} }

View File

@ -93,7 +93,7 @@ fn selector_append(
.node .node
.to_selector(span, scope, super_selector, "selectors", false)?; .to_selector(span, scope, super_selector, "selectors", false)?;
if tmp.contains_parent_selector() { if tmp.contains_parent_selector() {
return Err(("Parent selectors aren't allowed here.", span).into()); Err(("Parent selectors aren't allowed here.", span).into())
} else { } else {
Ok(tmp) Ok(tmp)
} }
@ -128,9 +128,7 @@ fn selector_append(
line_break: false, line_break: false,
}) })
} else { } else {
return Err( Err((format!("Can't append {} to {}.", complex, parent), span).into())
(format!("Can't append {} to {}.", complex, parent), span).into()
);
} }
}) })
.collect::<SassResult<Vec<ComplexSelector>>>()?, .collect::<SassResult<Vec<ComplexSelector>>>()?,
@ -196,7 +194,7 @@ fn selector_unify(
.into()); .into());
} }
Ok(match selector1.unify(selector2) { Ok(match selector1.unify(&selector2) {
Some(sel) => sel.into_value(), Some(sel) => sel.into_value(),
None => Value::Null, None => Value::Null,
}) })

View File

@ -47,7 +47,7 @@ impl Color {
} }
} }
fn new_hsla( const fn new_hsla(
red: Number, red: Number,
green: Number, green: Number,
blue: Number, blue: Number,

View File

@ -20,7 +20,7 @@ impl SassError {
} }
} }
pub(crate) fn from_loc(message: String, loc: SpanLoc) -> Self { pub(crate) const fn from_loc(message: String, loc: SpanLoc) -> Self {
SassError { SassError {
kind: SassErrorKind::ParseError { message, loc }, kind: SassErrorKind::ParseError { message, loc },
} }

View File

@ -67,6 +67,7 @@ grass input.scss
clippy::todo, clippy::todo,
clippy::too_many_lines, clippy::too_many_lines,
clippy::panic, clippy::panic,
clippy::unwrap_used,
clippy::option_unwrap_used, clippy::option_unwrap_used,
clippy::result_unwrap_used, clippy::result_unwrap_used,
clippy::cast_possible_truncation, clippy::cast_possible_truncation,

View File

@ -62,7 +62,7 @@ impl ComplexSelector {
pub fn is_invisible(&self) -> bool { pub fn is_invisible(&self) -> bool {
self.components self.components
.iter() .iter()
.any(|component| component.is_invisible()) .any(ComplexSelectorComponent::is_invisible)
} }
/// Returns whether `self` is a superselector of `other`. /// Returns whether `self` is a superselector of `other`.
@ -108,7 +108,7 @@ impl ComplexSelector {
.collect(); .collect();
return compound1.is_super_selector( return compound1.is_super_selector(
other.components.last().unwrap().as_compound(), other.components.last().unwrap().as_compound(),
Some(parents), &Some(parents),
); );
} }
@ -119,7 +119,7 @@ impl ComplexSelector {
{ {
if compound1.is_super_selector( if compound1.is_super_selector(
compound2, compound2,
Some( &Some(
other other
.components .components
.iter() .iter()

View File

@ -16,14 +16,14 @@ impl fmt::Display for CompoundSelector {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut did_write = false; let mut did_write = false;
for simple in &self.components { for simple in &self.components {
if !did_write { if did_write {
write!(f, "{}", simple)?;
} else {
let s = simple.to_string(); let s = simple.to_string();
if !s.is_empty() { if !s.is_empty() {
did_write = true; did_write = true;
} }
write!(f, "{}", s)?; write!(f, "{}", s)?;
} else {
write!(f, "{}", simple)?;
} }
} }
@ -43,7 +43,7 @@ impl CompoundSelector {
pub fn specificity(&self) -> Specificity { pub fn specificity(&self) -> Specificity {
let mut min = 0; let mut min = 0;
let mut max = 0; let mut max = 0;
for simple in self.components.iter() { for simple in &self.components {
todo!() todo!()
// min += simple.min_specificity; // min += simple.min_specificity;
// max += simple.max_specificity; // max += simple.max_specificity;
@ -52,15 +52,13 @@ impl CompoundSelector {
} }
pub fn is_invisible(&self) -> bool { pub fn is_invisible(&self) -> bool {
self.components self.components.iter().any(SimpleSelector::is_invisible)
.iter()
.any(|component| component.is_invisible())
} }
pub fn is_super_selector( pub fn is_super_selector(
&self, &self,
other: &Self, other: &Self,
parents: Option<Vec<ComplexSelectorComponent>>, parents: &Option<Vec<ComplexSelectorComponent>>,
) -> bool { ) -> bool {
for simple1 in &self.components { for simple1 in &self.components {
if let SimpleSelector::Pseudo( if let SimpleSelector::Pseudo(
@ -84,13 +82,13 @@ impl CompoundSelector {
.. ..
}) = simple2 }) = simple2
{ {
if !simple2.is_super_selector_of_compound(&self) { if !simple2.is_super_selector_of_compound(self) {
return false; return false;
} }
} }
} }
return true; true
} }
/// Returns a new `CompoundSelector` based on `compound` with all /// Returns a new `CompoundSelector` based on `compound` with all

View File

@ -1,3 +1,5 @@
#![allow(clippy::similar_names)]
use std::collections::VecDeque; use std::collections::VecDeque;
use super::{ use super::{
@ -5,7 +7,7 @@ use super::{
}; };
/// Returns the contents of a `SelectorList` that matches only elements that are /// Returns the contents of a `SelectorList` that matches only elements that are
/// matched by both `complex1` and `complex2`. /// matched by both `complex_one` and `complex_two`.
/// ///
/// If no such list can be produced, returns `None`. /// If no such list can be produced, returns `None`.
pub(crate) fn unify_complex( pub(crate) fn unify_complex(
@ -74,7 +76,7 @@ fn weave(complexes: Vec<Vec<ComplexSelectorComponent>>) -> Vec<Vec<ComplexSelect
let target = complex.last().unwrap().clone(); let target = complex.last().unwrap().clone();
if complex.len() == 1 { if complex.len() == 1 {
for prefix in prefixes.iter_mut() { for prefix in &mut prefixes {
prefix.push(target.clone()); prefix.push(target.clone());
} }
continue; continue;
@ -94,8 +96,6 @@ fn weave(complexes: Vec<Vec<ComplexSelectorComponent>>) -> Vec<Vec<ComplexSelect
parent_prefix.push(target.clone()); parent_prefix.push(target.clone());
new_prefixes.push(parent_prefix); new_prefixes.push(parent_prefix);
} }
} else {
continue;
} }
} }
prefixes = new_prefixes; prefixes = new_prefixes;
@ -104,7 +104,7 @@ fn weave(complexes: Vec<Vec<ComplexSelectorComponent>>) -> Vec<Vec<ComplexSelect
prefixes prefixes
} }
/// Interweaves `parents1` and `parents2` as parents of the same target selector. /// Interweaves `parents_one` and `parents_two` as parents of the same target selector.
/// ///
/// Returns all possible orderings of the selectors in the inputs (including /// Returns all possible orderings of the selectors in the inputs (including
/// using unification) that maintain the relative ordering of the input. For /// using unification) that maintain the relative ordering of the input. For
@ -118,61 +118,61 @@ fn weave(complexes: Vec<Vec<ComplexSelectorComponent>>) -> Vec<Vec<ComplexSelect
/// elements matched by `B X`. Some `AB_i` are elided to reduce the size of /// elements matched by `B X`. Some `AB_i` are elided to reduce the size of
/// the output. /// the output.
fn weave_parents( fn weave_parents(
parents1: Vec<ComplexSelectorComponent>, parents_one: Vec<ComplexSelectorComponent>,
parents2: Vec<ComplexSelectorComponent>, parents_two: Vec<ComplexSelectorComponent>,
) -> Option<Vec<Vec<ComplexSelectorComponent>>> { ) -> Option<Vec<Vec<ComplexSelectorComponent>>> {
let mut queue1 = VecDeque::from(parents1); let mut queue_one = VecDeque::from(parents_one);
let mut queue2 = VecDeque::from(parents2); let mut queue_two = VecDeque::from(parents_two);
let initial_combinators = merge_initial_combinators(&mut queue1, &mut queue2)?; let initial_combinators = merge_initial_combinators(&mut queue_one, &mut queue_two)?;
let mut final_combinators = merge_final_combinators(&mut queue1, &mut queue2, None)?; let mut final_combinators = merge_final_combinators(&mut queue_one, &mut queue_two, None)?;
match (first_if_root(&mut queue1), first_if_root(&mut queue2)) { match (first_if_root(&mut queue_one), first_if_root(&mut queue_two)) {
(Some(root1), Some(root2)) => { (Some(root_one), Some(root_two)) => {
let root = ComplexSelectorComponent::Compound(root1.unify(root2)?); let root = ComplexSelectorComponent::Compound(root_one.unify(root_two)?);
queue1.push_front(root.clone()); queue_one.push_front(root.clone());
queue2.push_front(root); queue_two.push_front(root);
} }
(Some(root1), None) => { (Some(root_one), None) => {
queue2.push_front(ComplexSelectorComponent::Compound(root1)); queue_two.push_front(ComplexSelectorComponent::Compound(root_one));
} }
(None, Some(root2)) => { (None, Some(root_two)) => {
queue1.push_front(ComplexSelectorComponent::Compound(root2)); queue_one.push_front(ComplexSelectorComponent::Compound(root_two));
} }
(None, None) => {} (None, None) => {}
} }
let mut groups1 = group_selectors(Vec::from(queue1)); let mut groups_one = group_selectors(Vec::from(queue_one));
let mut groups2 = group_selectors(Vec::from(queue2)); let mut groups_two = group_selectors(Vec::from(queue_two));
let lcs = longest_common_subsequence( let lcs = longest_common_subsequence(
Vec::from(groups2.clone()), groups_two.as_slices().0,
Vec::from(groups1.clone()), groups_one.as_slices().0,
Some(&|group1, group2| { Some(&|group_one, group_two| {
if group1 == group2 { if group_one == group_two {
return Some(group1); return Some(group_one);
} }
if let ComplexSelectorComponent::Combinator(..) = group1.first()? { if let ComplexSelectorComponent::Combinator(..) = group_one.first()? {
return None; return None;
} }
if let ComplexSelectorComponent::Combinator(..) = group2.first()? { if let ComplexSelectorComponent::Combinator(..) = group_two.first()? {
return None; return None;
} }
if complex_is_parent_superselector(group1.clone(), group2.clone()) { if complex_is_parent_superselector(group_one.clone(), group_two.clone()) {
return Some(group2); return Some(group_two);
} }
if complex_is_parent_superselector(group2.clone(), group1.clone()) { if complex_is_parent_superselector(group_two.clone(), group_one.clone()) {
return Some(group1); return Some(group_one);
} }
if !must_unify(group1.clone(), group2.clone()) { if !must_unify(&group_one, &group_two) {
return None; return None;
} }
let unified = unify_complex(vec![group1, group2])?; let unified = unify_complex(vec![group_one, group_two])?;
if unified.len() > 1 { if unified.len() > 1 {
return None; return None;
} }
@ -188,7 +188,7 @@ fn weave_parents(
for group in lcs { for group in lcs {
choices.push( choices.push(
chunks(&mut groups1, &mut groups2, |sequence| { chunks(&mut groups_one, &mut groups_two, |sequence| {
complex_is_parent_superselector(sequence.get(0).unwrap().clone(), group.clone()) complex_is_parent_superselector(sequence.get(0).unwrap().clone(), group.clone())
}) })
.into_iter() .into_iter()
@ -196,12 +196,12 @@ fn weave_parents(
.collect(), .collect(),
); );
choices.push(vec![group]); choices.push(vec![group]);
groups1.pop_front(); groups_one.pop_front();
groups2.pop_front(); groups_two.pop_front();
} }
choices.push( choices.push(
chunks(&mut groups1, &mut groups2, |sequence| sequence.is_empty()) chunks(&mut groups_one, &mut groups_two, VecDeque::is_empty)
.into_iter() .into_iter()
.map(|chunk| chunk.into_iter().flatten().collect()) .map(|chunk| chunk.into_iter().flatten().collect())
.collect(), .collect(),
@ -222,35 +222,35 @@ fn weave_parents(
) )
} }
/// Extracts leading `Combinator`s from `components1` and `components2` and /// Extracts leading `Combinator`s from `components_one` and `components_two` and
/// merges them together into a single list of combinators. /// merges them together into a single list of combinators.
/// ///
/// If there are no combinators to be merged, returns an empty list. If the /// If there are no combinators to be merged, returns an empty list. If the
/// combinators can't be merged, returns `None`. /// combinators can't be merged, returns `None`.
fn merge_initial_combinators( fn merge_initial_combinators(
components1: &mut VecDeque<ComplexSelectorComponent>, components_one: &mut VecDeque<ComplexSelectorComponent>,
components2: &mut VecDeque<ComplexSelectorComponent>, components_two: &mut VecDeque<ComplexSelectorComponent>,
) -> Option<Vec<Combinator>> { ) -> Option<Vec<Combinator>> {
let mut combinators1: Vec<Combinator> = Vec::new(); let mut combinators_one: Vec<Combinator> = Vec::new();
while let Some(ComplexSelectorComponent::Combinator(c)) = components1.get(0) { while let Some(ComplexSelectorComponent::Combinator(c)) = components_one.get(0) {
combinators1.push(*c); combinators_one.push(*c);
components1.pop_front(); components_one.pop_front();
} }
let mut combinators2 = Vec::new(); let mut combinators_two = Vec::new();
while let Some(ComplexSelectorComponent::Combinator(c)) = components2.get(0) { while let Some(ComplexSelectorComponent::Combinator(c)) = components_two.get(0) {
combinators2.push(*c); combinators_two.push(*c);
components2.pop_front(); components_two.pop_front();
} }
let lcs = longest_common_subsequence(combinators1.clone(), combinators2.clone(), None); let lcs = longest_common_subsequence(&combinators_one, &combinators_two, None);
if lcs == combinators1 { if lcs == combinators_one {
Some(combinators2) Some(combinators_two)
} else if lcs == combinators2 { } else if lcs == combinators_two {
Some(combinators1) Some(combinators_one)
} else { } else {
// If neither sequence of combinators is a subsequence of the other, they // If neither sequence of combinators is a subsequence of the other, they
// cannot be merged successfully. // cannot be merged successfully.
@ -258,34 +258,38 @@ fn merge_initial_combinators(
} }
} }
/// Returns the longest common subsequence between `list1` and `list2`. /// Returns the longest common subsequence between `list_one` and `list_two`.
/// ///
/// If there are more than one equally long common subsequence, returns the one /// If there are more than one equally long common subsequence, returns the one
/// which starts first in `list1`. /// which starts first in `list_one`.
/// ///
/// If `select` is passed, it's used to check equality between elements in each /// If `select` is passed, it's used to check equality between elements in each
/// list. If it returns `None`, the elements are considered unequal; otherwise, /// list. If it returns `None`, the elements are considered unequal; otherwise,
/// it should return the element to include in the return value. /// it should return the element to include in the return value.
#[allow(clippy::cast_sign_loss, clippy::cast_possible_wrap)]
fn longest_common_subsequence<T: PartialEq + Clone + std::fmt::Debug>( fn longest_common_subsequence<T: PartialEq + Clone + std::fmt::Debug>(
list1: Vec<T>, list_one: &[T],
list2: Vec<T>, list_two: &[T],
select: Option<&dyn Fn(T, T) -> Option<T>>, select: Option<&dyn Fn(T, T) -> Option<T>>,
) -> Vec<T> { ) -> Vec<T> {
let select = select.unwrap_or(&|element1, element2| { let select = select.unwrap_or(&|element_one, element_two| {
if element1 == element2 { if element_one == element_two {
Some(element1) Some(element_one)
} else { } else {
None None
} }
}); });
let mut lengths = vec![vec![0; list2.len() + 1]; list1.len() + 1]; let mut lengths = vec![vec![0; list_two.len() + 1]; list_one.len() + 1];
let mut selections: Vec<Vec<Option<T>>> = vec![vec![None; list2.len()]; list1.len()]; let mut selections: Vec<Vec<Option<T>>> = vec![vec![None; list_two.len()]; list_one.len()];
for i in 0..list1.len() { for i in 0..list_one.len() {
for j in 0..list2.len() { for j in 0..list_two.len() {
let selection = select(list1.get(i).unwrap().clone(), list2.get(j).unwrap().clone()); let selection = select(
list_one.get(i).unwrap().clone(),
list_two.get(j).unwrap().clone(),
);
selections[i][j] = selection.clone(); selections[i][j] = selection.clone();
lengths[i + 1][j + 1] = if selection.is_none() { lengths[i + 1][j + 1] = if selection.is_none() {
std::cmp::max(lengths[i + 1][j], lengths[i][j + 1]) std::cmp::max(lengths[i + 1][j], lengths[i][j + 1])
@ -319,69 +323,70 @@ fn longest_common_subsequence<T: PartialEq + Clone + std::fmt::Debug>(
} }
} }
backtrack( backtrack(
list1.len() as isize - 1, (list_one.len() as isize).saturating_sub(1),
list2.len() as isize - 1, (list_two.len() as isize).saturating_sub(1),
lengths, lengths,
&mut selections, &mut selections,
) )
} }
/// Extracts trailing `Combinator`s, and the selectors to which they apply, from /// Extracts trailing `Combinator`s, and the selectors to which they apply, from
/// `components1` and `components2` and merges them together into a single list. /// `components_one` and `components_two` and merges them together into a single list.
/// ///
/// If there are no combinators to be merged, returns an empty list. If the /// If there are no combinators to be merged, returns an empty list. If the
/// sequences can't be merged, returns `None`. /// sequences can't be merged, returns `None`.
#[allow(clippy::cognitive_complexity)]
fn merge_final_combinators( fn merge_final_combinators(
components1: &mut VecDeque<ComplexSelectorComponent>, components_one: &mut VecDeque<ComplexSelectorComponent>,
components2: &mut VecDeque<ComplexSelectorComponent>, components_two: &mut VecDeque<ComplexSelectorComponent>,
result: Option<VecDeque<Vec<Vec<ComplexSelectorComponent>>>>, result: Option<VecDeque<Vec<Vec<ComplexSelectorComponent>>>>,
) -> Option<Vec<Vec<Vec<ComplexSelectorComponent>>>> { ) -> Option<Vec<Vec<Vec<ComplexSelectorComponent>>>> {
let mut result = result.unwrap_or(VecDeque::new()); let mut result = result.unwrap_or_default();
if (components1.is_empty() if (components_one.is_empty()
|| !components1 || !components_one
.get(components1.len() - 1) .get(components_one.len() - 1)
.unwrap() .unwrap()
.is_combinator()) .is_combinator())
&& (components2.is_empty() && (components_two.is_empty()
|| !components2 || !components_two
.get(components2.len() - 1) .get(components_two.len() - 1)
.unwrap() .unwrap()
.is_combinator()) .is_combinator())
{ {
return Some(Vec::from(result)); return Some(Vec::from(result));
} }
let mut combinators1 = Vec::new(); let mut combinators_one = Vec::new();
while let Some(ComplexSelectorComponent::Combinator(combinator)) = while let Some(ComplexSelectorComponent::Combinator(combinator)) =
components1.get(components1.len().checked_sub(1).unwrap_or(0)) components_one.get(components_one.len().saturating_sub(1))
{ {
combinators1.push(*combinator); combinators_one.push(*combinator);
components1.pop_back(); components_one.pop_back();
} }
let mut combinators2 = Vec::new(); let mut combinators_two = Vec::new();
while let Some(ComplexSelectorComponent::Combinator(combinator)) = while let Some(ComplexSelectorComponent::Combinator(combinator)) =
components2.get(components2.len().checked_sub(1).unwrap_or(0)) components_two.get(components_two.len().saturating_sub(1))
{ {
combinators2.push(*combinator); combinators_two.push(*combinator);
components2.pop_back(); components_two.pop_back();
} }
if combinators1.len() > 1 || combinators2.len() > 1 { if combinators_one.len() > 1 || combinators_two.len() > 1 {
// If there are multiple combinators, something hacky's going on. If one // If there are multiple combinators, something hacky's going on. If one
// is a supersequence of the other, use that, otherwise give up. // is a supersequence of the other, use that, otherwise give up.
let lcs = longest_common_subsequence(combinators1.clone(), combinators2.clone(), None); let lcs = longest_common_subsequence(&combinators_one, &combinators_two, None);
if lcs == combinators1 { if lcs == combinators_one {
result.push_front(vec![combinators2 result.push_front(vec![combinators_two
.into_iter() .into_iter()
.map(ComplexSelectorComponent::Combinator) .map(ComplexSelectorComponent::Combinator)
.rev() .rev()
.collect()]); .collect()]);
} else if lcs == combinators2 { } else if lcs == combinators_two {
result.push_front(vec![combinators1 result.push_front(vec![combinators_one
.into_iter() .into_iter()
.map(ComplexSelectorComponent::Combinator) .map(ComplexSelectorComponent::Combinator)
.rev() .rev()
@ -393,60 +398,60 @@ fn merge_final_combinators(
return Some(Vec::from(result)); return Some(Vec::from(result));
} }
let combinator1 = if combinators1.is_empty() { let combinator_one = if combinators_one.is_empty() {
None None
} else { } else {
combinators1.first() combinators_one.first()
}; };
let combinator2 = if combinators2.is_empty() { let combinator_two = if combinators_two.is_empty() {
None None
} else { } else {
combinators2.first() combinators_two.first()
}; };
// This code looks complicated, but it's actually just a bunch of special // This code looks complicated, but it's actually just a bunch of special
// cases for interactions between different combinators. // cases for interactions between different combinators.
match (combinator1, combinator2) { match (combinator_one, combinator_two) {
(Some(combinator1), Some(combinator2)) => { (Some(combinator_one), Some(combinator_two)) => {
let compound1 = match components1.pop_back() { let compound_one = match components_one.pop_back() {
Some(ComplexSelectorComponent::Compound(c)) => c, Some(ComplexSelectorComponent::Compound(c)) => c,
Some(..) | None => unreachable!(), Some(..) | None => unreachable!(),
}; };
let compound2 = match components2.pop_back() { let compound_two = match components_two.pop_back() {
Some(ComplexSelectorComponent::Compound(c)) => c, Some(ComplexSelectorComponent::Compound(c)) => c,
Some(..) | None => unreachable!(), Some(..) | None => unreachable!(),
}; };
match (combinator1, combinator2) { match (combinator_one, combinator_two) {
(Combinator::FollowingSibling, Combinator::FollowingSibling) => { (Combinator::FollowingSibling, Combinator::FollowingSibling) => {
if compound1.is_super_selector(&compound2, None) { if compound_one.is_super_selector(&compound_two, &None) {
result.push_front(vec![vec![ result.push_front(vec![vec![
ComplexSelectorComponent::Compound(compound2), ComplexSelectorComponent::Compound(compound_two),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling), ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
]]) ]])
} else if compound2.is_super_selector(&compound1, None) { } else if compound_two.is_super_selector(&compound_one, &None) {
result.push_front(vec![vec![ result.push_front(vec![vec![
ComplexSelectorComponent::Compound(compound1), ComplexSelectorComponent::Compound(compound_one),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling), ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
]]) ]])
} else { } else {
let mut choices = vec![ let mut choices = vec![
vec![ vec![
ComplexSelectorComponent::Compound(compound1.clone()), ComplexSelectorComponent::Compound(compound_one.clone()),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling), ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
ComplexSelectorComponent::Compound(compound2.clone()), ComplexSelectorComponent::Compound(compound_two.clone()),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling), ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
], ],
vec![ vec![
ComplexSelectorComponent::Compound(compound2.clone()), ComplexSelectorComponent::Compound(compound_two.clone()),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling), ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
ComplexSelectorComponent::Compound(compound1.clone()), ComplexSelectorComponent::Compound(compound_one.clone()),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling), ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
], ],
]; ];
if let Some(unified) = compound1.unify(compound2) { if let Some(unified) = compound_one.unify(compound_two) {
choices.push(vec![ choices.push(vec![
ComplexSelectorComponent::Compound(unified), ComplexSelectorComponent::Compound(unified),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling), ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
@ -458,20 +463,20 @@ fn merge_final_combinators(
} }
(Combinator::FollowingSibling, Combinator::NextSibling) (Combinator::FollowingSibling, Combinator::NextSibling)
| (Combinator::NextSibling, Combinator::FollowingSibling) => { | (Combinator::NextSibling, Combinator::FollowingSibling) => {
let following_sibling_selector = if combinator1 == &Combinator::FollowingSibling let following_sibling_selector =
{ if combinator_one == &Combinator::FollowingSibling {
compound1.clone() compound_one.clone()
} else {
compound_two.clone()
};
let next_sibling_selector = if combinator_one == &Combinator::FollowingSibling {
compound_two.clone()
} else { } else {
compound2.clone() compound_one.clone()
}; };
let next_sibling_selector = if combinator1 == &Combinator::FollowingSibling { if following_sibling_selector.is_super_selector(&next_sibling_selector, &None) {
compound2.clone()
} else {
compound1.clone()
};
if following_sibling_selector.is_super_selector(&next_sibling_selector, None) {
result.push_front(vec![vec![ result.push_front(vec![vec![
ComplexSelectorComponent::Compound(next_sibling_selector), ComplexSelectorComponent::Compound(next_sibling_selector),
ComplexSelectorComponent::Combinator(Combinator::NextSibling), ComplexSelectorComponent::Combinator(Combinator::NextSibling),
@ -484,7 +489,7 @@ fn merge_final_combinators(
ComplexSelectorComponent::Combinator(Combinator::NextSibling), ComplexSelectorComponent::Combinator(Combinator::NextSibling),
]]; ]];
if let Some(unified) = compound1.unify(compound2) { if let Some(unified) = compound_one.unify(compound_two) {
v.push(vec![ v.push(vec![
ComplexSelectorComponent::Compound(unified), ComplexSelectorComponent::Compound(unified),
ComplexSelectorComponent::Combinator(Combinator::NextSibling), ComplexSelectorComponent::Combinator(Combinator::NextSibling),
@ -496,81 +501,83 @@ fn merge_final_combinators(
(Combinator::Child, Combinator::NextSibling) (Combinator::Child, Combinator::NextSibling)
| (Combinator::Child, Combinator::FollowingSibling) => { | (Combinator::Child, Combinator::FollowingSibling) => {
result.push_front(vec![vec![ result.push_front(vec![vec![
ComplexSelectorComponent::Compound(compound2), ComplexSelectorComponent::Compound(compound_two),
ComplexSelectorComponent::Combinator(*combinator2), ComplexSelectorComponent::Combinator(*combinator_two),
]]); ]]);
components1.push_back(ComplexSelectorComponent::Compound(compound1)); components_one.push_back(ComplexSelectorComponent::Compound(compound_one));
components1.push_back(ComplexSelectorComponent::Combinator(Combinator::Child)); components_one
.push_back(ComplexSelectorComponent::Combinator(Combinator::Child));
} }
(Combinator::NextSibling, Combinator::Child) (Combinator::NextSibling, Combinator::Child)
| (Combinator::FollowingSibling, Combinator::Child) => { | (Combinator::FollowingSibling, Combinator::Child) => {
result.push_front(vec![vec![ result.push_front(vec![vec![
ComplexSelectorComponent::Compound(compound1), ComplexSelectorComponent::Compound(compound_one),
ComplexSelectorComponent::Combinator(*combinator1), ComplexSelectorComponent::Combinator(*combinator_one),
]]); ]]);
components2.push_back(ComplexSelectorComponent::Compound(compound2)); components_two.push_back(ComplexSelectorComponent::Compound(compound_two));
components2.push_back(ComplexSelectorComponent::Combinator(Combinator::Child)); components_two
.push_back(ComplexSelectorComponent::Combinator(Combinator::Child));
} }
(..) => { (..) => {
if combinator1 != combinator2 { if combinator_one != combinator_two {
return None; return None;
} }
let unified = compound1.unify(compound2)?; let unified = compound_one.unify(compound_two)?;
result.push_front(vec![vec![ result.push_front(vec![vec![
ComplexSelectorComponent::Compound(unified), ComplexSelectorComponent::Compound(unified),
ComplexSelectorComponent::Combinator(*combinator1), ComplexSelectorComponent::Combinator(*combinator_one),
]]); ]]);
} }
} }
merge_final_combinators(components1, components2, Some(result)) merge_final_combinators(components_one, components_two, Some(result))
} }
(Some(combinator1), None) => { (Some(combinator_one), None) => {
if *combinator1 == Combinator::Child && !components2.is_empty() { if *combinator_one == Combinator::Child && !components_two.is_empty() {
if let Some(ComplexSelectorComponent::Compound(c1)) = if let Some(ComplexSelectorComponent::Compound(c1)) =
components1.get(components1.len() - 1) components_one.get(components_one.len() - 1)
{ {
if let Some(ComplexSelectorComponent::Compound(c2)) = if let Some(ComplexSelectorComponent::Compound(c2)) =
components2.get(components2.len() - 1) components_two.get(components_two.len() - 1)
{ {
if c2.is_super_selector(c1, None) { if c2.is_super_selector(c1, &None) {
components2.pop_back(); components_two.pop_back();
} }
} }
} }
} }
result.push_front(vec![vec![ result.push_front(vec![vec![
components1.pop_back().unwrap(), components_one.pop_back().unwrap(),
ComplexSelectorComponent::Combinator(*combinator1), ComplexSelectorComponent::Combinator(*combinator_one),
]]); ]]);
merge_final_combinators(components1, components2, Some(result)) merge_final_combinators(components_one, components_two, Some(result))
} }
(None, Some(combinator2)) => { (None, Some(combinator_two)) => {
if *combinator2 == Combinator::Child && !components1.is_empty() { if *combinator_two == Combinator::Child && !components_one.is_empty() {
if let Some(ComplexSelectorComponent::Compound(c1)) = if let Some(ComplexSelectorComponent::Compound(c1)) =
components1.get(components1.len() - 1) components_one.get(components_one.len() - 1)
{ {
if let Some(ComplexSelectorComponent::Compound(c2)) = if let Some(ComplexSelectorComponent::Compound(c2)) =
components2.get(components2.len() - 1) components_two.get(components_two.len() - 1)
{ {
if c1.is_super_selector(c2, None) { if c1.is_super_selector(c2, &None) {
components1.pop_back(); components_one.pop_back();
} }
} }
} }
} }
result.push_front(vec![vec![ result.push_front(vec![vec![
components2.pop_back().unwrap(), components_two.pop_back().unwrap(),
ComplexSelectorComponent::Combinator(*combinator2), ComplexSelectorComponent::Combinator(*combinator_two),
]]); ]]);
merge_final_combinators(components1, components2, Some(result)) merge_final_combinators(components_one, components_two, Some(result))
} }
(None, None) => todo!("the above, but we dont have access to combinator2"), (None, None) => todo!("the above, but we dont have access to combinator_two"),
} }
} }
@ -586,7 +593,7 @@ fn first_if_root(queue: &mut VecDeque<ComplexSelectorComponent>) -> Option<Compo
} }
let compound = c.clone(); let compound = c.clone();
queue.pop_front(); queue.pop_front();
return Some(compound); Some(compound)
} else { } else {
None None
} }
@ -623,8 +630,12 @@ fn group_selectors(
groups.push_back(group.clone()); groups.push_back(group.clone());
while let Some(c) = iter.next() { for c in iter {
if group.last().map_or(false, |g| g.is_combinator()) || c.is_combinator() { if group
.last()
.map_or(false, ComplexSelectorComponent::is_combinator)
|| c.is_combinator()
{
group.push(c); group.push(c);
} else { } else {
group = vec![c]; group = vec![c];
@ -635,79 +646,79 @@ fn group_selectors(
groups groups
} }
/// Returns all orderings of initial subseqeuences of `queue1` and `queue2`. /// Returns all orderings of initial subseqeuences of `queue_one` and `queue_two`.
/// ///
/// The `done` callback is used to determine the extent of the initial /// The `done` callback is used to determine the extent of the initial
/// subsequences. It's called with each queue until it returns `true`. /// subsequences. It's called with each queue until it returns `true`.
/// ///
/// This destructively removes the initial subsequences of `queue1` and /// This destructively removes the initial subsequences of `queue_one` and
/// `queue2`. /// `queue_two`.
/// ///
/// For example, given `(A B C | D E)` and `(1 2 | 3 4 5)` (with `|` denoting /// For example, given `(A B C | D E)` and `(1 2 | 3 4 5)` (with `|` denoting
/// the boundary of the initial subsequence), this would return `[(A B C 1 2), /// the boundary of the initial subsequence), this would return `[(A B C 1 2),
/// (1 2 A B C)]`. The queues would then contain `(D E)` and `(3 4 5)`. /// (1 2 A B C)]`. The queues would then contain `(D E)` and `(3 4 5)`.
fn chunks<T: Clone>( fn chunks<T: Clone>(
queue1: &mut VecDeque<T>, queue_one: &mut VecDeque<T>,
queue2: &mut VecDeque<T>, queue_two: &mut VecDeque<T>,
done: impl Fn(&VecDeque<T>) -> bool, done: impl Fn(&VecDeque<T>) -> bool,
) -> Vec<Vec<T>> { ) -> Vec<Vec<T>> {
let mut chunk1 = Vec::new(); let mut chunk_one = Vec::new();
while !done(&queue1) { while !done(queue_one) {
chunk1.push(queue1.pop_front().unwrap()); chunk_one.push(queue_one.pop_front().unwrap());
} }
let mut chunk2 = Vec::new(); let mut chunk_two = Vec::new();
while !done(&queue2) { while !done(queue_two) {
chunk2.push(queue2.pop_front().unwrap()); chunk_two.push(queue_two.pop_front().unwrap());
} }
match (chunk1.is_empty(), chunk2.is_empty()) { match (chunk_one.is_empty(), chunk_two.is_empty()) {
(true, true) => Vec::new(), (true, true) => Vec::new(),
(true, false) => vec![chunk2], (true, false) => vec![chunk_two],
(false, true) => vec![chunk1], (false, true) => vec![chunk_one],
(false, false) => { (false, false) => {
let mut l1 = chunk1.clone(); let mut l1 = chunk_one.clone();
l1.append(&mut chunk2.clone()); l1.append(&mut chunk_two.clone());
let mut l2 = chunk2.clone(); let mut l2 = chunk_two;
l2.append(&mut chunk1); l2.append(&mut chunk_one);
vec![l1, l2] vec![l1, l2]
} }
} }
} }
/// Like `complex_is_superselector`, but compares `complex1` and `complex2` as /// Like `complex_is_superselector`, but compares `complex_one` and `complex_two` as
/// though they shared an implicit base `SimpleSelector`. /// though they shared an implicit base `SimpleSelector`.
/// ///
/// For example, `B` is not normally a superselector of `B A`, since it doesn't /// For example, `B` is not normally a superselector of `B A`, since it doesn't
/// match elements that match `A`. However, it *is* a parent superselector, /// match elements that match `A`. However, it *is* a parent superselector,
/// since `B X` is a superselector of `B A X`. /// since `B X` is a superselector of `B A X`.
fn complex_is_parent_superselector( fn complex_is_parent_superselector(
mut complex1: Vec<ComplexSelectorComponent>, mut complex_one: Vec<ComplexSelectorComponent>,
mut complex2: Vec<ComplexSelectorComponent>, mut complex_two: Vec<ComplexSelectorComponent>,
) -> bool { ) -> bool {
if let Some(ComplexSelectorComponent::Combinator(..)) = complex1.first() { if let Some(ComplexSelectorComponent::Combinator(..)) = complex_one.first() {
return false; return false;
} }
if let Some(ComplexSelectorComponent::Combinator(..)) = complex2.first() { if let Some(ComplexSelectorComponent::Combinator(..)) = complex_two.first() {
return false; return false;
} }
if complex1.len() > complex2.len() { if complex_one.len() > complex_two.len() {
return false; return false;
} }
let base = CompoundSelector { let base = CompoundSelector {
components: vec![SimpleSelector::Placeholder(String::new())], components: vec![SimpleSelector::Placeholder(String::new())],
}; };
complex1.push(ComplexSelectorComponent::Compound(base.clone())); complex_one.push(ComplexSelectorComponent::Compound(base.clone()));
complex2.push(ComplexSelectorComponent::Compound(base)); complex_two.push(ComplexSelectorComponent::Compound(base));
ComplexSelector { ComplexSelector {
components: complex1, components: complex_one,
line_break: false, line_break: false,
} }
.is_super_selector(&ComplexSelector { .is_super_selector(&ComplexSelector {
components: complex2, components: complex_two,
line_break: false, line_break: false,
}) })
} }
@ -736,19 +747,19 @@ fn paths<T: Clone + std::fmt::Debug>(choices: Vec<Vec<T>>) -> Vec<Vec<T>> {
}) })
} }
/// Returns whether `complex1` and `complex2` need to be unified to produce a /// Returns whether `complex_one` and `complex_two` need to be unified to produce a
/// valid combined selector. /// valid combined selector.
/// ///
/// This is necessary when both selectors contain the same unique simple /// This is necessary when both selectors contain the same unique simple
/// selector, such as an ID. /// selector, such as an ID.
fn must_unify( fn must_unify(
complex1: Vec<ComplexSelectorComponent>, complex_one: &[ComplexSelectorComponent],
complex2: Vec<ComplexSelectorComponent>, complex_two: &[ComplexSelectorComponent],
) -> bool { ) -> bool {
let mut unique_selectors = Vec::new(); let mut unique_selectors = Vec::new();
for component in complex1 { for component in complex_one {
if let ComplexSelectorComponent::Compound(c) = component { if let ComplexSelectorComponent::Compound(c) = component {
unique_selectors.extend(c.components.into_iter().filter(|f| is_unique(f))); unique_selectors.extend(c.components.iter().filter(|f| is_unique(f)));
} }
} }
@ -756,12 +767,12 @@ fn must_unify(
return false; return false;
} }
complex2.iter().any(|component| { complex_two.iter().any(|component| {
if let ComplexSelectorComponent::Compound(compound) = component { if let ComplexSelectorComponent::Compound(compound) = component {
compound compound
.components .components
.iter() .iter()
.any(|simple| is_unique(simple) && unique_selectors.contains(simple)) .any(|simple| is_unique(simple) && unique_selectors.contains(&simple))
} else { } else {
false false
} }

View File

@ -47,14 +47,16 @@ impl fmt::Display for SelectorList {
impl SelectorList { impl SelectorList {
pub fn is_invisible(&self) -> bool { pub fn is_invisible(&self) -> bool {
self.components.iter().all(|c| c.is_invisible()) self.components.iter().all(ComplexSelector::is_invisible)
} }
pub fn contains_parent_selector(&self) -> bool { pub fn contains_parent_selector(&self) -> bool {
self.components.iter().any(|c| c.contains_parent_selector()) self.components
.iter()
.any(ComplexSelector::contains_parent_selector)
} }
pub fn new() -> Self { pub const fn new() -> Self {
Self { Self {
components: Vec::new(), components: Vec::new(),
} }
@ -64,7 +66,7 @@ impl SelectorList {
self.components.is_empty() self.components.is_empty()
} }
/// Returns a SassScript list that represents this selector. /// Returns a `SassScript` list that represents this selector.
/// ///
/// This has the same format as a list returned by `selector-parse()`. /// This has the same format as a list returned by `selector-parse()`.
pub fn to_sass_list(self) -> Value { pub fn to_sass_list(self) -> Value {
@ -94,7 +96,7 @@ impl SelectorList {
/// both this and `other`. /// both this and `other`.
/// ///
/// If no such list can be produced, returns `None`. /// If no such list can be produced, returns `None`.
pub fn unify(self, other: Self) -> Option<Self> { pub fn unify(self, other: &Self) -> Option<Self> {
let contents: Vec<ComplexSelector> = self let contents: Vec<ComplexSelector> = self
.components .components
.into_iter() .into_iter()
@ -181,7 +183,7 @@ impl SelectorList {
{ {
Some(r) => r, Some(r) => r,
None => { None => {
for new_complex in new_complexes.iter_mut() { for new_complex in &mut new_complexes {
new_complex.push(component.clone()); new_complex.push(component.clone());
} }
continue; continue;
@ -191,10 +193,9 @@ impl SelectorList {
let previous_complexes = mem::take(&mut new_complexes); let previous_complexes = mem::take(&mut new_complexes);
let previous_line_breaks = mem::take(&mut line_breaks); let previous_line_breaks = mem::take(&mut line_breaks);
let mut i = 0; for (i, new_complex) in previous_complexes.into_iter().enumerate() {
for new_complex in previous_complexes { // todo: use .get(i)
let line_break = previous_line_breaks[i]; let line_break = previous_line_breaks[i];
i += 1;
for mut resolved_complex in resolved.clone() { for mut resolved_complex in resolved.clone() {
let mut new_this_complex = new_complex.clone(); let mut new_this_complex = new_complex.clone();
new_this_complex.append(&mut resolved_complex.components); new_this_complex.append(&mut resolved_complex.components);
@ -203,14 +204,14 @@ impl SelectorList {
} }
} }
} else { } else {
for new_complex in new_complexes.iter_mut() { for new_complex in &mut new_complexes {
new_complex.push(component.clone()); new_complex.push(component.clone());
} }
} }
} }
let mut i = 0; let mut i = 0;
return new_complexes new_complexes
.into_iter() .into_iter()
.map(|new_complex| { .map(|new_complex| {
i += 1; i += 1;
@ -219,7 +220,7 @@ impl SelectorList {
line_break: line_breaks[i - 1], line_break: line_breaks[i - 1],
} }
}) })
.collect(); .collect()
}) })
.collect(), .collect(),
), ),
@ -236,15 +237,12 @@ impl SelectorList {
} }
fn flatten_vertically<A: std::fmt::Debug>(iterable: Vec<Vec<A>>) -> Vec<A> { fn flatten_vertically<A: std::fmt::Debug>(iterable: Vec<Vec<A>>) -> Vec<A> {
let mut queues: Vec<VecDeque<A>> = iterable let mut queues: Vec<VecDeque<A>> = iterable.into_iter().map(VecDeque::from).collect();
.into_iter()
.map(|inner| VecDeque::from(inner))
.collect();
let mut result = Vec::new(); let mut result = Vec::new();
while !queues.is_empty() { while !queues.is_empty() {
for queue in queues.iter_mut() { for queue in &mut queues {
if queue.is_empty() { if queue.is_empty() {
continue; continue;
} }

View File

@ -112,6 +112,7 @@ impl Selector {
)) ))
} }
#[allow(clippy::needless_pass_by_value)]
pub fn replace(super_selector: &Selector, this: Selector) -> Selector { pub fn replace(super_selector: &Selector, this: Selector) -> Selector {
todo!() todo!()
} }
@ -153,7 +154,7 @@ impl Selector {
self.0.is_empty() self.0.is_empty()
} }
pub fn new() -> Selector { pub const fn new() -> Selector {
Selector(SelectorList::new()) Selector(SelectorList::new())
} }
@ -161,7 +162,7 @@ impl Selector {
self.0.to_sass_list() self.0.to_sass_list()
} }
pub fn unify(self, other: Self) -> Option<Self> { pub fn unify(self, other: &Self) -> Option<Self> {
Some(Selector(self.0.unify(other.0)?)) Some(Selector(self.0.unify(&other.0)?))
} }
} }

View File

@ -38,7 +38,7 @@ impl DevouredWhitespace {
} }
/// Pseudo-class selectors that take unadorned selectors as arguments. /// Pseudo-class selectors that take unadorned selectors as arguments.
const SELECTOR_PSEUDO_CLASSES: [&'static str; 7] = [ const SELECTOR_PSEUDO_CLASSES: [&str; 7] = [
"not", "not",
"matches", "matches",
"current", "current",
@ -49,7 +49,7 @@ const SELECTOR_PSEUDO_CLASSES: [&'static str; 7] = [
]; ];
/// Pseudo-element selectors that take unadorned selectors as arguments. /// Pseudo-element selectors that take unadorned selectors as arguments.
const SELECTOR_PSEUDO_ELEMENTS: [&'static str; 1] = ["slotted"]; const SELECTOR_PSEUDO_ELEMENTS: [&str; 1] = ["slotted"];
pub(crate) struct SelectorParser<'a, I: Iterator<Item = Token>> { pub(crate) struct SelectorParser<'a, I: Iterator<Item = Token>> {
/// Whether this parser allows the parent selector `&`. /// Whether this parser allows the parent selector `&`.
@ -114,7 +114,7 @@ impl<'a, I: Iterator<Item = Token>> SelectorParser<'a, I> {
line_break = false; line_break = false;
} }
return Ok(SelectorList { components }); Ok(SelectorList { components })
} }
fn eat_whitespace(&mut self) -> DevouredWhitespace { fn eat_whitespace(&mut self) -> DevouredWhitespace {
@ -344,6 +344,7 @@ impl<'a, I: Iterator<Item = Token>> SelectorParser<'a, I> {
} else if unvendored == "nth-child" || unvendored == "nth-last-child" { } else if unvendored == "nth-child" || unvendored == "nth-last-child" {
let mut this_arg = self.parse_a_n_plus_b()?; let mut this_arg = self.parse_a_n_plus_b()?;
let found_whitespace = devour_whitespace(self.toks); let found_whitespace = devour_whitespace(self.toks);
#[allow(clippy::match_same_arms)]
match (found_whitespace, self.toks.peek()) { match (found_whitespace, self.toks.peek()) {
(_, Some(Token { kind: ')', .. })) => {} (_, Some(Token { kind: ')', .. })) => {}
(true, _) => { (true, _) => {
@ -507,7 +508,9 @@ impl<'a, I: Iterator<Item = Token>> SelectorParser<'a, I> {
devour_whitespace(self.toks); devour_whitespace(self.toks);
if let Some(t @ Token { kind: '+', .. }) | Some(t @ Token { kind: '-', .. }) = self.toks.peek() { if let Some(t @ Token { kind: '+', .. }) | Some(t @ Token { kind: '-', .. }) =
self.toks.peek()
{
buf.push(t.kind); buf.push(t.kind);
self.toks.next(); self.toks.next();
devour_whitespace(self.toks); devour_whitespace(self.toks);
@ -516,7 +519,7 @@ impl<'a, I: Iterator<Item = Token>> SelectorParser<'a, I> {
return Err(("Expected a number.", self.span).into()) return Err(("Expected a number.", self.span).into())
} }
None => return Err(("Expected a number.", self.span).into()), None => return Err(("Expected a number.", self.span).into()),
_ => {} Some(..) => {}
} }
while let Some(t) = self.toks.peek() { while let Some(t) = self.toks.peek() {
@ -575,7 +578,7 @@ fn unvendor(name: &str) -> &str {
return name; return name;
} }
if bytes[0usize] != b'-' || bytes[1usize] == b'-' { if bytes[0_usize] != b'-' || bytes[1_usize] == b'-' {
return name; return name;
} }

View File

@ -5,7 +5,7 @@ use super::{
QualifiedName, SelectorList, QualifiedName, SelectorList,
}; };
const SUBSELECTOR_PSEUDOS: [&'static str; 4] = ["matches", "any", "nth-child", "nth-last-child"]; const SUBSELECTOR_PSEUDOS: [&str; 4] = ["matches", "any", "nth-child", "nth-last-child"];
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) enum SimpleSelector { pub(crate) enum SimpleSelector {
@ -85,7 +85,7 @@ impl SimpleSelector {
Self::Universal(..) => 0, Self::Universal(..) => 0,
Self::Type(..) => 1, Self::Type(..) => 1,
Self::Pseudo { .. } => todo!(), Self::Pseudo { .. } => todo!(),
Self::Id(..) => 1000u32.pow(2u32), Self::Id(..) => 1000_u32.pow(2_u32),
_ => 1000, _ => 1000,
} }
} }
@ -109,7 +109,7 @@ impl SimpleSelector {
| Self::Class(..) | Self::Class(..)
| Self::Attribute(..) => false, | Self::Attribute(..) => false,
Self::Pseudo(Pseudo { name, selector, .. }) => { Self::Pseudo(Pseudo { name, selector, .. }) => {
name != "not" && selector.as_ref().map_or(false, |s| s.is_invisible()) name != "not" && selector.as_ref().map_or(false, SelectorList::is_invisible)
} }
Self::Placeholder(..) => true, Self::Placeholder(..) => true,
Self::Parent(..) => todo!(), Self::Parent(..) => todo!(),
@ -119,14 +119,16 @@ impl SimpleSelector {
pub fn add_suffix(&mut self, suffix: &str) { pub fn add_suffix(&mut self, suffix: &str) {
match self { match self {
Self::Type(name) => name.ident.push_str(suffix), Self::Type(name) => name.ident.push_str(suffix),
Self::Pseudo(Pseudo { Self::Placeholder(name)
| Self::Id(name)
| Self::Class(name)
| Self::Pseudo(Pseudo {
name, name,
argument: None, argument: None,
selector: None, selector: None,
.. ..
}) => name.push_str(suffix), }) => name.push_str(suffix),
Self::Placeholder(name) | Self::Id(name) | Self::Class(name) => name.push_str(suffix), _ => todo!(),
Self::Universal(..) | _ => todo!(),
} }
} }
@ -196,7 +198,7 @@ impl SimpleSelector {
} }
if !added_this { if !added_this {
result.push(self.clone()); result.push(self);
} }
Some(result) Some(result)
@ -348,13 +350,13 @@ impl SimpleSelector {
if complex.components.len() != 1 { if complex.components.len() != 1 {
return false; return false;
}; };
return complex complex
.components .components
.get(0) .get(0)
.unwrap() .unwrap()
.as_compound() .as_compound()
.components .components
.contains(self); .contains(self)
}); });
} }
false false

View File

@ -422,7 +422,7 @@ impl<'a> StyleSheetParser<'a> {
Expr::Selector(s) => { Expr::Selector(s) => {
self.nesting += 1; self.nesting += 1;
let rules = let rules =
self.eat_rules(&s.resolve_parent_selectors(&super_selector, true), scope)?; self.eat_rules(&s.resolve_parent_selectors(super_selector, true), scope)?;
stmts.push(Spanned { stmts.push(Spanned {
node: Stmt::RuleSet(RuleSet { node: Stmt::RuleSet(RuleSet {
super_selector: super_selector.clone(), super_selector: super_selector.clone(),