sassc 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +13 -0
- data/Rakefile +1 -3
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +1 -0
- data/ext/libsass/src/ast.cpp +49 -59
- data/ext/libsass/src/ast.hpp +263 -102
- data/ext/libsass/src/ast_def_macros.hpp +8 -0
- data/ext/libsass/src/ast_fwd_decl.cpp +2 -1
- data/ext/libsass/src/ast_fwd_decl.hpp +40 -116
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +209 -722
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +559 -1001
- data/ext/libsass/src/ast_selectors.hpp +311 -367
- data/ext/libsass/src/ast_supports.cpp +1 -17
- data/ext/libsass/src/ast_values.cpp +216 -29
- data/ext/libsass/src/ast_values.hpp +42 -33
- data/ext/libsass/src/bind.cpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +5 -6
- data/ext/libsass/src/check_nesting.hpp +4 -0
- data/ext/libsass/src/color_maps.cpp +11 -10
- data/ext/libsass/src/color_maps.hpp +0 -8
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +30 -60
- data/ext/libsass/src/context.hpp +8 -20
- data/ext/libsass/src/cssize.cpp +36 -120
- data/ext/libsass/src/cssize.hpp +4 -10
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +364 -207
- data/ext/libsass/src/emitter.cpp +3 -4
- data/ext/libsass/src/emitter.hpp +0 -2
- data/ext/libsass/src/environment.hpp +5 -0
- data/ext/libsass/src/error_handling.cpp +21 -0
- data/ext/libsass/src/error_handling.hpp +25 -3
- data/ext/libsass/src/eval.cpp +33 -153
- data/ext/libsass/src/eval.hpp +11 -13
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +214 -167
- data/ext/libsass/src/expand.hpp +26 -6
- data/ext/libsass/src/extender.cpp +1186 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +15 -14
- data/ext/libsass/src/file.hpp +5 -12
- data/ext/libsass/src/fn_colors.cpp +12 -10
- data/ext/libsass/src/fn_lists.cpp +12 -11
- data/ext/libsass/src/fn_miscs.cpp +22 -34
- data/ext/libsass/src/fn_numbers.cpp +13 -6
- data/ext/libsass/src/fn_selectors.cpp +94 -124
- data/ext/libsass/src/fn_strings.cpp +16 -14
- data/ext/libsass/src/fn_utils.cpp +5 -6
- data/ext/libsass/src/fn_utils.hpp +9 -3
- data/ext/libsass/src/inspect.cpp +154 -117
- data/ext/libsass/src/inspect.hpp +10 -8
- data/ext/libsass/src/lexer.cpp +17 -81
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +22 -36
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/memory/SharedPtr.hpp +39 -5
- data/ext/libsass/src/operation.hpp +27 -17
- data/ext/libsass/src/operators.cpp +1 -0
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +30 -49
- data/ext/libsass/src/output.hpp +1 -1
- data/ext/libsass/src/parser.cpp +211 -381
- data/ext/libsass/src/parser.hpp +17 -15
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +140 -0
- data/ext/libsass/src/position.hpp +1 -1
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.hpp +1 -0
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +42 -91
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +0 -1
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +5 -3
- data/ext/libsass/src/util.cpp +10 -12
- data/ext/libsass/src/util.hpp +2 -3
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +61 -8
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +1 -1
- data/lib/sassc/script.rb +4 -4
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +18 -1
- data/test/native_test.rb +1 -1
- metadata +17 -12
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
data/ext/libsass/src/extend.hpp
DELETED
@@ -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
|
data/ext/libsass/src/node.cpp
DELETED
@@ -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
|
-
}
|
data/ext/libsass/src/node.hpp
DELETED
@@ -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
|