sassc 2.2.1 → 2.3.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +13 -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 +1 -0
  9. data/ext/libsass/src/ast.cpp +49 -59
  10. data/ext/libsass/src/ast.hpp +263 -102
  11. data/ext/libsass/src/ast_def_macros.hpp +8 -0
  12. data/ext/libsass/src/ast_fwd_decl.cpp +2 -1
  13. data/ext/libsass/src/ast_fwd_decl.hpp +40 -116
  14. data/ext/libsass/src/ast_helpers.hpp +292 -0
  15. data/ext/libsass/src/ast_sel_cmp.cpp +209 -722
  16. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  17. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  18. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  19. data/ext/libsass/src/ast_selectors.cpp +559 -1001
  20. data/ext/libsass/src/ast_selectors.hpp +311 -367
  21. data/ext/libsass/src/ast_supports.cpp +1 -17
  22. data/ext/libsass/src/ast_values.cpp +216 -29
  23. data/ext/libsass/src/ast_values.hpp +42 -33
  24. data/ext/libsass/src/bind.cpp +1 -1
  25. data/ext/libsass/src/cencode.c +4 -6
  26. data/ext/libsass/src/check_nesting.cpp +5 -6
  27. data/ext/libsass/src/check_nesting.hpp +4 -0
  28. data/ext/libsass/src/color_maps.cpp +11 -10
  29. data/ext/libsass/src/color_maps.hpp +0 -8
  30. data/ext/libsass/src/constants.cpp +5 -0
  31. data/ext/libsass/src/constants.hpp +6 -0
  32. data/ext/libsass/src/context.cpp +30 -60
  33. data/ext/libsass/src/context.hpp +8 -20
  34. data/ext/libsass/src/cssize.cpp +36 -120
  35. data/ext/libsass/src/cssize.hpp +4 -10
  36. data/ext/libsass/src/dart_helpers.hpp +199 -0
  37. data/ext/libsass/src/debugger.hpp +364 -207
  38. data/ext/libsass/src/emitter.cpp +3 -4
  39. data/ext/libsass/src/emitter.hpp +0 -2
  40. data/ext/libsass/src/environment.hpp +5 -0
  41. data/ext/libsass/src/error_handling.cpp +21 -0
  42. data/ext/libsass/src/error_handling.hpp +25 -3
  43. data/ext/libsass/src/eval.cpp +33 -153
  44. data/ext/libsass/src/eval.hpp +11 -13
  45. data/ext/libsass/src/eval_selectors.cpp +75 -0
  46. data/ext/libsass/src/expand.cpp +214 -167
  47. data/ext/libsass/src/expand.hpp +26 -6
  48. data/ext/libsass/src/extender.cpp +1186 -0
  49. data/ext/libsass/src/extender.hpp +399 -0
  50. data/ext/libsass/src/extension.cpp +43 -0
  51. data/ext/libsass/src/extension.hpp +89 -0
  52. data/ext/libsass/src/file.cpp +15 -14
  53. data/ext/libsass/src/file.hpp +5 -12
  54. data/ext/libsass/src/fn_colors.cpp +12 -10
  55. data/ext/libsass/src/fn_lists.cpp +12 -11
  56. data/ext/libsass/src/fn_miscs.cpp +22 -34
  57. data/ext/libsass/src/fn_numbers.cpp +13 -6
  58. data/ext/libsass/src/fn_selectors.cpp +94 -124
  59. data/ext/libsass/src/fn_strings.cpp +16 -14
  60. data/ext/libsass/src/fn_utils.cpp +5 -6
  61. data/ext/libsass/src/fn_utils.hpp +9 -3
  62. data/ext/libsass/src/inspect.cpp +154 -117
  63. data/ext/libsass/src/inspect.hpp +10 -8
  64. data/ext/libsass/src/lexer.cpp +17 -81
  65. data/ext/libsass/src/lexer.hpp +5 -16
  66. data/ext/libsass/src/listize.cpp +22 -36
  67. data/ext/libsass/src/listize.hpp +8 -9
  68. data/ext/libsass/src/memory/SharedPtr.hpp +39 -5
  69. data/ext/libsass/src/operation.hpp +27 -17
  70. data/ext/libsass/src/operators.cpp +1 -0
  71. data/ext/libsass/src/ordered_map.hpp +112 -0
  72. data/ext/libsass/src/output.cpp +30 -49
  73. data/ext/libsass/src/output.hpp +1 -1
  74. data/ext/libsass/src/parser.cpp +211 -381
  75. data/ext/libsass/src/parser.hpp +17 -15
  76. data/ext/libsass/src/parser_selectors.cpp +189 -0
  77. data/ext/libsass/src/permutate.hpp +140 -0
  78. data/ext/libsass/src/position.hpp +1 -1
  79. data/ext/libsass/src/prelexer.cpp +6 -6
  80. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  81. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  82. data/ext/libsass/src/sass.hpp +1 -0
  83. data/ext/libsass/src/sass2scss.cpp +4 -4
  84. data/ext/libsass/src/sass_context.cpp +42 -91
  85. data/ext/libsass/src/sass_context.hpp +2 -2
  86. data/ext/libsass/src/sass_functions.cpp +1 -1
  87. data/ext/libsass/src/sass_values.cpp +0 -1
  88. data/ext/libsass/src/stylesheet.cpp +22 -0
  89. data/ext/libsass/src/stylesheet.hpp +57 -0
  90. data/ext/libsass/src/to_value.cpp +2 -2
  91. data/ext/libsass/src/to_value.hpp +1 -1
  92. data/ext/libsass/src/units.cpp +5 -3
  93. data/ext/libsass/src/util.cpp +10 -12
  94. data/ext/libsass/src/util.hpp +2 -3
  95. data/ext/libsass/src/util_string.cpp +111 -61
  96. data/ext/libsass/src/util_string.hpp +61 -8
  97. data/lib/sassc/engine.rb +5 -3
  98. data/lib/sassc/functions_handler.rb +8 -8
  99. data/lib/sassc/native.rb +1 -1
  100. data/lib/sassc/script.rb +4 -4
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/functions_test.rb +18 -1
  103. data/test/native_test.rb +1 -1
  104. metadata +17 -12
  105. data/ext/libsass/src/extend.cpp +0 -2132
  106. data/ext/libsass/src/extend.hpp +0 -86
  107. data/ext/libsass/src/node.cpp +0 -322
  108. data/ext/libsass/src/node.hpp +0 -118
  109. data/ext/libsass/src/paths.hpp +0 -71
  110. data/ext/libsass/src/sass_util.cpp +0 -152
  111. data/ext/libsass/src/sass_util.hpp +0 -256
  112. data/ext/libsass/src/subset_map.cpp +0 -58
  113. data/ext/libsass/src/subset_map.hpp +0 -76
@@ -101,6 +101,14 @@ private:
101
101
 
102
102
  #endif
103
103
 
104
+ #define ATTACH_VIRTUAL_CMP_OPERATIONS(klass) \
105
+ virtual bool operator==(const klass& rhs) const = 0; \
106
+ virtual bool operator!=(const klass& rhs) const { return !(*this == rhs); }; \
107
+
108
+ #define ATTACH_CMP_OPERATIONS(klass) \
109
+ virtual bool operator==(const klass& rhs) const; \
110
+ virtual bool operator!=(const klass& rhs) const { return !(*this == rhs); }; \
111
+
104
112
  #ifdef DEBUG_SHARED_PTR
105
113
 
106
114
  #define IMPLEMENT_AST_OPERATORS(klass) \
@@ -25,6 +25,7 @@ namespace Sass {
25
25
  IMPLEMENT_BASE_CAST(String_Constant)
26
26
  IMPLEMENT_BASE_CAST(Supports_Condition)
27
27
  IMPLEMENT_BASE_CAST(Selector)
28
- IMPLEMENT_BASE_CAST(Simple_Selector)
28
+ IMPLEMENT_BASE_CAST(SelectorComponent)
29
+ IMPLEMENT_BASE_CAST(SimpleSelector)
29
30
 
30
31
  }
@@ -1,17 +1,12 @@
1
1
  #ifndef SASS_AST_FWD_DECL_H
2
2
  #define SASS_AST_FWD_DECL_H
3
3
 
4
- #include <map>
5
- #include <set>
6
- #include <deque>
7
- #include <vector>
8
- #include <typeinfo>
9
- #include <iostream>
10
- #include <algorithm>
11
- #include <unordered_map>
12
- #include <unordered_set>
13
- #include "memory/SharedPtr.hpp"
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
7
+
14
8
  #include "sass/functions.h"
9
+ #include "memory/SharedPtr.hpp"
15
10
 
16
11
  /////////////////////////////////////////////
17
12
  // Forward declarations for the AST visitors.
@@ -22,7 +17,7 @@ namespace Sass {
22
17
 
23
18
  class Has_Block;
24
19
 
25
- class Simple_Selector;
20
+ class SimpleSelector;
26
21
 
27
22
  class Parent_Reference;
28
23
 
@@ -36,11 +31,13 @@ namespace Sass {
36
31
  class Bubble;
37
32
  class Trace;
38
33
 
39
- class Media_Block;
34
+ class MediaRule;
35
+ class CssMediaRule;
36
+ class CssMediaQuery;
37
+
40
38
  class Supports_Block;
41
39
  class Directive;
42
40
 
43
-
44
41
  class Keyframe_Rule;
45
42
  class At_Root_Block;
46
43
  class Assignment;
@@ -59,7 +56,7 @@ namespace Sass {
59
56
  class While;
60
57
  class Return;
61
58
  class Content;
62
- class Extension;
59
+ class ExtendRule;
63
60
  class Definition;
64
61
 
65
62
  class List;
@@ -80,6 +77,7 @@ namespace Sass {
80
77
  class Color_HSLA;
81
78
  class Boolean;
82
79
  class String;
80
+ class Null;
83
81
 
84
82
  class String_Schema;
85
83
  class String_Constant;
@@ -92,12 +90,8 @@ namespace Sass {
92
90
  class Supports_Negation;
93
91
  class Supports_Declaration;
94
92
  class Supports_Interpolation;
95
-
96
-
97
- class Null;
98
-
93
+
99
94
  class At_Root_Query;
100
- class Parent_Selector;
101
95
  class Parameter;
102
96
  class Parameters;
103
97
  class Argument;
@@ -113,20 +107,26 @@ namespace Sass {
113
107
  class Attribute_Selector;
114
108
 
115
109
  class Pseudo_Selector;
116
- class Wrapped_Selector;
117
- class Compound_Selector;
118
- class Complex_Selector;
119
- class Selector_List;
120
-
110
+
111
+ class SelectorComponent;
112
+ class SelectorCombinator;
113
+ class CompoundSelector;
114
+ class ComplexSelector;
115
+ class SelectorList;
121
116
 
122
117
  // common classes
123
118
  class Context;
124
119
  class Expand;
125
120
  class Eval;
126
121
 
122
+ class Extension;
123
+
127
124
  // declare classes that are instances of memory nodes
128
- // #define IMPL_MEM_OBJ(type) using type##_Obj = SharedImpl<type>
129
- #define IMPL_MEM_OBJ(type) typedef SharedImpl<type> type##_Obj
125
+ // Note: also add a mapping without underscore
126
+ // ToDo: move to camelCase vars in the future
127
+ #define IMPL_MEM_OBJ(type) \
128
+ typedef SharedImpl<type> type##Obj; \
129
+ typedef SharedImpl<type> type##_Obj; \
130
130
 
131
131
  IMPL_MEM_OBJ(AST_Node);
132
132
  IMPL_MEM_OBJ(Statement);
@@ -134,7 +134,9 @@ namespace Sass {
134
134
  IMPL_MEM_OBJ(Ruleset);
135
135
  IMPL_MEM_OBJ(Bubble);
136
136
  IMPL_MEM_OBJ(Trace);
137
- IMPL_MEM_OBJ(Media_Block);
137
+ IMPL_MEM_OBJ(MediaRule);
138
+ IMPL_MEM_OBJ(CssMediaRule);
139
+ IMPL_MEM_OBJ(CssMediaQuery);
138
140
  IMPL_MEM_OBJ(Supports_Block);
139
141
  IMPL_MEM_OBJ(Directive);
140
142
  IMPL_MEM_OBJ(Keyframe_Rule);
@@ -155,7 +157,7 @@ namespace Sass {
155
157
  IMPL_MEM_OBJ(While);
156
158
  IMPL_MEM_OBJ(Return);
157
159
  IMPL_MEM_OBJ(Content);
158
- IMPL_MEM_OBJ(Extension);
160
+ IMPL_MEM_OBJ(ExtendRule);
159
161
  IMPL_MEM_OBJ(Definition);
160
162
  IMPL_MEM_OBJ(Mixin_Call);
161
163
  IMPL_MEM_OBJ(Value);
@@ -187,7 +189,6 @@ namespace Sass {
187
189
  IMPL_MEM_OBJ(Supports_Interpolation);
188
190
  IMPL_MEM_OBJ(At_Root_Query);
189
191
  IMPL_MEM_OBJ(Null);
190
- IMPL_MEM_OBJ(Parent_Selector);
191
192
  IMPL_MEM_OBJ(Parent_Reference);
192
193
  IMPL_MEM_OBJ(Parameter);
193
194
  IMPL_MEM_OBJ(Parameters);
@@ -195,107 +196,29 @@ namespace Sass {
195
196
  IMPL_MEM_OBJ(Arguments);
196
197
  IMPL_MEM_OBJ(Selector);
197
198
  IMPL_MEM_OBJ(Selector_Schema);
198
- IMPL_MEM_OBJ(Simple_Selector);
199
+ IMPL_MEM_OBJ(SimpleSelector);
199
200
  IMPL_MEM_OBJ(Placeholder_Selector);
200
201
  IMPL_MEM_OBJ(Type_Selector);
201
202
  IMPL_MEM_OBJ(Class_Selector);
202
203
  IMPL_MEM_OBJ(Id_Selector);
203
204
  IMPL_MEM_OBJ(Attribute_Selector);
204
205
  IMPL_MEM_OBJ(Pseudo_Selector);
205
- IMPL_MEM_OBJ(Wrapped_Selector);
206
- IMPL_MEM_OBJ(Compound_Selector);
207
- IMPL_MEM_OBJ(Complex_Selector);
208
- IMPL_MEM_OBJ(Selector_List);
209
206
 
210
- // ###########################################################################
211
- // Implement compare, order and hashing operations for AST Nodes
212
- // ###########################################################################
213
-
214
- struct HashNodes {
215
- template <class T>
216
- size_t operator() (const T& ex) const {
217
- return ex.isNull() ? 0 : ex->hash();
218
- }
219
- };
220
- template <class T>
221
- bool OrderFunction(const T& lhs, const T& rhs) {
222
- return !lhs.isNull() && !rhs.isNull() && *lhs < *rhs;
223
- };
224
- struct OrderNodes {
225
- template <class T>
226
- bool operator() (const T& lhs, const T& rhs) const {
227
- return OrderFunction<T>(lhs, rhs);
228
- }
229
- };
230
- template <class T>
231
- bool CompareFunction(const T& lhs, const T& rhs) {
232
- // code around sass logic issue. 1px == 1 is true
233
- // but both items are still different keys in maps
234
- if (dynamic_cast<Number*>(lhs.ptr()))
235
- if (dynamic_cast<Number*>(rhs.ptr()))
236
- return lhs->hash() == rhs->hash();
237
- return !lhs.isNull() && !rhs.isNull() && *lhs == *rhs;
238
- }
239
- struct CompareNodes {
240
- template <class T>
241
- bool operator() (const T& lhs, const T& rhs) const {
242
- return CompareFunction<T>(lhs, rhs);
243
- }
244
- };
245
-
246
- struct HashPtr {
247
- template <class T>
248
- size_t operator() (const T *ref) const {
249
- return ref->hash();
250
- }
251
- };
252
- struct ComparePtrs {
253
- template <class T>
254
- bool operator() (const T *lhs, const T *rhs) const {
255
- return *lhs == *rhs;
256
- }
257
- };
207
+ IMPL_MEM_OBJ(SelectorComponent);
208
+ IMPL_MEM_OBJ(SelectorCombinator);
209
+ IMPL_MEM_OBJ(CompoundSelector);
210
+ IMPL_MEM_OBJ(ComplexSelector);
211
+ IMPL_MEM_OBJ(SelectorList);
258
212
 
259
213
  // ###########################################################################
260
214
  // some often used typedefs
261
215
  // ###########################################################################
262
216
 
263
- typedef std::unordered_map<
264
- Expression_Obj, // key
265
- Expression_Obj, // value
266
- HashNodes, // hasher
267
- CompareNodes // compare
268
- > ExpressionMap;
269
- typedef std::unordered_set<
270
- Expression_Obj, // value
271
- HashNodes, // hasher
272
- CompareNodes // compare
273
- > ExpressionSet;
274
-
275
- typedef std::string SubSetMapKey;
276
- typedef std::vector<std::string> SubSetMapKeys;
277
-
278
- typedef std::pair<Complex_Selector_Obj, Compound_Selector_Obj> SubSetMapPair;
279
- typedef std::pair<Compound_Selector_Obj, Complex_Selector_Obj> SubSetMapLookup;
280
- typedef std::vector<SubSetMapPair> SubSetMapPairs;
281
- typedef std::vector<SubSetMapLookup> SubSetMapLookups;
282
-
283
- typedef std::pair<Complex_Selector_Obj, SubSetMapPairs> SubSetMapResult;
284
- typedef std::vector<SubSetMapResult> SubSetMapResults;
285
-
286
- typedef std::set<Selector_Obj, OrderNodes> SelectorSet;
287
-
288
- typedef std::deque<Complex_Selector_Obj> ComplexSelectorDeque;
289
- typedef std::set<Simple_Selector_Obj, OrderNodes> SimpleSelectorSet;
290
- typedef std::set<Complex_Selector_Obj, OrderNodes> ComplexSelectorSet;
291
- typedef std::set<Compound_Selector_Obj, OrderNodes> CompoundSelectorSet;
292
- typedef std::unordered_set<Simple_Selector_Obj, HashNodes, CompareNodes> SimpleSelectorDict;
293
-
294
217
  typedef std::vector<Block*> BlockStack;
295
218
  typedef std::vector<Sass_Callee> CalleeStack;
296
219
  typedef std::vector<AST_Node_Obj> CallStack;
297
- typedef std::vector<Media_Block*> MediaStack;
298
- typedef std::vector<Selector_List_Obj> SelectorStack;
220
+ typedef std::vector<CssMediaRuleObj> MediaStack;
221
+ typedef std::vector<SelectorListObj> SelectorStack;
299
222
  typedef std::vector<Sass_Import_Entry> ImporterStack;
300
223
 
301
224
  // only to switch implementations for testing
@@ -334,7 +257,8 @@ namespace Sass {
334
257
  DECLARE_BASE_CAST(String_Constant)
335
258
  DECLARE_BASE_CAST(Supports_Condition)
336
259
  DECLARE_BASE_CAST(Selector)
337
- DECLARE_BASE_CAST(Simple_Selector)
260
+ DECLARE_BASE_CAST(SimpleSelector)
261
+ DECLARE_BASE_CAST(SelectorComponent)
338
262
 
339
263
  }
340
264
 
@@ -0,0 +1,292 @@
1
+ #ifndef SASS_AST_HELPERS_H
2
+ #define SASS_AST_HELPERS_H
3
+
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
7
+ #include <algorithm>
8
+ #include <functional>
9
+ #include "util_string.hpp"
10
+
11
+ namespace Sass {
12
+
13
+ // ###########################################################################
14
+ // ###########################################################################
15
+
16
+ // easier to search with name
17
+ const bool DELAYED = true;
18
+
19
+ // ToDo: should this really be hardcoded
20
+ // Note: most methods follow precision option
21
+ const double NUMBER_EPSILON = 1e-12;
22
+
23
+ // macro to test if numbers are equal within a small error margin
24
+ #define NEAR_EQUAL(lhs, rhs) std::fabs(lhs - rhs) < NUMBER_EPSILON
25
+
26
+ // ###########################################################################
27
+ // We define various functions and functors here.
28
+ // Functions satisfy the BinaryPredicate requirement
29
+ // Functors are structs used for e.g. unordered_map
30
+ // ###########################################################################
31
+
32
+ // ###########################################################################
33
+ // Implement compare and hashing operations for raw pointers
34
+ // ###########################################################################
35
+
36
+ template <class T>
37
+ size_t PtrHashFn(const T* ptr) {
38
+ return std::hash<std::size_t>()((size_t)ptr);
39
+ }
40
+
41
+ struct PtrHash {
42
+ template <class T>
43
+ size_t operator() (const T* ptr) const {
44
+ return PtrHashFn(ptr);
45
+ }
46
+ };
47
+
48
+ template <class T>
49
+ bool PtrEqualityFn(const T* lhs, const T* rhs) {
50
+ return lhs == rhs; // compare raw pointers
51
+ }
52
+
53
+ struct PtrEquality {
54
+ template <class T>
55
+ bool operator() (const T* lhs, const T* rhs) const {
56
+ return PtrEqualityFn<T>(lhs, rhs);
57
+ }
58
+ };
59
+
60
+ // ###########################################################################
61
+ // Implement compare and hashing operations for AST Nodes
62
+ // ###########################################################################
63
+
64
+ // TODO: get rid of funtions and use ObjEquality<T>
65
+
66
+ template <class T>
67
+ // Hash the raw pointer instead of object
68
+ size_t ObjPtrHashFn(const T& obj) {
69
+ return PtrHashFn(obj.ptr());
70
+ }
71
+
72
+ struct ObjPtrHash {
73
+ template <class T>
74
+ // Hash the raw pointer instead of object
75
+ size_t operator() (const T& obj) const {
76
+ return ObjPtrHashFn(obj);
77
+ }
78
+ };
79
+
80
+ template <class T>
81
+ // Hash the object and its content
82
+ size_t ObjHashFn(const T& obj) {
83
+ return obj ? obj->hash() : 0;
84
+ }
85
+
86
+ struct ObjHash {
87
+ template <class T>
88
+ // Hash the object and its content
89
+ size_t operator() (const T& obj) const {
90
+ return ObjHashFn(obj);
91
+ }
92
+ };
93
+
94
+ template <class T>
95
+ // Hash the object behind pointer
96
+ size_t PtrObjHashFn(const T* obj) {
97
+ return obj ? obj->hash() : 0;
98
+ }
99
+
100
+ struct PtrObjHash {
101
+ template <class T>
102
+ // Hash the object behind pointer
103
+ size_t operator() (const T* obj) const {
104
+ return PtrObjHashFn(obj);
105
+ }
106
+ };
107
+
108
+ template <class T>
109
+ // Compare raw pointers to the object
110
+ bool ObjPtrEqualityFn(const T& lhs, const T& rhs) {
111
+ return PtrEqualityFn(lhs.ptr(), rhs.ptr());
112
+ }
113
+
114
+ struct ObjPtrEquality {
115
+ template <class T>
116
+ // Compare raw pointers to the object
117
+ bool operator() (const T& lhs, const T& rhs) const {
118
+ return ObjPtrEqualityFn<T>(lhs, rhs);
119
+ }
120
+ };
121
+
122
+ template <class T>
123
+ // Compare the objects behind the pointers
124
+ bool PtrObjEqualityFn(const T* lhs, const T* rhs) {
125
+ if (lhs == nullptr) return rhs == nullptr;
126
+ else if (rhs == nullptr) return false;
127
+ else return *lhs == *rhs;
128
+ }
129
+
130
+ struct PtrObjEquality {
131
+ template <class T>
132
+ // Compare the objects behind the pointers
133
+ bool operator() (const T* lhs, const T* rhs) const {
134
+ return PtrObjEqualityFn<T>(lhs, rhs);
135
+ }
136
+ };
137
+
138
+ template <class T>
139
+ // Compare the objects and its contents
140
+ bool ObjEqualityFn(const T& lhs, const T& rhs) {
141
+ return PtrObjEqualityFn(lhs.ptr(), rhs.ptr());
142
+ }
143
+
144
+ struct ObjEquality {
145
+ template <class T>
146
+ // Compare the objects and its contents
147
+ bool operator() (const T& lhs, const T& rhs) const {
148
+ return ObjEqualityFn<T>(lhs, rhs);
149
+ }
150
+ };
151
+
152
+ // ###########################################################################
153
+ // Implement ordering operations for AST Nodes
154
+ // ###########################################################################
155
+
156
+ template <class T>
157
+ // Compare the objects behind pointers
158
+ bool PtrObjLessThanFn(const T* lhs, const T* rhs) {
159
+ if (lhs == nullptr) return rhs != nullptr;
160
+ else if (rhs == nullptr) return false;
161
+ else return *lhs < *rhs;
162
+ }
163
+
164
+ struct PtrObjLessThan {
165
+ template <class T>
166
+ // Compare the objects behind pointers
167
+ bool operator() (const T* lhs, const T* rhs) const {
168
+ return PtrObjLessThanFn<T>(lhs, rhs);
169
+ }
170
+ };
171
+
172
+ template <class T>
173
+ // Compare the objects and its content
174
+ bool ObjLessThanFn(const T& lhs, const T& rhs) {
175
+ return PtrObjLessThanFn(lhs.ptr(), rhs.ptr());
176
+ };
177
+
178
+ struct ObjLessThan {
179
+ template <class T>
180
+ // Compare the objects and its content
181
+ bool operator() (const T& lhs, const T& rhs) const {
182
+ return ObjLessThanFn<T>(lhs, rhs);
183
+ }
184
+ };
185
+
186
+ // ###########################################################################
187
+ // Some STL helper functions
188
+ // ###########################################################################
189
+
190
+ // Check if all elements are equal
191
+ template <class X, class Y,
192
+ typename XT = typename X::value_type,
193
+ typename YT = typename Y::value_type>
194
+ bool ListEquality(const X& lhs, const Y& rhs,
195
+ bool(*cmp)(const XT*, const YT*))
196
+ {
197
+ return lhs.size() == rhs.size() &&
198
+ std::equal(lhs.begin(), lhs.end(),
199
+ rhs.begin(), cmp);
200
+ }
201
+
202
+ // Return if Vector is empty
203
+ template <class T>
204
+ bool listIsEmpty(T* cnt) {
205
+ return cnt && cnt->empty();
206
+ }
207
+
208
+ // Erase items from vector that match predicate
209
+ template<class T, class UnaryPredicate>
210
+ void listEraseItemIf(T& vec, UnaryPredicate* predicate)
211
+ {
212
+ vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end());
213
+ }
214
+
215
+ // Check that every item in `lhs` is also in `rhs`
216
+ // Note: this works by comparing the raw pointers
217
+ template <typename T>
218
+ bool listIsSubsetOrEqual(const T& lhs, const T& rhs) {
219
+ for (const auto& item : lhs) {
220
+ if (std::find(rhs.begin(), rhs.end(), item) == rhs.end())
221
+ return false;
222
+ }
223
+ return true;
224
+ }
225
+
226
+ // ##########################################################################
227
+ // Returns whether [name] is the name of a pseudo-element
228
+ // that can be written with pseudo-class syntax (CSS2 vs CSS3):
229
+ // `:before`, `:after`, `:first-line`, or `:first-letter`
230
+ // ##########################################################################
231
+ inline bool isFakePseudoElement(const std::string& name)
232
+ {
233
+ return Util::equalsLiteral("after", name)
234
+ || Util::equalsLiteral("before", name)
235
+ || Util::equalsLiteral("first-line", name)
236
+ || Util::equalsLiteral("first-letter", name);
237
+ }
238
+
239
+ // ##########################################################################
240
+ // Names of pseudo selectors that take selectors as arguments,
241
+ // and that are subselectors of their arguments.
242
+ // For example, `.foo` is a superselector of `:matches(.foo)`.
243
+ // ##########################################################################
244
+ inline bool isSubselectorPseudo(const std::string& norm)
245
+ {
246
+ return Util::equalsLiteral("any", norm)
247
+ || Util::equalsLiteral("matches", norm)
248
+ || Util::equalsLiteral("nth-child", norm)
249
+ || Util::equalsLiteral("nth-last-child", norm);
250
+ }
251
+ // EO isSubselectorPseudo
252
+
253
+ // ###########################################################################
254
+ // Pseudo-class selectors that take unadorned selectors as arguments.
255
+ // ###########################################################################
256
+ inline bool isSelectorPseudoClass(const std::string& test)
257
+ {
258
+ return Util::equalsLiteral("not", test)
259
+ || Util::equalsLiteral("matches", test)
260
+ || Util::equalsLiteral("current", test)
261
+ || Util::equalsLiteral("any", test)
262
+ || Util::equalsLiteral("has", test)
263
+ || Util::equalsLiteral("host", test)
264
+ || Util::equalsLiteral("host-context", test);
265
+ }
266
+ // EO isSelectorPseudoClass
267
+
268
+ // ###########################################################################
269
+ // Pseudo-element selectors that take unadorned selectors as arguments.
270
+ // ###########################################################################
271
+ inline bool isSelectorPseudoElement(const std::string& test)
272
+ {
273
+ return Util::equalsLiteral("slotted", test);
274
+ }
275
+ // EO isSelectorPseudoElement
276
+
277
+ // ###########################################################################
278
+ // Pseudo-element selectors that has binominals
279
+ // ###########################################################################
280
+ inline bool isSelectorPseudoBinominal(const std::string& test)
281
+ {
282
+ return Util::equalsLiteral("nth-child", test)
283
+ || Util::equalsLiteral("nth-last-child", test);
284
+ }
285
+ // isSelectorPseudoBinominal
286
+
287
+ // ###########################################################################
288
+ // ###########################################################################
289
+
290
+ }
291
+
292
+ #endif