@@ -1518,7 +1518,8 @@ namespace Sass {
15181518 DEBUG_EXEC (EXTEND_COMPOUND, printCompoundSelector (pSelector, " EXTEND COMPOUND: " ))
15191519 // TODO: Ruby has another loop here to skip certain members?
15201520
1521- Node extendedSelectors = Node::createCollection ();
1521+ // let RESULTS be an empty list of complex selectors
1522+ Node results = Node::createCollection ();
15221523 // extendedSelectors.got_line_feed = true;
15231524
15241525 SubSetMapPairs entries = subset_map.get_v (pSelector);
@@ -1529,24 +1530,18 @@ namespace Sass {
15291530
15301531 SubSetMapLookups holder;
15311532
1532-
1533- for (SubSetMapResults::iterator groupedIter = arr.begin (), groupedIterEnd = arr.end (); groupedIter != groupedIterEnd; groupedIter++) {
1534- SubSetMapResult& groupedPair = *groupedIter;
1533+ // for each (EXTENDER, TARGET) in MAP.get(COMPOUND):
1534+ for (SubSetMapResult& groupedPair : arr) {
15351535
15361536 Complex_Selector_Obj seq = groupedPair.first ;
15371537 SubSetMapPairs& group = groupedPair.second ;
15381538
15391539 DEBUG_EXEC (EXTEND_COMPOUND, printComplexSelector (seq, " SEQ: " ))
15401540
15411541 Compound_Selector_Obj pSels = SASS_MEMORY_NEW (Compound_Selector, pSelector->pstate ());
1542- for (SubSetMapPairs::iterator groupIter = group.begin (), groupIterEnd = group.end (); groupIter != groupIterEnd; groupIter++) {
1543- SubSetMapPair& pair = *groupIter;
1544- Compound_Selector_Obj pCompound = pair.second ;
1545- for (size_t index = 0 ; index < pCompound->length (); index++) {
1546- Simple_Selector_Obj pSimpleSelector = (*pCompound)[index];
1547- pSels->append (pSimpleSelector);
1548- pCompound->extended (true );
1549- }
1542+ for (SubSetMapPair& pair : group) {
1543+ pair.second ->extended (true );
1544+ pSels->concat (pair.second );
15501545 }
15511546
15521547 DEBUG_EXEC (EXTEND_COMPOUND, printCompoundSelector (pSels, " SELS: " ))
@@ -1630,8 +1625,7 @@ namespace Sass {
16301625 }
16311626
16321627
1633- for (SubSetMapLookups::iterator holderIter = holder.begin (), holderIterEnd = holder.end (); holderIter != holderIterEnd; holderIter++) {
1634- SubSetMapLookup& pair = *holderIter;
1628+ for (SubSetMapLookup& pair : holder) {
16351629
16361630 Compound_Selector_Obj pSels = pair.first ;
16371631 Complex_Selector_Obj pNewSelector = pair.second ;
@@ -1656,28 +1650,28 @@ namespace Sass {
16561650 iterator != endIterator; ++iterator) {
16571651 Node newSelector = *iterator;
16581652
1659- // DEBUG_PRINTLN(EXTEND_COMPOUND, "EXTENDED AT THIS POINT: " << extendedSelectors )
1660- // DEBUG_PRINTLN(EXTEND_COMPOUND, "SELECTOR EXISTS ALREADY: " << newSelector << " " << extendedSelectors .contains(newSelector, false /*simpleSelectorOrderDependent*/));
1653+ // DEBUG_PRINTLN(EXTEND_COMPOUND, "EXTENDED AT THIS POINT: " << results )
1654+ // DEBUG_PRINTLN(EXTEND_COMPOUND, "SELECTOR EXISTS ALREADY: " << newSelector << " " << results .contains(newSelector, false /*simpleSelectorOrderDependent*/));
16611655
1662- if (!extendedSelectors .contains (newSelector)) {
1656+ if (!results .contains (newSelector)) {
16631657// DEBUG_PRINTLN(EXTEND_COMPOUND, "ADDING NEW SELECTOR")
1664- extendedSelectors .collection ()->push_back (newSelector);
1658+ results .collection ()->push_back (newSelector);
16651659 }
16661660 }
16671661 }
16681662
16691663 DEBUG_EXEC (EXTEND_COMPOUND, printCompoundSelector (pSelector, " EXTEND COMPOUND END: " ))
16701664
1671- return extendedSelectors ;
1665+ return results ;
16721666 }
16731667
16741668
16751669 // check if selector has something to be extended by subset_map
1676- bool Extend::complexSelectorHasExtension (Complex_Selector_Ptr pComplexSelector , CompoundSelectorSet& seen) {
1670+ bool Extend::complexSelectorHasExtension (Complex_Selector_Ptr selector , CompoundSelectorSet& seen) {
16771671
16781672 bool hasExtension = false ;
16791673
1680- Complex_Selector_Obj pIter = pComplexSelector ;
1674+ Complex_Selector_Obj pIter = selector ;
16811675
16821676 while (!hasExtension && pIter) {
16831677 Compound_Selector_Obj pHead = pIter->head ();
@@ -1706,7 +1700,7 @@ namespace Sass {
17061700 err << " You may only @extend selectors within the same directive.\n " ;
17071701 err << " From \" @extend " << ext.second ->to_string () << " \" " ;
17081702 err << " on line " << pstate.line +1 << " of " << rel_path << " \n " ;
1709- error (err.str (), pComplexSelector ->pstate ());
1703+ error (err.str (), selector ->pstate ());
17101704 }
17111705 if (entries.size () > 0 ) hasExtension = true ;
17121706 }
@@ -1729,19 +1723,18 @@ namespace Sass {
17291723 the combinator and compound selector are one unit
17301724 next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence)
17311725 */
1732- Node Extend::extendComplexSelector (Complex_Selector_Ptr pComplexSelector , CompoundSelectorSet& seen, bool isReplace, bool isOriginal) {
1726+ Node Extend::extendComplexSelector (Complex_Selector_Ptr selector , CompoundSelectorSet& seen, bool isReplace, bool isOriginal) {
17331727
1734- Node complexSelector = complexSelectorToNode (pComplexSelector);
1728+ // convert the input selector to extend node format
1729+ Node complexSelector = complexSelectorToNode (selector);
17351730 DEBUG_PRINTLN (EXTEND_COMPLEX, " EXTEND COMPLEX: " << complexSelector)
17361731
1737- Node extendedNotExpanded = Node::createCollection ();
1738-
1739- for (NodeDeque::iterator complexSelIter = complexSelector.collection ()->begin (),
1740- complexSelIterEnd = complexSelector.collection ()->end ();
1741- complexSelIter != complexSelIterEnd; ++complexSelIter)
1742- {
1732+ // let CHOICES be an empty list of selector-lists
1733+ // create new collection to hold the results
1734+ Node choices = Node::createCollection ();
17431735
1744- Node& sseqOrOp = *complexSelIter;
1736+ // for each compound selector COMPOUND in COMPLEX:
1737+ for (Node& sseqOrOp : *complexSelector.collection ()) {
17451738
17461739 DEBUG_PRINTLN (EXTEND_COMPLEX, " LOOP: " << sseqOrOp)
17471740
@@ -1754,94 +1747,90 @@ namespace Sass {
17541747 Node inner = Node::createCollection ();
17551748 outer.collection ()->push_back (inner);
17561749 inner.collection ()->push_back (sseqOrOp);
1757- extendedNotExpanded .collection ()->push_back (outer);
1750+ choices .collection ()->push_back (outer);
17581751 continue ;
17591752 }
17601753
1761- Compound_Selector_Obj pCompoundSelector = sseqOrOp.selector ()->head ();
1754+ // verified now that node is a valid selector
1755+ Complex_Selector_Obj sseqSel = sseqOrOp.selector ();
1756+ Compound_Selector_Obj sseqHead = sseqSel->head ();
17621757
1758+ // let EXTENDED be extend_compound(COMPOUND, SEEN)
1759+ // extend the compound selector against the given subset_map
17631760 // RUBY: extended = sseq_or_op.do_extend(extends, parent_directives, replace, seen)
1764- Node extended = extendCompoundSelector (pCompoundSelector , seen, isReplace);
1761+ Node extended = extendCompoundSelector (sseqHead , seen, isReplace); // slow(17%)!
17651762 if (sseqOrOp.got_line_feed ) extended.got_line_feed = true ;
17661763 DEBUG_PRINTLN (EXTEND_COMPLEX, " EXTENDED: " << extended)
17671764
1768-
1769- // Prepend the Compound_Selector based on the choices logic; choices seems to be extend but with an ruby Array instead of a Sequence
1770- // due to the member mapping: choices = extended.map {|seq| seq.members}
1771- Complex_Selector_Obj pJustCurrentCompoundSelector = sseqOrOp.selector ();
1772-
1765+ // Prepend the Compound_Selector based on the choices logic; choices seems to be extend but with a ruby
1766+ // Array instead of a Sequence due to the member mapping: choices = extended.map {|seq| seq.members}
17731767 // RUBY: extended.first.add_sources!([self]) if original && !has_placeholder?
1774- if (isOriginal && !pComplexSelector ->has_placeholder ()) {
1768+ if (isOriginal && !selector ->has_placeholder ()) {
17751769 ComplexSelectorSet srcset;
1776- srcset.insert (pComplexSelector );
1777- pJustCurrentCompoundSelector ->addSources (srcset);
1770+ srcset.insert (selector );
1771+ sseqSel ->addSources (srcset);
17781772 DEBUG_PRINTLN (EXTEND_COMPLEX, " ADD SOURCES: " << *pComplexSelector)
17791773 }
17801774
17811775 bool isSuperselector = false ;
1782- for (NodeDeque::iterator iterator = extended.collection ()->begin (), endIterator = extended.collection ()->end ();
1783- iterator != endIterator; ++iterator) {
1784- Node& childNode = *iterator;
1776+ // if no complex selector in EXTENDED is a superselector of COMPOUND:
1777+ for (Node& childNode : *extended.collection ()) {
17851778 Complex_Selector_Obj pExtensionSelector = nodeToComplexSelector (childNode);
1786- if (pExtensionSelector->is_superselector_of (pJustCurrentCompoundSelector )) {
1779+ if (pExtensionSelector->is_superselector_of (sseqSel )) {
17871780 isSuperselector = true ;
17881781 break ;
17891782 }
17901783 }
17911784
17921785 if (!isSuperselector) {
1793- if (sseqOrOp.got_line_feed ) pJustCurrentCompoundSelector->has_line_feed (sseqOrOp.got_line_feed );
1794- extended.collection ()->push_front (complexSelectorToNode (pJustCurrentCompoundSelector));
1786+ // add a complex selector composed only of COMPOUND to EXTENDED
1787+ if (sseqOrOp.got_line_feed ) sseqSel->has_line_feed (sseqOrOp.got_line_feed );
1788+ extended.collection ()->push_front (complexSelectorToNode (sseqSel));
17951789 }
17961790
17971791 DEBUG_PRINTLN (EXTEND_COMPLEX, " CHOICES UNSHIFTED: " << extended)
17981792
1793+ // add EXTENDED to CHOICES
17991794 // Aggregate our current extensions
1800- extendedNotExpanded .collection ()->push_back (extended);
1795+ choices .collection ()->push_back (extended);
18011796 }
18021797
18031798
1804- DEBUG_PRINTLN (EXTEND_COMPLEX, " EXTENDED NOT EXPANDED: " << extendedNotExpanded )
1799+ DEBUG_PRINTLN (EXTEND_COMPLEX, " EXTENDED NOT EXPANDED: " << choices )
18051800
18061801
18071802
18081803 // Ruby Equivalent: paths
1809- Node paths = Sass::paths (extendedNotExpanded );
1804+ Node paths = Sass::paths (choices );
18101805
18111806 DEBUG_PRINTLN (EXTEND_COMPLEX, " PATHS: " << paths)
18121807
1813-
1814-
1815- // Ruby Equivalent: weave
1808+ // let WEAVES be an empty list of selector lists
18161809 Node weaves = Node::createCollection ();
18171810
1818- for (NodeDeque::iterator pathsIter = paths.collection ()->begin (), pathsEndIter = paths.collection ()->end (); pathsIter != pathsEndIter; ++pathsIter) {
1819- Node& path = *pathsIter;
1820- Node weaved = weave (path);
1811+ // for each list of complex selectors PATH in paths(CHOICES):
1812+ for (Node& path : *paths.collection ()) {
1813+ // add weave(PATH) to WEAVES
1814+ Node weaved = weave (path); // slow(12%)!
18211815 weaved.got_line_feed = path.got_line_feed ;
18221816 weaves.collection ()->push_back (weaved);
18231817 }
18241818
18251819 DEBUG_PRINTLN (EXTEND_COMPLEX, " WEAVES: " << weaves)
18261820
1827-
1828-
18291821 // Ruby Equivalent: trim
1830- Node trimmed = trim (weaves, isReplace);
1822+ Node trimmed ( trim (weaves, isReplace)); // slow(19%)!
18311823
18321824 DEBUG_PRINTLN (EXTEND_COMPLEX, " TRIMMED: " << trimmed)
18331825
1834-
18351826 // Ruby Equivalent: flatten
1836- Node extendedSelectors = flatten (trimmed, 1 );
1827+ Node flattened ( flatten (trimmed, 1 ) );
18371828
18381829 DEBUG_PRINTLN (EXTEND_COMPLEX, " >>>>> EXTENDED: " << extendedSelectors)
1839-
1840-
18411830 DEBUG_PRINTLN (EXTEND_COMPLEX, " EXTEND COMPLEX END: " << complexSelector)
18421831
1843-
1844- return extendedSelectors ;
1832+ // return trim(WEAVES)
1833+ return flattened ;
18451834 }
18461835
18471836
@@ -1876,18 +1865,22 @@ namespace Sass {
18761865
18771866 // now do the actual extension of the complex selector
18781867 Node extendedSelectors = extendComplexSelector (pSelector, seen, isReplace, true );
1868+
18791869 if (!pSelector->has_placeholder ()) {
1880- if (!extendedSelectors.contains (complexSelectorToNode (pSelector))) {
1870+ Node nSelector (complexSelectorToNode (pSelector));
1871+ if (!extendedSelectors.contains (nSelector)) {
18811872 pNewSelectors->append (pSelector);
18821873 continue ;
18831874 }
18841875 }
18851876
1886- for (NodeDeque::iterator iterator = extendedSelectors.collection ()->begin (), iteratorBegin = extendedSelectors.collection ()->begin (), iteratorEnd = extendedSelectors.collection ()->end (); iterator != iteratorEnd; ++iterator) {
1877+ bool doReplace = isReplace;
1878+ for (Node& childNode : *extendedSelectors.collection ()) {
18871879 // When it is a replace, skip the first one, unless there is only one
1888- if (isReplace && iterator == iteratorBegin && extendedSelectors.collection ()->size () > 1 ) continue ;
1889-
1890- Node& childNode = *iterator;
1880+ if (doReplace && extendedSelectors.collection ()->size () > 1 ) {
1881+ doReplace = false ;
1882+ continue ;
1883+ }
18911884 pNewSelectors->append (nodeToComplexSelector (childNode));
18921885 }
18931886 }
0 commit comments