avoid deep recursion in extend
This commit is contained in:
parent
8ea601ee43
commit
2b72a1fc0d
@ -239,7 +239,7 @@ impl Extender {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SelectorList {
|
SelectorList {
|
||||||
components: self.trim(extended, |complex| self.originals.contains(complex)),
|
components: self.trim(extended, &|complex| self.originals.contains(complex)),
|
||||||
span: self.span,
|
span: self.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,10 +273,12 @@ impl Extender {
|
|||||||
|
|
||||||
let complex_has_line_break = complex.line_break;
|
let complex_has_line_break = complex.line_break;
|
||||||
|
|
||||||
|
let is_original = self.originals.contains(&complex);
|
||||||
|
|
||||||
for (i, component) in complex.components.iter().enumerate() {
|
for (i, component) in complex.components.iter().enumerate() {
|
||||||
if let ComplexSelectorComponent::Compound(component) = component {
|
if let ComplexSelectorComponent::Compound(component) = component {
|
||||||
if let Some(extended) =
|
if let Some(extended) =
|
||||||
self.extend_compound(component, extensions, media_query_context)
|
self.extend_compound(component, extensions, media_query_context, is_original)
|
||||||
{
|
{
|
||||||
if extended_not_expanded.is_none() {
|
if extended_not_expanded.is_none() {
|
||||||
extended_not_expanded = Some(
|
extended_not_expanded = Some(
|
||||||
@ -361,13 +363,12 @@ impl Extender {
|
|||||||
///
|
///
|
||||||
/// The `in_original` parameter indicates whether this is in an original
|
/// The `in_original` parameter indicates whether this is in an original
|
||||||
/// complex selector, meaning that `compound` should not be trimmed out.
|
/// complex selector, meaning that `compound` should not be trimmed out.
|
||||||
// todo: `in_original` is actually obsolete and we should upstream its removal
|
|
||||||
// to dart-sass
|
|
||||||
fn extend_compound(
|
fn extend_compound(
|
||||||
&mut self,
|
&mut self,
|
||||||
compound: &CompoundSelector,
|
compound: &CompoundSelector,
|
||||||
extensions: Option<&HashMap<SimpleSelector, IndexMap<ComplexSelector, Extension>>>,
|
extensions: Option<&HashMap<SimpleSelector, IndexMap<ComplexSelector, Extension>>>,
|
||||||
media_query_context: &Option<Vec<CssMediaQuery>>,
|
media_query_context: &Option<Vec<CssMediaQuery>>,
|
||||||
|
in_original: bool,
|
||||||
) -> Option<Vec<ComplexSelector>> {
|
) -> Option<Vec<ComplexSelector>> {
|
||||||
// If there's more than one target and they all need to match, we track
|
// If there's more than one target and they all need to match, we track
|
||||||
// which targets are actually extended.
|
// which targets are actually extended.
|
||||||
@ -524,7 +525,14 @@ impl Extender {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(unified_paths.flatten().flatten().collect())
|
let unified_paths: Vec<ComplexSelector> = unified_paths.flatten().flatten().collect();
|
||||||
|
|
||||||
|
Some(if in_original && self.mode != ExtendMode::Replace {
|
||||||
|
let original = unified_paths.first().cloned();
|
||||||
|
self.trim(unified_paths, &|complex| Some(complex) == original.as_ref())
|
||||||
|
} else {
|
||||||
|
self.trim(unified_paths, &|_| false)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_simple(
|
fn extend_simple(
|
||||||
@ -781,7 +789,7 @@ impl Extender {
|
|||||||
fn trim(
|
fn trim(
|
||||||
&self,
|
&self,
|
||||||
selectors: Vec<ComplexSelector>,
|
selectors: Vec<ComplexSelector>,
|
||||||
is_original: impl Fn(&ComplexSelector) -> bool,
|
is_original: &dyn Fn(&ComplexSelector) -> bool,
|
||||||
) -> Vec<ComplexSelector> {
|
) -> Vec<ComplexSelector> {
|
||||||
// Avoid truly horrific quadratic behavior.
|
// Avoid truly horrific quadratic behavior.
|
||||||
//
|
//
|
||||||
|
@ -1880,6 +1880,23 @@ test!(
|
|||||||
}",
|
}",
|
||||||
":has(a >) b, :has(a >) :has(a >) :has(a >) b, :has(a >) :has(a >) :has(a >) b {\n color: red;\n}\n"
|
":has(a >) b, :has(a >) :has(a >) :has(a >) b, :has(a >) :has(a >) :has(a >) b {\n color: red;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
extend_after_target,
|
||||||
|
".a .b {
|
||||||
|
c: d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a.mod1, .a.mod2 {
|
||||||
|
@extend .a, .b;
|
||||||
|
}
|
||||||
|
.a.mod3, .a.mod4 {
|
||||||
|
@extend .a, .b;
|
||||||
|
}
|
||||||
|
.a.mod5, .a.mod6 {
|
||||||
|
@extend .a, .b;
|
||||||
|
}",
|
||||||
|
".a .b, .a .a.mod5, .a .a.mod6, .a .a.mod3, .a .a.mod4, .a .a.mod1, .a .a.mod2 {\n c: d;\n}\n"
|
||||||
|
);
|
||||||
error!(
|
error!(
|
||||||
extend_optional_keyword_not_complete,
|
extend_optional_keyword_not_complete,
|
||||||
"a {
|
"a {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user