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) => {
let rules = self.eval(
&selector.resolve_parent_selectors(&super_selector, true),
&selector.resolve_parent_selectors(super_selector, true),
content,
)?;
stmts.push(Spanned {

View File

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

View File

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

View File

@ -47,7 +47,7 @@ impl Color {
}
}
fn new_hsla(
const fn new_hsla(
red: Number,
green: 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 {
kind: SassErrorKind::ParseError { message, loc },
}

View File

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

View File

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

View File

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

View File

@ -1,3 +1,5 @@
#![allow(clippy::similar_names)]
use std::collections::VecDeque;
use super::{
@ -5,7 +7,7 @@ use super::{
};
/// 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`.
pub(crate) fn unify_complex(
@ -74,7 +76,7 @@ fn weave(complexes: Vec<Vec<ComplexSelectorComponent>>) -> Vec<Vec<ComplexSelect
let target = complex.last().unwrap().clone();
if complex.len() == 1 {
for prefix in prefixes.iter_mut() {
for prefix in &mut prefixes {
prefix.push(target.clone());
}
continue;
@ -94,8 +96,6 @@ fn weave(complexes: Vec<Vec<ComplexSelectorComponent>>) -> Vec<Vec<ComplexSelect
parent_prefix.push(target.clone());
new_prefixes.push(parent_prefix);
}
} else {
continue;
}
}
prefixes = new_prefixes;
@ -104,7 +104,7 @@ fn weave(complexes: Vec<Vec<ComplexSelectorComponent>>) -> Vec<Vec<ComplexSelect
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
/// 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
/// the output.
fn weave_parents(
parents1: Vec<ComplexSelectorComponent>,
parents2: Vec<ComplexSelectorComponent>,
parents_one: Vec<ComplexSelectorComponent>,
parents_two: Vec<ComplexSelectorComponent>,
) -> Option<Vec<Vec<ComplexSelectorComponent>>> {
let mut queue1 = VecDeque::from(parents1);
let mut queue2 = VecDeque::from(parents2);
let mut queue_one = VecDeque::from(parents_one);
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)) {
(Some(root1), Some(root2)) => {
let root = ComplexSelectorComponent::Compound(root1.unify(root2)?);
queue1.push_front(root.clone());
queue2.push_front(root);
match (first_if_root(&mut queue_one), first_if_root(&mut queue_two)) {
(Some(root_one), Some(root_two)) => {
let root = ComplexSelectorComponent::Compound(root_one.unify(root_two)?);
queue_one.push_front(root.clone());
queue_two.push_front(root);
}
(Some(root1), None) => {
queue2.push_front(ComplexSelectorComponent::Compound(root1));
(Some(root_one), None) => {
queue_two.push_front(ComplexSelectorComponent::Compound(root_one));
}
(None, Some(root2)) => {
queue1.push_front(ComplexSelectorComponent::Compound(root2));
(None, Some(root_two)) => {
queue_one.push_front(ComplexSelectorComponent::Compound(root_two));
}
(None, None) => {}
}
let mut groups1 = group_selectors(Vec::from(queue1));
let mut groups2 = group_selectors(Vec::from(queue2));
let mut groups_one = group_selectors(Vec::from(queue_one));
let mut groups_two = group_selectors(Vec::from(queue_two));
let lcs = longest_common_subsequence(
Vec::from(groups2.clone()),
Vec::from(groups1.clone()),
Some(&|group1, group2| {
if group1 == group2 {
return Some(group1);
groups_two.as_slices().0,
groups_one.as_slices().0,
Some(&|group_one, group_two| {
if group_one == group_two {
return Some(group_one);
}
if let ComplexSelectorComponent::Combinator(..) = group1.first()? {
if let ComplexSelectorComponent::Combinator(..) = group_one.first()? {
return None;
}
if let ComplexSelectorComponent::Combinator(..) = group2.first()? {
if let ComplexSelectorComponent::Combinator(..) = group_two.first()? {
return None;
}
if complex_is_parent_superselector(group1.clone(), group2.clone()) {
return Some(group2);
if complex_is_parent_superselector(group_one.clone(), group_two.clone()) {
return Some(group_two);
}
if complex_is_parent_superselector(group2.clone(), group1.clone()) {
return Some(group1);
if complex_is_parent_superselector(group_two.clone(), group_one.clone()) {
return Some(group_one);
}
if !must_unify(group1.clone(), group2.clone()) {
if !must_unify(&group_one, &group_two) {
return None;
}
let unified = unify_complex(vec![group1, group2])?;
let unified = unify_complex(vec![group_one, group_two])?;
if unified.len() > 1 {
return None;
}
@ -188,7 +188,7 @@ fn weave_parents(
for group in lcs {
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())
})
.into_iter()
@ -196,12 +196,12 @@ fn weave_parents(
.collect(),
);
choices.push(vec![group]);
groups1.pop_front();
groups2.pop_front();
groups_one.pop_front();
groups_two.pop_front();
}
choices.push(
chunks(&mut groups1, &mut groups2, |sequence| sequence.is_empty())
chunks(&mut groups_one, &mut groups_two, VecDeque::is_empty)
.into_iter()
.map(|chunk| chunk.into_iter().flatten().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.
///
/// If there are no combinators to be merged, returns an empty list. If the
/// combinators can't be merged, returns `None`.
fn merge_initial_combinators(
components1: &mut VecDeque<ComplexSelectorComponent>,
components2: &mut VecDeque<ComplexSelectorComponent>,
components_one: &mut VecDeque<ComplexSelectorComponent>,
components_two: &mut VecDeque<ComplexSelectorComponent>,
) -> 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) {
combinators1.push(*c);
components1.pop_front();
while let Some(ComplexSelectorComponent::Combinator(c)) = components_one.get(0) {
combinators_one.push(*c);
components_one.pop_front();
}
let mut combinators2 = Vec::new();
let mut combinators_two = Vec::new();
while let Some(ComplexSelectorComponent::Combinator(c)) = components2.get(0) {
combinators2.push(*c);
components2.pop_front();
while let Some(ComplexSelectorComponent::Combinator(c)) = components_two.get(0) {
combinators_two.push(*c);
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 {
Some(combinators2)
} else if lcs == combinators2 {
Some(combinators1)
if lcs == combinators_one {
Some(combinators_two)
} else if lcs == combinators_two {
Some(combinators_one)
} else {
// If neither sequence of combinators is a subsequence of the other, they
// 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
/// 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
/// list. If it returns `None`, the elements are considered unequal; otherwise,
/// 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>(
list1: Vec<T>,
list2: Vec<T>,
list_one: &[T],
list_two: &[T],
select: Option<&dyn Fn(T, T) -> Option<T>>,
) -> Vec<T> {
let select = select.unwrap_or(&|element1, element2| {
if element1 == element2 {
Some(element1)
let select = select.unwrap_or(&|element_one, element_two| {
if element_one == element_two {
Some(element_one)
} else {
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 j in 0..list2.len() {
let selection = select(list1.get(i).unwrap().clone(), list2.get(j).unwrap().clone());
for i in 0..list_one.len() {
for j in 0..list_two.len() {
let selection = select(
list_one.get(i).unwrap().clone(),
list_two.get(j).unwrap().clone(),
);
selections[i][j] = selection.clone();
lengths[i + 1][j + 1] = if selection.is_none() {
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(
list1.len() as isize - 1,
list2.len() as isize - 1,
(list_one.len() as isize).saturating_sub(1),
(list_two.len() as isize).saturating_sub(1),
lengths,
&mut selections,
)
}
/// 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
/// sequences can't be merged, returns `None`.
#[allow(clippy::cognitive_complexity)]
fn merge_final_combinators(
components1: &mut VecDeque<ComplexSelectorComponent>,
components2: &mut VecDeque<ComplexSelectorComponent>,
components_one: &mut VecDeque<ComplexSelectorComponent>,
components_two: &mut VecDeque<ComplexSelectorComponent>,
result: Option<VecDeque<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()
|| !components1
.get(components1.len() - 1)
if (components_one.is_empty()
|| !components_one
.get(components_one.len() - 1)
.unwrap()
.is_combinator())
&& (components2.is_empty()
|| !components2
.get(components2.len() - 1)
&& (components_two.is_empty()
|| !components_two
.get(components_two.len() - 1)
.unwrap()
.is_combinator())
{
return Some(Vec::from(result));
}
let mut combinators1 = Vec::new();
let mut combinators_one = Vec::new();
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);
components1.pop_back();
combinators_one.push(*combinator);
components_one.pop_back();
}
let mut combinators2 = Vec::new();
let mut combinators_two = Vec::new();
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);
components2.pop_back();
combinators_two.push(*combinator);
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
// is a supersequence of the other, use that, otherwise give up.
let lcs = longest_common_subsequence(combinators1.clone(), combinators2.clone(), None);
if lcs == combinators1 {
result.push_front(vec![combinators2
let lcs = longest_common_subsequence(&combinators_one, &combinators_two, None);
if lcs == combinators_one {
result.push_front(vec![combinators_two
.into_iter()
.map(ComplexSelectorComponent::Combinator)
.rev()
.collect()]);
} else if lcs == combinators2 {
result.push_front(vec![combinators1
} else if lcs == combinators_two {
result.push_front(vec![combinators_one
.into_iter()
.map(ComplexSelectorComponent::Combinator)
.rev()
@ -393,60 +398,60 @@ fn merge_final_combinators(
return Some(Vec::from(result));
}
let combinator1 = if combinators1.is_empty() {
let combinator_one = if combinators_one.is_empty() {
None
} else {
combinators1.first()
combinators_one.first()
};
let combinator2 = if combinators2.is_empty() {
let combinator_two = if combinators_two.is_empty() {
None
} else {
combinators2.first()
combinators_two.first()
};
// This code looks complicated, but it's actually just a bunch of special
// cases for interactions between different combinators.
match (combinator1, combinator2) {
(Some(combinator1), Some(combinator2)) => {
let compound1 = match components1.pop_back() {
match (combinator_one, combinator_two) {
(Some(combinator_one), Some(combinator_two)) => {
let compound_one = match components_one.pop_back() {
Some(ComplexSelectorComponent::Compound(c)) => c,
Some(..) | None => unreachable!(),
};
let compound2 = match components2.pop_back() {
let compound_two = match components_two.pop_back() {
Some(ComplexSelectorComponent::Compound(c)) => c,
Some(..) | None => unreachable!(),
};
match (combinator1, combinator2) {
match (combinator_one, combinator_two) {
(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![
ComplexSelectorComponent::Compound(compound2),
ComplexSelectorComponent::Compound(compound_two),
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![
ComplexSelectorComponent::Compound(compound1),
ComplexSelectorComponent::Compound(compound_one),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
]])
} else {
let mut choices = vec![
vec![
ComplexSelectorComponent::Compound(compound1.clone()),
ComplexSelectorComponent::Compound(compound_one.clone()),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
ComplexSelectorComponent::Compound(compound2.clone()),
ComplexSelectorComponent::Compound(compound_two.clone()),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
],
vec![
ComplexSelectorComponent::Compound(compound2.clone()),
ComplexSelectorComponent::Compound(compound_two.clone()),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
ComplexSelectorComponent::Compound(compound1.clone()),
ComplexSelectorComponent::Compound(compound_one.clone()),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
],
];
if let Some(unified) = compound1.unify(compound2) {
if let Some(unified) = compound_one.unify(compound_two) {
choices.push(vec![
ComplexSelectorComponent::Compound(unified),
ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
@ -458,20 +463,20 @@ fn merge_final_combinators(
}
(Combinator::FollowingSibling, Combinator::NextSibling)
| (Combinator::NextSibling, Combinator::FollowingSibling) => {
let following_sibling_selector = if combinator1 == &Combinator::FollowingSibling
{
compound1.clone()
let following_sibling_selector =
if combinator_one == &Combinator::FollowingSibling {
compound_one.clone()
} else {
compound_two.clone()
};
let next_sibling_selector = if combinator_one == &Combinator::FollowingSibling {
compound_two.clone()
} else {
compound2.clone()
compound_one.clone()
};
let next_sibling_selector = if combinator1 == &Combinator::FollowingSibling {
compound2.clone()
} else {
compound1.clone()
};
if following_sibling_selector.is_super_selector(&next_sibling_selector, None) {
if following_sibling_selector.is_super_selector(&next_sibling_selector, &None) {
result.push_front(vec![vec![
ComplexSelectorComponent::Compound(next_sibling_selector),
ComplexSelectorComponent::Combinator(Combinator::NextSibling),
@ -484,7 +489,7 @@ fn merge_final_combinators(
ComplexSelectorComponent::Combinator(Combinator::NextSibling),
]];
if let Some(unified) = compound1.unify(compound2) {
if let Some(unified) = compound_one.unify(compound_two) {
v.push(vec![
ComplexSelectorComponent::Compound(unified),
ComplexSelectorComponent::Combinator(Combinator::NextSibling),
@ -496,81 +501,83 @@ fn merge_final_combinators(
(Combinator::Child, Combinator::NextSibling)
| (Combinator::Child, Combinator::FollowingSibling) => {
result.push_front(vec![vec![
ComplexSelectorComponent::Compound(compound2),
ComplexSelectorComponent::Combinator(*combinator2),
ComplexSelectorComponent::Compound(compound_two),
ComplexSelectorComponent::Combinator(*combinator_two),
]]);
components1.push_back(ComplexSelectorComponent::Compound(compound1));
components1.push_back(ComplexSelectorComponent::Combinator(Combinator::Child));
components_one.push_back(ComplexSelectorComponent::Compound(compound_one));
components_one
.push_back(ComplexSelectorComponent::Combinator(Combinator::Child));
}
(Combinator::NextSibling, Combinator::Child)
| (Combinator::FollowingSibling, Combinator::Child) => {
result.push_front(vec![vec![
ComplexSelectorComponent::Compound(compound1),
ComplexSelectorComponent::Combinator(*combinator1),
ComplexSelectorComponent::Compound(compound_one),
ComplexSelectorComponent::Combinator(*combinator_one),
]]);
components2.push_back(ComplexSelectorComponent::Compound(compound2));
components2.push_back(ComplexSelectorComponent::Combinator(Combinator::Child));
components_two.push_back(ComplexSelectorComponent::Compound(compound_two));
components_two
.push_back(ComplexSelectorComponent::Combinator(Combinator::Child));
}
(..) => {
if combinator1 != combinator2 {
if combinator_one != combinator_two {
return None;
}
let unified = compound1.unify(compound2)?;
let unified = compound_one.unify(compound_two)?;
result.push_front(vec![vec![
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) => {
if *combinator1 == Combinator::Child && !components2.is_empty() {
(Some(combinator_one), None) => {
if *combinator_one == Combinator::Child && !components_two.is_empty() {
if let Some(ComplexSelectorComponent::Compound(c1)) =
components1.get(components1.len() - 1)
components_one.get(components_one.len() - 1)
{
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) {
components2.pop_back();
if c2.is_super_selector(c1, &None) {
components_two.pop_back();
}
}
}
}
result.push_front(vec![vec![
components1.pop_back().unwrap(),
ComplexSelectorComponent::Combinator(*combinator1),
components_one.pop_back().unwrap(),
ComplexSelectorComponent::Combinator(*combinator_one),
]]);
merge_final_combinators(components1, components2, Some(result))
merge_final_combinators(components_one, components_two, Some(result))
}
(None, Some(combinator2)) => {
if *combinator2 == Combinator::Child && !components1.is_empty() {
(None, Some(combinator_two)) => {
if *combinator_two == Combinator::Child && !components_one.is_empty() {
if let Some(ComplexSelectorComponent::Compound(c1)) =
components1.get(components1.len() - 1)
components_one.get(components_one.len() - 1)
{
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) {
components1.pop_back();
if c1.is_super_selector(c2, &None) {
components_one.pop_back();
}
}
}
}
result.push_front(vec![vec![
components2.pop_back().unwrap(),
ComplexSelectorComponent::Combinator(*combinator2),
components_two.pop_back().unwrap(),
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();
queue.pop_front();
return Some(compound);
Some(compound)
} else {
None
}
@ -623,8 +630,12 @@ fn group_selectors(
groups.push_back(group.clone());
while let Some(c) = iter.next() {
if group.last().map_or(false, |g| g.is_combinator()) || c.is_combinator() {
for c in iter {
if group
.last()
.map_or(false, ComplexSelectorComponent::is_combinator)
|| c.is_combinator()
{
group.push(c);
} else {
group = vec![c];
@ -635,79 +646,79 @@ fn group_selectors(
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
/// subsequences. It's called with each queue until it returns `true`.
///
/// This destructively removes the initial subsequences of `queue1` and
/// `queue2`.
/// This destructively removes the initial subsequences of `queue_one` and
/// `queue_two`.
///
/// 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),
/// (1 2 A B C)]`. The queues would then contain `(D E)` and `(3 4 5)`.
fn chunks<T: Clone>(
queue1: &mut VecDeque<T>,
queue2: &mut VecDeque<T>,
queue_one: &mut VecDeque<T>,
queue_two: &mut VecDeque<T>,
done: impl Fn(&VecDeque<T>) -> bool,
) -> Vec<Vec<T>> {
let mut chunk1 = Vec::new();
while !done(&queue1) {
chunk1.push(queue1.pop_front().unwrap());
let mut chunk_one = Vec::new();
while !done(queue_one) {
chunk_one.push(queue_one.pop_front().unwrap());
}
let mut chunk2 = Vec::new();
while !done(&queue2) {
chunk2.push(queue2.pop_front().unwrap());
let mut chunk_two = Vec::new();
while !done(queue_two) {
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, false) => vec![chunk2],
(false, true) => vec![chunk1],
(true, false) => vec![chunk_two],
(false, true) => vec![chunk_one],
(false, false) => {
let mut l1 = chunk1.clone();
l1.append(&mut chunk2.clone());
let mut l1 = chunk_one.clone();
l1.append(&mut chunk_two.clone());
let mut l2 = chunk2.clone();
l2.append(&mut chunk1);
let mut l2 = chunk_two;
l2.append(&mut chunk_one);
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`.
///
/// 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,
/// since `B X` is a superselector of `B A X`.
fn complex_is_parent_superselector(
mut complex1: Vec<ComplexSelectorComponent>,
mut complex2: Vec<ComplexSelectorComponent>,
mut complex_one: Vec<ComplexSelectorComponent>,
mut complex_two: Vec<ComplexSelectorComponent>,
) -> bool {
if let Some(ComplexSelectorComponent::Combinator(..)) = complex1.first() {
if let Some(ComplexSelectorComponent::Combinator(..)) = complex_one.first() {
return false;
}
if let Some(ComplexSelectorComponent::Combinator(..)) = complex2.first() {
if let Some(ComplexSelectorComponent::Combinator(..)) = complex_two.first() {
return false;
}
if complex1.len() > complex2.len() {
if complex_one.len() > complex_two.len() {
return false;
}
let base = CompoundSelector {
components: vec![SimpleSelector::Placeholder(String::new())],
};
complex1.push(ComplexSelectorComponent::Compound(base.clone()));
complex2.push(ComplexSelectorComponent::Compound(base));
complex_one.push(ComplexSelectorComponent::Compound(base.clone()));
complex_two.push(ComplexSelectorComponent::Compound(base));
ComplexSelector {
components: complex1,
components: complex_one,
line_break: false,
}
.is_super_selector(&ComplexSelector {
components: complex2,
components: complex_two,
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.
///
/// This is necessary when both selectors contain the same unique simple
/// selector, such as an ID.
fn must_unify(
complex1: Vec<ComplexSelectorComponent>,
complex2: Vec<ComplexSelectorComponent>,
complex_one: &[ComplexSelectorComponent],
complex_two: &[ComplexSelectorComponent],
) -> bool {
let mut unique_selectors = Vec::new();
for component in complex1 {
for component in complex_one {
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;
}
complex2.iter().any(|component| {
complex_two.iter().any(|component| {
if let ComplexSelectorComponent::Compound(compound) = component {
compound
.components
.iter()
.any(|simple| is_unique(simple) && unique_selectors.contains(simple))
.any(|simple| is_unique(simple) && unique_selectors.contains(&simple))
} else {
false
}

View File

@ -47,14 +47,16 @@ impl fmt::Display for SelectorList {
impl SelectorList {
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 {
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 {
components: Vec::new(),
}
@ -64,7 +66,7 @@ impl SelectorList {
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()`.
pub fn to_sass_list(self) -> Value {
@ -94,7 +96,7 @@ impl SelectorList {
/// both this and `other`.
///
/// 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
.components
.into_iter()
@ -181,7 +183,7 @@ impl SelectorList {
{
Some(r) => r,
None => {
for new_complex in new_complexes.iter_mut() {
for new_complex in &mut new_complexes {
new_complex.push(component.clone());
}
continue;
@ -191,10 +193,9 @@ impl SelectorList {
let previous_complexes = mem::take(&mut new_complexes);
let previous_line_breaks = mem::take(&mut line_breaks);
let mut i = 0;
for new_complex in previous_complexes {
for (i, new_complex) in previous_complexes.into_iter().enumerate() {
// todo: use .get(i)
let line_break = previous_line_breaks[i];
i += 1;
for mut resolved_complex in resolved.clone() {
let mut new_this_complex = new_complex.clone();
new_this_complex.append(&mut resolved_complex.components);
@ -203,14 +204,14 @@ impl SelectorList {
}
}
} else {
for new_complex in new_complexes.iter_mut() {
for new_complex in &mut new_complexes {
new_complex.push(component.clone());
}
}
}
let mut i = 0;
return new_complexes
new_complexes
.into_iter()
.map(|new_complex| {
i += 1;
@ -219,7 +220,7 @@ impl SelectorList {
line_break: line_breaks[i - 1],
}
})
.collect();
.collect()
})
.collect(),
),
@ -236,15 +237,12 @@ impl SelectorList {
}
fn flatten_vertically<A: std::fmt::Debug>(iterable: Vec<Vec<A>>) -> Vec<A> {
let mut queues: Vec<VecDeque<A>> = iterable
.into_iter()
.map(|inner| VecDeque::from(inner))
.collect();
let mut queues: Vec<VecDeque<A>> = iterable.into_iter().map(VecDeque::from).collect();
let mut result = Vec::new();
while !queues.is_empty() {
for queue in queues.iter_mut() {
for queue in &mut queues {
if queue.is_empty() {
continue;
}

View File

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

View File

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

View File

@ -5,7 +5,7 @@ use super::{
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)]
pub(crate) enum SimpleSelector {
@ -85,7 +85,7 @@ impl SimpleSelector {
Self::Universal(..) => 0,
Self::Type(..) => 1,
Self::Pseudo { .. } => todo!(),
Self::Id(..) => 1000u32.pow(2u32),
Self::Id(..) => 1000_u32.pow(2_u32),
_ => 1000,
}
}
@ -109,7 +109,7 @@ impl SimpleSelector {
| Self::Class(..)
| Self::Attribute(..) => false,
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::Parent(..) => todo!(),
@ -119,14 +119,16 @@ impl SimpleSelector {
pub fn add_suffix(&mut self, suffix: &str) {
match self {
Self::Type(name) => name.ident.push_str(suffix),
Self::Pseudo(Pseudo {
Self::Placeholder(name)
| Self::Id(name)
| Self::Class(name)
| Self::Pseudo(Pseudo {
name,
argument: None,
selector: None,
..
}) => name.push_str(suffix),
Self::Placeholder(name) | Self::Id(name) | Self::Class(name) => name.push_str(suffix),
Self::Universal(..) | _ => todo!(),
_ => todo!(),
}
}
@ -196,7 +198,7 @@ impl SimpleSelector {
}
if !added_this {
result.push(self.clone());
result.push(self);
}
Some(result)
@ -348,13 +350,13 @@ impl SimpleSelector {
if complex.components.len() != 1 {
return false;
};
return complex
complex
.components
.get(0)
.unwrap()
.as_compound()
.components
.contains(self);
.contains(self)
});
}
false

View File

@ -422,7 +422,7 @@ impl<'a> StyleSheetParser<'a> {
Expr::Selector(s) => {
self.nesting += 1;
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 {
node: Stmt::RuleSet(RuleSet {
super_selector: super_selector.clone(),