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
11namespace 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 sass::string& name)
232 {
233 return Util::equalsLiteral(lit: "after", test: name)
234 || Util::equalsLiteral(lit: "before", test: name)
235 || Util::equalsLiteral(lit: "first-line", test: name)
236 || Util::equalsLiteral(lit: "first-letter", test: 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 sass::string& norm)
245 {
246 return Util::equalsLiteral(lit: "any", test: norm)
247 || Util::equalsLiteral(lit: "matches", test: norm)
248 || Util::equalsLiteral(lit: "nth-child", test: norm)
249 || Util::equalsLiteral(lit: "nth-last-child", test: norm);
250 }
251 // EO isSubselectorPseudo
252
253 // ###########################################################################
254 // Pseudo-class selectors that take unadorned selectors as arguments.
255 // ###########################################################################
256 inline bool isSelectorPseudoClass(const sass::string& test)
257 {
258 return Util::equalsLiteral(lit: "not", test)
259 || Util::equalsLiteral(lit: "matches", test)
260 || Util::equalsLiteral(lit: "current", test)
261 || Util::equalsLiteral(lit: "any", test)
262 || Util::equalsLiteral(lit: "has", test)
263 || Util::equalsLiteral(lit: "host", test)
264 || Util::equalsLiteral(lit: "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 sass::string& test)
272 {
273 return Util::equalsLiteral(lit: "slotted", test);
274 }
275 // EO isSelectorPseudoElement
276
277 // ###########################################################################
278 // Pseudo-element selectors that has binominals
279 // ###########################################################################
280 inline bool isSelectorPseudoBinominal(const sass::string& test)
281 {
282 return Util::equalsLiteral(lit: "nth-child", test)
283 || Util::equalsLiteral(lit: "nth-last-child", test);
284 }
285 // isSelectorPseudoBinominal
286
287 // ###########################################################################
288 // ###########################################################################
289
290}
291
292#endif
293

source code of gtk/subprojects/libsass/src/ast_helpers.hpp