@@ -1711,7 +1711,8 @@ namespace Sass {
1711
1711
static bool complexSelectorHasExtension (
1712
1712
Complex_Selector* pComplexSelector,
1713
1713
Context& ctx,
1714
- ExtensionSubsetMap& subset_map) {
1714
+ ExtensionSubsetMap& subset_map,
1715
+ std::set<Compound_Selector>& seen) {
1715
1716
1716
1717
bool hasExtension = false ;
1717
1718
@@ -1721,16 +1722,18 @@ namespace Sass {
1721
1722
Compound_Selector* pHead = pIter->head ();
1722
1723
1723
1724
if (pHead) {
1724
- for (Simple_Selector* pSimple : *pHead) {
1725
- if (Wrapped_Selector* ws = dynamic_cast <Wrapped_Selector*>(pSimple)) {
1726
- if (Selector_List* sl = dynamic_cast <Selector_List*>(ws->selector ())) {
1727
- for (Complex_Selector* cs : sl->elements ()) {
1728
- while (cs) {
1729
- if (complexSelectorHasExtension (cs, ctx, subset_map)) {
1730
- hasExtension = true ;
1731
- break ;
1725
+ if (seen.find (*pHead) == seen.end ()) {
1726
+ for (Simple_Selector* pSimple : *pHead) {
1727
+ if (Wrapped_Selector* ws = dynamic_cast <Wrapped_Selector*>(pSimple)) {
1728
+ if (Selector_List* sl = dynamic_cast <Selector_List*>(ws->selector ())) {
1729
+ for (Complex_Selector* cs : sl->elements ()) {
1730
+ while (cs) {
1731
+ if (complexSelectorHasExtension (cs, ctx, subset_map, seen)) {
1732
+ hasExtension = true ;
1733
+ break ;
1734
+ }
1735
+ cs = cs->tail ();
1732
1736
}
1733
- cs = cs->tail ();
1734
1737
}
1735
1738
}
1736
1739
}
@@ -1907,6 +1910,14 @@ namespace Sass {
1907
1910
This is the equivalent of ruby's CommaSequence.do_extend.
1908
1911
*/
1909
1912
Selector_List* Extend::extendSelectorList (Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool & extendedSomething) {
1913
+ std::set<Compound_Selector> seen;
1914
+ return extendSelectorList (pSelectorList, ctx, subset_map, isReplace, extendedSomething, seen);
1915
+ }
1916
+
1917
+ /*
1918
+ This is the equivalent of ruby's CommaSequence.do_extend.
1919
+ */
1920
+ Selector_List* Extend::extendSelectorList (Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool & extendedSomething, std::set<Compound_Selector>& seen) {
1910
1921
1911
1922
Selector_List* pNewSelectors = SASS_MEMORY_NEW (ctx.mem , Selector_List, pSelectorList->pstate (), pSelectorList->length ());
1912
1923
@@ -1920,15 +1931,13 @@ namespace Sass {
1920
1931
// run through the extend code (which does a data model transformation), check if there is anything to extend before doing
1921
1932
// the extend. We might be able to optimize extendComplexSelector, but this approach keeps us closer to ruby sass (which helps
1922
1933
// when debugging).
1923
- if (!complexSelectorHasExtension (pSelector, ctx, subset_map)) {
1934
+ if (!complexSelectorHasExtension (pSelector, ctx, subset_map, seen )) {
1924
1935
*pNewSelectors << pSelector;
1925
1936
continue ;
1926
1937
}
1927
1938
1928
1939
extendedSomething = true ;
1929
1940
1930
- std::set<Compound_Selector> seen;
1931
-
1932
1941
Node extendedSelectors = extendComplexSelector (pSelector, ctx, subset_map, seen, isReplace, true );
1933
1942
if (!pSelector->has_placeholder ()) {
1934
1943
if (!extendedSelectors.contains (complexSelectorToNode (pSelector, ctx), true /* simpleSelectorOrderDependent*/ )) {
@@ -1955,7 +1964,9 @@ namespace Sass {
1955
1964
// process tails
1956
1965
while (cur) {
1957
1966
// process header
1958
- if (cur->head ()) {
1967
+ if (cur->head () && seen.find (*cur->head ()) == seen.end ()) {
1968
+ std::set<Compound_Selector> recseen (seen);
1969
+ recseen.insert (*cur->head ());
1959
1970
// create a copy since we add multiple items if stuff get unwrapped
1960
1971
Compound_Selector* cpy_head = SASS_MEMORY_NEW (ctx.mem , Compound_Selector, cur->pstate ());
1961
1972
for (Simple_Selector* hs : *cur->head ()) {
@@ -1969,7 +1980,7 @@ namespace Sass {
1969
1980
// has wrapped selectors
1970
1981
else {
1971
1982
// extend the inner list of wrapped selector
1972
- Selector_List* ext_sl = extendSelectorList (sl, ctx, subset_map);
1983
+ Selector_List* ext_sl = extendSelectorList (sl, ctx, subset_map, recseen );
1973
1984
for (size_t i = 0 ; i < ext_sl->length (); i += 1 ) {
1974
1985
if (Complex_Selector* ext_cs = ext_sl->at (i)) {
1975
1986
// create clones for wrapped selector and the inner list
0 commit comments