sassc 2.2.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/CHANGELOG.md +18 -0
  4. data/Rakefile +1 -3
  5. data/ext/extconf.rb +13 -5
  6. data/ext/libsass/VERSION +1 -1
  7. data/ext/libsass/include/sass/base.h +2 -1
  8. data/ext/libsass/include/sass/context.h +4 -0
  9. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  10. data/ext/libsass/src/ast.cpp +158 -168
  11. data/ext/libsass/src/ast.hpp +389 -230
  12. data/ext/libsass/src/ast_def_macros.hpp +18 -10
  13. data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
  14. data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
  15. data/ext/libsass/src/ast_helpers.hpp +292 -0
  16. data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
  17. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  18. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  19. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  20. data/ext/libsass/src/ast_selectors.cpp +594 -1026
  21. data/ext/libsass/src/ast_selectors.hpp +339 -385
  22. data/ext/libsass/src/ast_supports.cpp +36 -52
  23. data/ext/libsass/src/ast_supports.hpp +29 -29
  24. data/ext/libsass/src/ast_values.cpp +271 -84
  25. data/ext/libsass/src/ast_values.hpp +116 -107
  26. data/ext/libsass/src/backtrace.cpp +9 -9
  27. data/ext/libsass/src/backtrace.hpp +5 -5
  28. data/ext/libsass/src/base64vlq.cpp +2 -2
  29. data/ext/libsass/src/base64vlq.hpp +1 -1
  30. data/ext/libsass/src/bind.cpp +18 -18
  31. data/ext/libsass/src/bind.hpp +1 -1
  32. data/ext/libsass/src/c2ast.cpp +3 -3
  33. data/ext/libsass/src/c2ast.hpp +1 -1
  34. data/ext/libsass/src/cencode.c +4 -6
  35. data/ext/libsass/src/check_nesting.cpp +40 -41
  36. data/ext/libsass/src/check_nesting.hpp +6 -2
  37. data/ext/libsass/src/color_maps.cpp +14 -13
  38. data/ext/libsass/src/color_maps.hpp +1 -9
  39. data/ext/libsass/src/constants.cpp +5 -0
  40. data/ext/libsass/src/constants.hpp +6 -0
  41. data/ext/libsass/src/context.cpp +92 -119
  42. data/ext/libsass/src/context.hpp +41 -53
  43. data/ext/libsass/src/cssize.cpp +66 -149
  44. data/ext/libsass/src/cssize.hpp +17 -23
  45. data/ext/libsass/src/dart_helpers.hpp +199 -0
  46. data/ext/libsass/src/debugger.hpp +451 -295
  47. data/ext/libsass/src/emitter.cpp +15 -16
  48. data/ext/libsass/src/emitter.hpp +10 -12
  49. data/ext/libsass/src/environment.cpp +27 -27
  50. data/ext/libsass/src/environment.hpp +29 -24
  51. data/ext/libsass/src/error_handling.cpp +62 -41
  52. data/ext/libsass/src/error_handling.hpp +61 -51
  53. data/ext/libsass/src/eval.cpp +167 -281
  54. data/ext/libsass/src/eval.hpp +27 -29
  55. data/ext/libsass/src/eval_selectors.cpp +75 -0
  56. data/ext/libsass/src/expand.cpp +275 -222
  57. data/ext/libsass/src/expand.hpp +36 -16
  58. data/ext/libsass/src/extender.cpp +1188 -0
  59. data/ext/libsass/src/extender.hpp +399 -0
  60. data/ext/libsass/src/extension.cpp +43 -0
  61. data/ext/libsass/src/extension.hpp +89 -0
  62. data/ext/libsass/src/file.cpp +81 -72
  63. data/ext/libsass/src/file.hpp +28 -37
  64. data/ext/libsass/src/fn_colors.cpp +20 -18
  65. data/ext/libsass/src/fn_lists.cpp +30 -29
  66. data/ext/libsass/src/fn_maps.cpp +3 -3
  67. data/ext/libsass/src/fn_miscs.cpp +34 -46
  68. data/ext/libsass/src/fn_numbers.cpp +20 -13
  69. data/ext/libsass/src/fn_selectors.cpp +98 -128
  70. data/ext/libsass/src/fn_strings.cpp +47 -33
  71. data/ext/libsass/src/fn_utils.cpp +31 -29
  72. data/ext/libsass/src/fn_utils.hpp +17 -11
  73. data/ext/libsass/src/inspect.cpp +186 -148
  74. data/ext/libsass/src/inspect.hpp +31 -29
  75. data/ext/libsass/src/lexer.cpp +20 -82
  76. data/ext/libsass/src/lexer.hpp +5 -16
  77. data/ext/libsass/src/listize.cpp +23 -37
  78. data/ext/libsass/src/listize.hpp +8 -9
  79. data/ext/libsass/src/mapping.hpp +1 -0
  80. data/ext/libsass/src/memory/allocator.cpp +48 -0
  81. data/ext/libsass/src/memory/allocator.hpp +138 -0
  82. data/ext/libsass/src/memory/config.hpp +20 -0
  83. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  84. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  85. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  86. data/ext/libsass/src/memory.hpp +12 -0
  87. data/ext/libsass/src/operation.hpp +71 -61
  88. data/ext/libsass/src/operators.cpp +19 -18
  89. data/ext/libsass/src/operators.hpp +11 -11
  90. data/ext/libsass/src/ordered_map.hpp +112 -0
  91. data/ext/libsass/src/output.cpp +45 -64
  92. data/ext/libsass/src/output.hpp +6 -6
  93. data/ext/libsass/src/parser.cpp +512 -700
  94. data/ext/libsass/src/parser.hpp +89 -97
  95. data/ext/libsass/src/parser_selectors.cpp +189 -0
  96. data/ext/libsass/src/permutate.hpp +164 -0
  97. data/ext/libsass/src/plugins.cpp +7 -7
  98. data/ext/libsass/src/plugins.hpp +8 -8
  99. data/ext/libsass/src/position.cpp +7 -26
  100. data/ext/libsass/src/position.hpp +44 -21
  101. data/ext/libsass/src/prelexer.cpp +6 -6
  102. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  103. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  104. data/ext/libsass/src/sass.cpp +16 -15
  105. data/ext/libsass/src/sass.hpp +10 -5
  106. data/ext/libsass/src/sass2scss.cpp +4 -4
  107. data/ext/libsass/src/sass_context.cpp +91 -122
  108. data/ext/libsass/src/sass_context.hpp +2 -2
  109. data/ext/libsass/src/sass_functions.cpp +1 -1
  110. data/ext/libsass/src/sass_values.cpp +8 -11
  111. data/ext/libsass/src/settings.hpp +19 -0
  112. data/ext/libsass/src/source.cpp +69 -0
  113. data/ext/libsass/src/source.hpp +95 -0
  114. data/ext/libsass/src/source_data.hpp +32 -0
  115. data/ext/libsass/src/source_map.cpp +22 -18
  116. data/ext/libsass/src/source_map.hpp +12 -9
  117. data/ext/libsass/src/stylesheet.cpp +22 -0
  118. data/ext/libsass/src/stylesheet.hpp +57 -0
  119. data/ext/libsass/src/to_value.cpp +2 -2
  120. data/ext/libsass/src/to_value.hpp +1 -1
  121. data/ext/libsass/src/units.cpp +24 -22
  122. data/ext/libsass/src/units.hpp +8 -8
  123. data/ext/libsass/src/utf8_string.cpp +9 -10
  124. data/ext/libsass/src/utf8_string.hpp +7 -6
  125. data/ext/libsass/src/util.cpp +48 -50
  126. data/ext/libsass/src/util.hpp +20 -21
  127. data/ext/libsass/src/util_string.cpp +111 -61
  128. data/ext/libsass/src/util_string.hpp +62 -8
  129. data/ext/libsass/src/values.cpp +12 -12
  130. data/lib/sassc/engine.rb +5 -3
  131. data/lib/sassc/functions_handler.rb +8 -8
  132. data/lib/sassc/native.rb +4 -6
  133. data/lib/sassc/script.rb +4 -4
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +18 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +29 -15
  138. data/ext/libsass/src/extend.cpp +0 -2132
  139. data/ext/libsass/src/extend.hpp +0 -86
  140. data/ext/libsass/src/node.cpp +0 -322
  141. data/ext/libsass/src/node.hpp +0 -118
  142. data/ext/libsass/src/paths.hpp +0 -71
  143. data/ext/libsass/src/sass_util.cpp +0 -152
  144. data/ext/libsass/src/sass_util.hpp +0 -256
  145. data/ext/libsass/src/subset_map.cpp +0 -58
  146. data/ext/libsass/src/subset_map.hpp +0 -76
  147. data/lib/sassc/native/lib_c.rb +0 -21
@@ -1,86 +0,0 @@
1
- #ifndef SASS_EXTEND_H
2
- #define SASS_EXTEND_H
3
-
4
- #include <string>
5
- #include <set>
6
-
7
- #include "ast.hpp"
8
- #include "node.hpp"
9
- #include "eval.hpp"
10
- #include "operation.hpp"
11
- #include "subset_map.hpp"
12
- #include "ast_fwd_decl.hpp"
13
-
14
- namespace Sass {
15
-
16
- Node subweave(Node& one, Node& two);
17
-
18
- class Extend : public Operation_CRTP<void, Extend> {
19
-
20
- Subset_Map& subset_map;
21
- Eval* eval;
22
-
23
- private:
24
-
25
- std::unordered_map<
26
- Selector_List_Obj, // key
27
- Selector_List_Obj, // value
28
- HashNodes, // hasher
29
- CompareNodes // compare
30
- > memoizeList;
31
-
32
- std::unordered_map<
33
- Complex_Selector_Obj, // key
34
- Node, // value
35
- HashNodes, // hasher
36
- CompareNodes // compare
37
- > memoizeComplex;
38
-
39
- /* this turned out to be too much overhead
40
- re-evaluate once we store an ast selector
41
- std::unordered_map<
42
- Compound_Selector_Obj, // key
43
- Node, // value
44
- HashNodes, // hasher
45
- CompareNodes // compare
46
- > memoizeCompound;
47
- */
48
-
49
- void extendObjectWithSelectorAndBlock(Ruleset* pObject);
50
- Node extendComplexSelector(Complex_Selector* sel, CompoundSelectorSet& seen, bool isReplace, bool isOriginal);
51
- Node extendCompoundSelector(Compound_Selector* sel, CompoundSelectorSet& seen, bool isReplace);
52
- bool complexSelectorHasExtension(Complex_Selector* selector, CompoundSelectorSet& seen);
53
- Node trim(Node& seqses, bool isReplace);
54
- Node weave(Node& path);
55
-
56
- public:
57
- void setEval(Eval& eval);
58
- Selector_List* extendSelectorList(Selector_List_Obj pSelectorList, bool isReplace, bool& extendedSomething, CompoundSelectorSet& seen);
59
- Selector_List* extendSelectorList(Selector_List_Obj pSelectorList, bool isReplace = false) {
60
- bool extendedSomething = false;
61
- CompoundSelectorSet seen;
62
- return extendSelectorList(pSelectorList, isReplace, extendedSomething, seen);
63
- }
64
- Selector_List* extendSelectorList(Selector_List_Obj pSelectorList, CompoundSelectorSet& seen) {
65
- bool isReplace = false;
66
- bool extendedSomething = false;
67
- return extendSelectorList(pSelectorList, isReplace, extendedSomething, seen);
68
- }
69
- Extend(Subset_Map&);
70
- ~Extend() { }
71
-
72
- void operator()(Block*);
73
- void operator()(Ruleset*);
74
- void operator()(Supports_Block*);
75
- void operator()(Media_Block*);
76
- void operator()(Directive*);
77
-
78
- // ignore missed types
79
- template <typename U>
80
- void fallback(U x) {}
81
-
82
- };
83
-
84
- }
85
-
86
- #endif
@@ -1,322 +0,0 @@
1
- // sass.hpp must go before all system headers to get the
2
- // __EXTENSIONS__ fix on Solaris.
3
- #include "sass.hpp"
4
-
5
- #include <vector>
6
-
7
- #include "node.hpp"
8
- #include "context.hpp"
9
- #include "parser.hpp"
10
-
11
- namespace Sass {
12
-
13
-
14
- Node Node::createCombinator(const Complex_Selector::Combinator& combinator) {
15
- NodeDequePtr null;
16
- return Node(COMBINATOR, combinator, NULL /*pSelector*/, null /*pCollection*/);
17
- }
18
-
19
-
20
- Node Node::createSelector(const Complex_Selector& pSelector) {
21
- NodeDequePtr null;
22
-
23
- Complex_Selector* pStripped = SASS_MEMORY_COPY(&pSelector);
24
- pStripped->tail({});
25
- pStripped->combinator(Complex_Selector::ANCESTOR_OF);
26
-
27
- Node n(SELECTOR, Complex_Selector::ANCESTOR_OF, pStripped, null /*pCollection*/);
28
- n.got_line_feed = pSelector.has_line_feed();
29
- return n;
30
- }
31
-
32
-
33
- Node Node::createCollection() {
34
- NodeDequePtr pEmptyCollection = std::make_shared<NodeDeque>();
35
- return Node(COLLECTION, Complex_Selector::ANCESTOR_OF, NULL /*pSelector*/, pEmptyCollection);
36
- }
37
-
38
-
39
- Node Node::createCollection(const NodeDeque& values) {
40
- NodeDequePtr pShallowCopiedCollection = std::make_shared<NodeDeque>(values);
41
- return Node(COLLECTION, Complex_Selector::ANCESTOR_OF, NULL /*pSelector*/, pShallowCopiedCollection);
42
- }
43
-
44
-
45
- Node Node::createNil() {
46
- NodeDequePtr null;
47
- return Node(NIL, Complex_Selector::ANCESTOR_OF, NULL /*pSelector*/, null /*pCollection*/);
48
- }
49
-
50
-
51
- Node::Node(const TYPE& type, Complex_Selector::Combinator combinator, Complex_Selector* pSelector, NodeDequePtr& pCollection)
52
- : got_line_feed(false), mType(type), mCombinator(combinator), mpSelector(pSelector), mpCollection(pCollection)
53
- { if (pSelector) got_line_feed = pSelector->has_line_feed(); }
54
-
55
-
56
- Node Node::klone() const {
57
- NodeDequePtr pNewCollection = std::make_shared<NodeDeque>();
58
- if (mpCollection) {
59
- for (NodeDeque::iterator iter = mpCollection->begin(), iterEnd = mpCollection->end(); iter != iterEnd; iter++) {
60
- Node& toClone = *iter;
61
- pNewCollection->push_back(toClone.klone());
62
- }
63
- }
64
-
65
- Node n(mType, mCombinator, mpSelector ? SASS_MEMORY_COPY(mpSelector) : NULL, pNewCollection);
66
- n.got_line_feed = got_line_feed;
67
- return n;
68
- }
69
-
70
-
71
- bool Node::contains(const Node& potentialChild) const {
72
- bool found = false;
73
-
74
- for (NodeDeque::iterator iter = mpCollection->begin(), iterEnd = mpCollection->end(); iter != iterEnd; iter++) {
75
- Node& toTest = *iter;
76
-
77
- if (toTest == potentialChild) {
78
- found = true;
79
- break;
80
- }
81
- }
82
-
83
- return found;
84
- }
85
-
86
-
87
- bool Node::operator==(const Node& rhs) const {
88
- if (this->type() != rhs.type()) {
89
- return false;
90
- }
91
-
92
- if (this->isCombinator()) {
93
-
94
- return this->combinator() == rhs.combinator();
95
-
96
- } else if (this->isNil()) {
97
-
98
- return true; // no state to check
99
-
100
- } else if (this->isSelector()){
101
-
102
- return *this->selector() == *rhs.selector();
103
-
104
- } else if (this->isCollection()) {
105
-
106
- if (this->collection()->size() != rhs.collection()->size()) {
107
- return false;
108
- }
109
-
110
- for (NodeDeque::iterator lhsIter = this->collection()->begin(), lhsIterEnd = this->collection()->end(),
111
- rhsIter = rhs.collection()->begin(); lhsIter != lhsIterEnd; lhsIter++, rhsIter++) {
112
-
113
- if (*lhsIter != *rhsIter) {
114
- return false;
115
- }
116
-
117
- }
118
-
119
- return true;
120
-
121
- }
122
-
123
- // We shouldn't get here.
124
- throw "Comparing unknown node types. A new type was probably added and this method wasn't implemented for it.";
125
- }
126
-
127
-
128
- void Node::plus(Node& rhs) {
129
- if (!this->isCollection() || !rhs.isCollection()) {
130
- throw "Both the current node and rhs must be collections.";
131
- }
132
- this->collection()->insert(this->collection()->end(), rhs.collection()->begin(), rhs.collection()->end());
133
- }
134
-
135
- #ifdef DEBUG
136
- std::ostream& operator<<(std::ostream& os, const Node& node) {
137
-
138
- if (node.isCombinator()) {
139
-
140
- switch (node.combinator()) {
141
- case Complex_Selector::ANCESTOR_OF: os << "\" \""; break;
142
- case Complex_Selector::PARENT_OF: os << "\">\""; break;
143
- case Complex_Selector::PRECEDES: os << "\"~\""; break;
144
- case Complex_Selector::ADJACENT_TO: os << "\"+\""; break;
145
- case Complex_Selector::REFERENCE: os << "\"/\""; break;
146
- }
147
-
148
- } else if (node.isNil()) {
149
-
150
- os << "nil";
151
-
152
- } else if (node.isSelector()){
153
-
154
- os << node.selector()->head()->to_string();
155
-
156
- } else if (node.isCollection()) {
157
-
158
- os << "[";
159
-
160
- for (NodeDeque::iterator iter = node.collection()->begin(), iterBegin = node.collection()->begin(), iterEnd = node.collection()->end(); iter != iterEnd; iter++) {
161
- if (iter != iterBegin) {
162
- os << ", ";
163
- }
164
-
165
- os << (*iter);
166
- }
167
-
168
- os << "]";
169
-
170
- }
171
-
172
- return os;
173
-
174
- }
175
- #endif
176
-
177
-
178
- Node complexSelectorToNode(Complex_Selector* pToConvert) {
179
- if (pToConvert == NULL) {
180
- return Node::createNil();
181
- }
182
- Node node = Node::createCollection();
183
- node.got_line_feed = pToConvert->has_line_feed();
184
- bool has_lf = pToConvert->has_line_feed();
185
-
186
- // unwrap the selector from parent ref
187
- if (pToConvert->head() && pToConvert->head()->has_parent_ref()) {
188
- Complex_Selector_Obj tail = pToConvert->tail();
189
- if (tail) tail->has_line_feed(pToConvert->has_line_feed());
190
- pToConvert = tail;
191
- }
192
-
193
- while (pToConvert) {
194
-
195
- bool empty_parent_ref = pToConvert->head() && pToConvert->head()->is_empty_reference();
196
-
197
- // the first Complex_Selector may contain a dummy head pointer, skip it.
198
- if (pToConvert->head() && !empty_parent_ref) {
199
- node.collection()->push_back(Node::createSelector(*pToConvert));
200
- if (has_lf) node.collection()->back().got_line_feed = has_lf;
201
- if (pToConvert->head() || empty_parent_ref) {
202
- if (pToConvert->tail()) {
203
- pToConvert->tail()->has_line_feed(pToConvert->has_line_feed());
204
- }
205
- }
206
- has_lf = false;
207
- }
208
-
209
- if (pToConvert->combinator() != Complex_Selector::ANCESTOR_OF) {
210
- node.collection()->push_back(Node::createCombinator(pToConvert->combinator()));
211
- if (has_lf) node.collection()->back().got_line_feed = has_lf;
212
- has_lf = false;
213
- }
214
-
215
- if (pToConvert && empty_parent_ref && pToConvert->tail()) {
216
- // pToConvert->tail()->has_line_feed(pToConvert->has_line_feed());
217
- }
218
-
219
- pToConvert = pToConvert->tail();
220
- }
221
-
222
- return node;
223
- }
224
-
225
-
226
- Complex_Selector* nodeToComplexSelector(const Node& toConvert) {
227
- if (toConvert.isNil()) {
228
- return NULL;
229
- }
230
-
231
-
232
- if (!toConvert.isCollection()) {
233
- throw "The node to convert to a Complex_Selector* must be a collection type or nil.";
234
- }
235
-
236
-
237
- NodeDeque& childNodes = *toConvert.collection();
238
-
239
- std::string noPath("");
240
- Complex_Selector_Obj pFirst = SASS_MEMORY_NEW(Complex_Selector, ParserState("[NODE]"), Complex_Selector::ANCESTOR_OF, {}, {});
241
-
242
- Complex_Selector_Obj pCurrent = pFirst;
243
-
244
- if (toConvert.isSelector()) pFirst->has_line_feed(toConvert.got_line_feed);
245
- if (toConvert.isCombinator()) pFirst->has_line_feed(toConvert.got_line_feed);
246
-
247
- for (NodeDeque::iterator childIter = childNodes.begin(), childIterEnd = childNodes.end(); childIter != childIterEnd; childIter++) {
248
-
249
- Node& child = *childIter;
250
-
251
- if (child.isSelector()) {
252
- // JMA - need to clone the selector, because they can end up getting shared across Node
253
- // collections, and can result in an infinite loop during the call to parentSuperselector()
254
- pCurrent->tail(SASS_MEMORY_COPY(child.selector()));
255
- // if (child.got_line_feed) pCurrent->has_line_feed(child.got_line_feed);
256
- pCurrent = pCurrent->tail();
257
- } else if (child.isCombinator()) {
258
- pCurrent->combinator(child.combinator());
259
- if (child.got_line_feed) pCurrent->has_line_feed(child.got_line_feed);
260
-
261
- // if the next node is also a combinator, create another Complex_Selector to hold it so it doesn't replace the current combinator
262
- if (childIter+1 != childIterEnd) {
263
- Node& nextNode = *(childIter+1);
264
- if (nextNode.isCombinator()) {
265
- pCurrent->tail(SASS_MEMORY_NEW(Complex_Selector, ParserState("[NODE]"), Complex_Selector::ANCESTOR_OF, {}, {}));
266
- if (nextNode.got_line_feed) pCurrent->tail()->has_line_feed(nextNode.got_line_feed);
267
- pCurrent = pCurrent->tail();
268
- }
269
- }
270
- } else {
271
- throw "The node to convert's children must be only combinators or selectors.";
272
- }
273
- }
274
-
275
- // Put the dummy Compound_Selector in the first position, for consistency with the rest of libsass
276
- Compound_Selector* fakeHead = SASS_MEMORY_NEW(Compound_Selector, ParserState("[NODE]"), 1);
277
- Parent_Selector* selectorRef = SASS_MEMORY_NEW(Parent_Selector, ParserState("[NODE]"));
278
- fakeHead->elements().push_back(selectorRef);
279
- if (toConvert.got_line_feed) pFirst->has_line_feed(toConvert.got_line_feed);
280
- // pFirst->has_line_feed(pFirst->has_line_feed() || pFirst->tail()->has_line_feed() || toConvert.got_line_feed);
281
- pFirst->head(fakeHead);
282
- return SASS_MEMORY_COPY(pFirst);
283
- }
284
-
285
- // A very naive trim function, which removes duplicates in a node
286
- // This is only used in Complex_Selector::unify_with for now, may need modifications to fit other needs
287
- Node Node::naiveTrim(Node& seqses) {
288
-
289
- std::vector<Node*> res;
290
- std::vector<Complex_Selector_Obj> known;
291
-
292
- NodeDeque::reverse_iterator seqsesIter = seqses.collection()->rbegin(),
293
- seqsesIterEnd = seqses.collection()->rend();
294
-
295
- for (; seqsesIter != seqsesIterEnd; ++seqsesIter)
296
- {
297
- Node& seqs1 = *seqsesIter;
298
- if( seqs1.isSelector() ) {
299
- Complex_Selector_Obj sel = seqs1.selector();
300
- std::vector<Complex_Selector_Obj>::iterator it;
301
- bool found = false;
302
- for (it = known.begin(); it != known.end(); ++it) {
303
- if (**it == *sel) { found = true; break; }
304
- }
305
- if( !found ) {
306
- known.push_back(seqs1.selector());
307
- res.push_back(&seqs1);
308
- }
309
- } else {
310
- res.push_back(&seqs1);
311
- }
312
- }
313
-
314
- Node result = Node::createCollection();
315
-
316
- for (size_t i = res.size() - 1; i != std::string::npos; --i) {
317
- result.collection()->push_back(*res[i]);
318
- }
319
-
320
- return result;
321
- }
322
- }
@@ -1,118 +0,0 @@
1
- #ifndef SASS_NODE_H
2
- #define SASS_NODE_H
3
-
4
- #include <deque>
5
- #include <memory>
6
-
7
- #include "ast.hpp"
8
-
9
-
10
- namespace Sass {
11
-
12
-
13
-
14
-
15
- class Context;
16
-
17
- /*
18
- There are a lot of stumbling blocks when trying to port the ruby extend code to C++. The biggest is the choice of
19
- data type. The ruby code will pretty seamlessly switch types between an Array<SimpleSequence or Op> (libsass'
20
- equivalent is the Complex_Selector) to a Sequence, which contains more metadata about the sequence than just the
21
- selector info. They also have the ability to have arbitrary nestings of arrays like [1, [2]], which is hard to
22
- implement using Array equivalents in C++ (like the deque or vector). They also have the ability to include nil
23
- in the arrays, like [1, nil, 3], which has potential semantic differences than an empty array [1, [], 3]. To be
24
- able to represent all of these as unique cases, we need to create a tree of variant objects. The tree nature allows
25
- the inconsistent nesting levels. The variant nature (while making some of the C++ code uglier) allows the code to
26
- more closely match the ruby code, which is a huge benefit when attempting to implement an complex algorithm like
27
- the Extend operator.
28
-
29
- Note that the current libsass data model also pairs the combinator with the Complex_Selector that follows it, but
30
- ruby sass has no such restriction, so we attempt to create a data structure that can handle them split apart.
31
- */
32
-
33
- class Node;
34
- typedef std::deque<Node> NodeDeque;
35
- typedef std::shared_ptr<NodeDeque> NodeDequePtr;
36
-
37
- class Node {
38
- public:
39
- enum TYPE {
40
- SELECTOR,
41
- COMBINATOR,
42
- COLLECTION,
43
- NIL
44
- };
45
-
46
- TYPE type() const { return mType; }
47
- bool isCombinator() const { return mType == COMBINATOR; }
48
- bool isSelector() const { return mType == SELECTOR; }
49
- bool isCollection() const { return mType == COLLECTION; }
50
- bool isNil() const { return mType == NIL; }
51
- bool got_line_feed;
52
-
53
- Complex_Selector::Combinator combinator() const { return mCombinator; }
54
-
55
- Complex_Selector_Obj selector() { return mpSelector; }
56
- Complex_Selector_Obj selector() const { return mpSelector; }
57
-
58
- NodeDequePtr collection() { return mpCollection; }
59
- const NodeDequePtr collection() const { return mpCollection; }
60
-
61
- static Node createCombinator(const Complex_Selector::Combinator& combinator);
62
-
63
- // This method will klone the selector, stripping off the tail and combinator
64
- static Node createSelector(const Complex_Selector& pSelector);
65
-
66
- static Node createCollection();
67
- static Node createCollection(const NodeDeque& values);
68
-
69
- static Node createNil();
70
- static Node naiveTrim(Node& seqses);
71
-
72
- Node klone() const;
73
-
74
- bool operator==(const Node& rhs) const;
75
- inline bool operator!=(const Node& rhs) const { return !(*this == rhs); }
76
-
77
-
78
- /*
79
- COLLECTION FUNCTIONS
80
-
81
- Most types don't need any helper methods (nil and combinator due to their simplicity and
82
- selector due to the fact that we leverage the non-node selector code on the Complex_Selector
83
- whereever possible). The following methods are intended to be called on Node objects whose
84
- type is COLLECTION only.
85
- */
86
-
87
- // rhs and this must be node collections. Shallow copy the nodes from rhs to the end of this.
88
- // This function DOES NOT remove the nodes from rhs.
89
- void plus(Node& rhs);
90
-
91
- // potentialChild must be a node collection of selectors/combinators. this must be a collection
92
- // of collections of nodes/combinators. This method checks if potentialChild is a child of this
93
- // Node.
94
- bool contains(const Node& potentialChild) const;
95
-
96
- private:
97
- // Private constructor; Use the static methods (like createCombinator and createSelector)
98
- // to instantiate this object. This is more expressive, and it allows us to break apart each
99
- // case into separate functions.
100
- Node(const TYPE& type, Complex_Selector::Combinator combinator, Complex_Selector* pSelector, NodeDequePtr& pCollection);
101
-
102
- TYPE mType;
103
-
104
- // TODO: can we union these to save on memory?
105
- Complex_Selector::Combinator mCombinator;
106
- Complex_Selector_Obj mpSelector;
107
- NodeDequePtr mpCollection;
108
- };
109
-
110
- #ifdef DEBUG
111
- std::ostream& operator<<(std::ostream& os, const Node& node);
112
- #endif
113
- Node complexSelectorToNode(Complex_Selector* pToConvert);
114
- Complex_Selector* nodeToComplexSelector(const Node& toConvert);
115
-
116
- }
117
-
118
- #endif
@@ -1,71 +0,0 @@
1
- #ifndef SASS_PATHS_H
2
- #define SASS_PATHS_H
3
-
4
- #include <string>
5
- #include <vector>
6
- #include <sstream>
7
-
8
-
9
- template<typename T>
10
- std::string vector_to_string(std::vector<T> v)
11
- {
12
- std::stringstream buffer;
13
- buffer << "[";
14
-
15
- if (!v.empty())
16
- { buffer << v[0]; }
17
- else
18
- { buffer << "]"; }
19
-
20
- if (v.size() == 1)
21
- { buffer << "]"; }
22
- else
23
- {
24
- for (size_t i = 1, S = v.size(); i < S; ++i) buffer << ", " << v[i];
25
- buffer << "]";
26
- }
27
-
28
- return buffer.str();
29
- }
30
-
31
- namespace Sass {
32
-
33
-
34
- template<typename T>
35
- std::vector<std::vector<T> > paths(std::vector<std::vector<T> > strata, size_t from_end = 0)
36
- {
37
- if (strata.empty()) {
38
- return std::vector<std::vector<T> >();
39
- }
40
-
41
- size_t end = strata.size() - from_end;
42
- if (end <= 1) {
43
- std::vector<std::vector<T> > starting_points;
44
- starting_points.reserve(strata[0].size());
45
- for (size_t i = 0, S = strata[0].size(); i < S; ++i) {
46
- std::vector<T> starting_point;
47
- starting_point.push_back(strata[0][i]);
48
- starting_points.push_back(starting_point);
49
- }
50
- return starting_points;
51
- }
52
-
53
- std::vector<std::vector<T> > up_to_here = paths(strata, from_end + 1);
54
- std::vector<T> here = strata[end-1];
55
-
56
- std::vector<std::vector<T> > branches;
57
- branches.reserve(up_to_here.size() * here.size());
58
- for (size_t i = 0, S1 = up_to_here.size(); i < S1; ++i) {
59
- for (size_t j = 0, S2 = here.size(); j < S2; ++j) {
60
- std::vector<T> branch = up_to_here[i];
61
- branch.push_back(here[j]);
62
- branches.push_back(branch);
63
- }
64
- }
65
-
66
- return branches;
67
- }
68
-
69
- }
70
-
71
- #endif