sassc 2.0.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +36 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +43 -7
  9. data/ext/depend +4 -0
  10. data/ext/extconf.rb +92 -0
  11. data/ext/libsass/VERSION +1 -0
  12. data/ext/libsass/include/sass/base.h +9 -1
  13. data/ext/libsass/include/sass/context.h +5 -1
  14. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  15. data/ext/libsass/src/ast.cpp +755 -2028
  16. data/ext/libsass/src/ast.hpp +492 -2477
  17. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  18. data/ext/libsass/src/ast2c.hpp +39 -0
  19. data/ext/libsass/src/ast_def_macros.hpp +70 -10
  20. data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
  21. data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
  22. data/ext/libsass/src/ast_helpers.hpp +292 -0
  23. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  24. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  25. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  26. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  28. data/ext/libsass/src/ast_selectors.hpp +522 -0
  29. data/ext/libsass/src/ast_supports.cpp +114 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +1154 -0
  32. data/ext/libsass/src/ast_values.hpp +498 -0
  33. data/ext/libsass/src/backtrace.cpp +11 -7
  34. data/ext/libsass/src/backtrace.hpp +5 -5
  35. data/ext/libsass/src/base64vlq.cpp +5 -2
  36. data/ext/libsass/src/base64vlq.hpp +1 -1
  37. data/ext/libsass/src/bind.cpp +35 -34
  38. data/ext/libsass/src/bind.hpp +3 -1
  39. data/ext/libsass/src/c2ast.cpp +64 -0
  40. data/ext/libsass/src/c2ast.hpp +14 -0
  41. data/ext/libsass/src/cencode.c +4 -6
  42. data/ext/libsass/src/check_nesting.cpp +83 -88
  43. data/ext/libsass/src/check_nesting.hpp +39 -34
  44. data/ext/libsass/src/color_maps.cpp +168 -164
  45. data/ext/libsass/src/color_maps.hpp +152 -160
  46. data/ext/libsass/src/constants.cpp +20 -0
  47. data/ext/libsass/src/constants.hpp +19 -0
  48. data/ext/libsass/src/context.cpp +104 -121
  49. data/ext/libsass/src/context.hpp +43 -55
  50. data/ext/libsass/src/cssize.cpp +103 -188
  51. data/ext/libsass/src/cssize.hpp +45 -51
  52. data/ext/libsass/src/dart_helpers.hpp +199 -0
  53. data/ext/libsass/src/debugger.hpp +524 -361
  54. data/ext/libsass/src/emitter.cpp +26 -26
  55. data/ext/libsass/src/emitter.hpp +20 -18
  56. data/ext/libsass/src/environment.cpp +41 -27
  57. data/ext/libsass/src/environment.hpp +33 -22
  58. data/ext/libsass/src/error_handling.cpp +92 -94
  59. data/ext/libsass/src/error_handling.hpp +73 -50
  60. data/ext/libsass/src/eval.cpp +380 -515
  61. data/ext/libsass/src/eval.hpp +64 -57
  62. data/ext/libsass/src/eval_selectors.cpp +75 -0
  63. data/ext/libsass/src/expand.cpp +322 -263
  64. data/ext/libsass/src/expand.hpp +55 -39
  65. data/ext/libsass/src/extender.cpp +1188 -0
  66. data/ext/libsass/src/extender.hpp +399 -0
  67. data/ext/libsass/src/extension.cpp +43 -0
  68. data/ext/libsass/src/extension.hpp +89 -0
  69. data/ext/libsass/src/file.cpp +134 -88
  70. data/ext/libsass/src/file.hpp +28 -37
  71. data/ext/libsass/src/fn_colors.cpp +596 -0
  72. data/ext/libsass/src/fn_colors.hpp +85 -0
  73. data/ext/libsass/src/fn_lists.cpp +285 -0
  74. data/ext/libsass/src/fn_lists.hpp +34 -0
  75. data/ext/libsass/src/fn_maps.cpp +94 -0
  76. data/ext/libsass/src/fn_maps.hpp +30 -0
  77. data/ext/libsass/src/fn_miscs.cpp +244 -0
  78. data/ext/libsass/src/fn_miscs.hpp +40 -0
  79. data/ext/libsass/src/fn_numbers.cpp +227 -0
  80. data/ext/libsass/src/fn_numbers.hpp +45 -0
  81. data/ext/libsass/src/fn_selectors.cpp +205 -0
  82. data/ext/libsass/src/fn_selectors.hpp +35 -0
  83. data/ext/libsass/src/fn_strings.cpp +268 -0
  84. data/ext/libsass/src/fn_strings.hpp +34 -0
  85. data/ext/libsass/src/fn_utils.cpp +158 -0
  86. data/ext/libsass/src/fn_utils.hpp +62 -0
  87. data/ext/libsass/src/inspect.cpp +253 -266
  88. data/ext/libsass/src/inspect.hpp +72 -74
  89. data/ext/libsass/src/json.cpp +2 -2
  90. data/ext/libsass/src/lexer.cpp +25 -84
  91. data/ext/libsass/src/lexer.hpp +5 -16
  92. data/ext/libsass/src/listize.cpp +27 -43
  93. data/ext/libsass/src/listize.hpp +14 -11
  94. data/ext/libsass/src/mapping.hpp +1 -0
  95. data/ext/libsass/src/memory.hpp +12 -0
  96. data/ext/libsass/src/memory/allocator.cpp +48 -0
  97. data/ext/libsass/src/memory/allocator.hpp +138 -0
  98. data/ext/libsass/src/memory/config.hpp +20 -0
  99. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  100. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  101. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  102. data/ext/libsass/src/operation.hpp +193 -143
  103. data/ext/libsass/src/operators.cpp +56 -29
  104. data/ext/libsass/src/operators.hpp +11 -11
  105. data/ext/libsass/src/ordered_map.hpp +112 -0
  106. data/ext/libsass/src/output.cpp +59 -75
  107. data/ext/libsass/src/output.hpp +15 -22
  108. data/ext/libsass/src/parser.cpp +662 -818
  109. data/ext/libsass/src/parser.hpp +96 -100
  110. data/ext/libsass/src/parser_selectors.cpp +189 -0
  111. data/ext/libsass/src/permutate.hpp +164 -0
  112. data/ext/libsass/src/plugins.cpp +12 -8
  113. data/ext/libsass/src/plugins.hpp +8 -8
  114. data/ext/libsass/src/position.cpp +10 -26
  115. data/ext/libsass/src/position.hpp +44 -21
  116. data/ext/libsass/src/prelexer.cpp +14 -8
  117. data/ext/libsass/src/prelexer.hpp +9 -9
  118. data/ext/libsass/src/remove_placeholders.cpp +59 -57
  119. data/ext/libsass/src/remove_placeholders.hpp +20 -18
  120. data/ext/libsass/src/sass.cpp +25 -18
  121. data/ext/libsass/src/sass.hpp +22 -14
  122. data/ext/libsass/src/sass2scss.cpp +49 -18
  123. data/ext/libsass/src/sass_context.cpp +104 -132
  124. data/ext/libsass/src/sass_context.hpp +2 -2
  125. data/ext/libsass/src/sass_functions.cpp +7 -4
  126. data/ext/libsass/src/sass_functions.hpp +1 -1
  127. data/ext/libsass/src/sass_values.cpp +26 -21
  128. data/ext/libsass/src/settings.hpp +19 -0
  129. data/ext/libsass/src/source.cpp +69 -0
  130. data/ext/libsass/src/source.hpp +95 -0
  131. data/ext/libsass/src/source_data.hpp +32 -0
  132. data/ext/libsass/src/source_map.cpp +27 -20
  133. data/ext/libsass/src/source_map.hpp +14 -11
  134. data/ext/libsass/src/stylesheet.cpp +22 -0
  135. data/ext/libsass/src/stylesheet.hpp +57 -0
  136. data/ext/libsass/src/to_value.cpp +24 -22
  137. data/ext/libsass/src/to_value.hpp +18 -22
  138. data/ext/libsass/src/units.cpp +28 -22
  139. data/ext/libsass/src/units.hpp +9 -8
  140. data/ext/libsass/src/utf8/checked.h +12 -10
  141. data/ext/libsass/src/utf8/core.h +3 -0
  142. data/ext/libsass/src/utf8_string.cpp +12 -10
  143. data/ext/libsass/src/utf8_string.hpp +7 -6
  144. data/ext/libsass/src/util.cpp +97 -107
  145. data/ext/libsass/src/util.hpp +74 -30
  146. data/ext/libsass/src/util_string.cpp +125 -0
  147. data/ext/libsass/src/util_string.hpp +73 -0
  148. data/ext/libsass/src/values.cpp +33 -24
  149. data/ext/libsass/src/values.hpp +2 -2
  150. data/lib/sassc.rb +24 -0
  151. data/lib/sassc/engine.rb +7 -5
  152. data/lib/sassc/functions_handler.rb +11 -13
  153. data/lib/sassc/native.rb +10 -9
  154. data/lib/sassc/native/native_functions_api.rb +0 -5
  155. data/lib/sassc/script.rb +4 -6
  156. data/lib/sassc/version.rb +1 -1
  157. data/sassc.gemspec +32 -12
  158. data/test/engine_test.rb +32 -2
  159. data/test/functions_test.rb +38 -1
  160. data/test/native_test.rb +4 -4
  161. metadata +95 -109
  162. data/ext/Rakefile +0 -3
  163. data/ext/libsass/.editorconfig +0 -15
  164. data/ext/libsass/.gitattributes +0 -2
  165. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  166. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  167. data/ext/libsass/.gitignore +0 -85
  168. data/ext/libsass/.travis.yml +0 -64
  169. data/ext/libsass/COPYING +0 -25
  170. data/ext/libsass/GNUmakefile.am +0 -88
  171. data/ext/libsass/INSTALL +0 -1
  172. data/ext/libsass/LICENSE +0 -25
  173. data/ext/libsass/Makefile +0 -351
  174. data/ext/libsass/Makefile.conf +0 -55
  175. data/ext/libsass/Readme.md +0 -104
  176. data/ext/libsass/SECURITY.md +0 -10
  177. data/ext/libsass/appveyor.yml +0 -91
  178. data/ext/libsass/configure.ac +0 -138
  179. data/ext/libsass/contrib/libsass.spec +0 -66
  180. data/ext/libsass/docs/README.md +0 -20
  181. data/ext/libsass/docs/api-context-example.md +0 -45
  182. data/ext/libsass/docs/api-context-internal.md +0 -163
  183. data/ext/libsass/docs/api-context.md +0 -295
  184. data/ext/libsass/docs/api-doc.md +0 -215
  185. data/ext/libsass/docs/api-function-example.md +0 -67
  186. data/ext/libsass/docs/api-function-internal.md +0 -8
  187. data/ext/libsass/docs/api-function.md +0 -74
  188. data/ext/libsass/docs/api-importer-example.md +0 -112
  189. data/ext/libsass/docs/api-importer-internal.md +0 -20
  190. data/ext/libsass/docs/api-importer.md +0 -86
  191. data/ext/libsass/docs/api-value-example.md +0 -55
  192. data/ext/libsass/docs/api-value-internal.md +0 -76
  193. data/ext/libsass/docs/api-value.md +0 -154
  194. data/ext/libsass/docs/build-on-darwin.md +0 -27
  195. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  196. data/ext/libsass/docs/build-on-windows.md +0 -139
  197. data/ext/libsass/docs/build-shared-library.md +0 -35
  198. data/ext/libsass/docs/build-with-autotools.md +0 -78
  199. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  200. data/ext/libsass/docs/build-with-mingw.md +0 -107
  201. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  202. data/ext/libsass/docs/build.md +0 -97
  203. data/ext/libsass/docs/compatibility-plan.md +0 -48
  204. data/ext/libsass/docs/contributing.md +0 -17
  205. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  206. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  207. data/ext/libsass/docs/implementations.md +0 -56
  208. data/ext/libsass/docs/plugins.md +0 -47
  209. data/ext/libsass/docs/setup-environment.md +0 -68
  210. data/ext/libsass/docs/source-map-internals.md +0 -51
  211. data/ext/libsass/docs/trace.md +0 -26
  212. data/ext/libsass/docs/triage.md +0 -17
  213. data/ext/libsass/docs/unicode.md +0 -39
  214. data/ext/libsass/extconf.rb +0 -6
  215. data/ext/libsass/include/sass/version.h.in +0 -12
  216. data/ext/libsass/m4/.gitkeep +0 -0
  217. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
  218. data/ext/libsass/res/resource.rc +0 -35
  219. data/ext/libsass/script/bootstrap +0 -13
  220. data/ext/libsass/script/branding +0 -10
  221. data/ext/libsass/script/ci-build-libsass +0 -134
  222. data/ext/libsass/script/ci-build-plugin +0 -62
  223. data/ext/libsass/script/ci-install-compiler +0 -6
  224. data/ext/libsass/script/ci-install-deps +0 -20
  225. data/ext/libsass/script/ci-report-coverage +0 -42
  226. data/ext/libsass/script/spec +0 -5
  227. data/ext/libsass/script/tap-driver +0 -652
  228. data/ext/libsass/script/tap-runner +0 -1
  229. data/ext/libsass/script/test-leaks.pl +0 -103
  230. data/ext/libsass/src/GNUmakefile.am +0 -54
  231. data/ext/libsass/src/extend.cpp +0 -2130
  232. data/ext/libsass/src/extend.hpp +0 -86
  233. data/ext/libsass/src/functions.cpp +0 -2234
  234. data/ext/libsass/src/functions.hpp +0 -198
  235. data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
  236. data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
  237. data/ext/libsass/src/node.cpp +0 -319
  238. data/ext/libsass/src/node.hpp +0 -118
  239. data/ext/libsass/src/paths.hpp +0 -71
  240. data/ext/libsass/src/sass_util.cpp +0 -149
  241. data/ext/libsass/src/sass_util.hpp +0 -256
  242. data/ext/libsass/src/subset_map.cpp +0 -55
  243. data/ext/libsass/src/subset_map.hpp +0 -76
  244. data/ext/libsass/src/support/libsass.pc.in +0 -11
  245. data/ext/libsass/src/to_c.hpp +0 -39
  246. data/ext/libsass/test/test_node.cpp +0 -94
  247. data/ext/libsass/test/test_paths.cpp +0 -28
  248. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  249. data/ext/libsass/test/test_specificity.cpp +0 -25
  250. data/ext/libsass/test/test_subset_map.cpp +0 -472
  251. data/ext/libsass/test/test_superselector.cpp +0 -69
  252. data/ext/libsass/test/test_unification.cpp +0 -31
  253. data/ext/libsass/version.sh +0 -10
  254. data/ext/libsass/win/libsass.sln +0 -39
  255. data/ext/libsass/win/libsass.sln.DotSettings +0 -9
  256. data/ext/libsass/win/libsass.targets +0 -118
  257. data/ext/libsass/win/libsass.vcxproj +0 -188
  258. data/ext/libsass/win/libsass.vcxproj.filters +0 -357
  259. data/lib/sassc/native/lib_c.rb +0 -21
  260. data/lib/tasks/libsass.rb +0 -33
@@ -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 sass::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 sass::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 sass::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 sass::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 sass::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
@@ -0,0 +1,396 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include "ast_selectors.hpp"
6
+
7
+ namespace Sass {
8
+
9
+ /*#########################################################################*/
10
+ // Compare against base class on right hand side
11
+ // try to find the most specialized implementation
12
+ /*#########################################################################*/
13
+
14
+ // Selector lists can be compared to comma lists
15
+ bool SelectorList::operator== (const Expression& rhs) const
16
+ {
17
+ if (auto l = Cast<List>(&rhs)) { return *this == *l; }
18
+ if (auto s = Cast<Selector>(&rhs)) { return *this == *s; }
19
+ if (Cast<String>(&rhs) || Cast<Null>(&rhs)) { return false; }
20
+ throw std::runtime_error("invalid selector base classes to compare");
21
+ }
22
+
23
+ // Selector lists can be compared to comma lists
24
+ bool SelectorList::operator== (const Selector& rhs) const
25
+ {
26
+ if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
27
+ if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
28
+ if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
29
+ if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
30
+ if (auto list = Cast<List>(&rhs)) { return *this == *list; }
31
+ throw std::runtime_error("invalid selector base classes to compare");
32
+ }
33
+
34
+ bool ComplexSelector::operator== (const Selector& rhs) const
35
+ {
36
+ if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
37
+ if (auto sel = Cast<ComplexSelector>(&rhs)) { return *sel == *this; }
38
+ if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
39
+ if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
40
+ throw std::runtime_error("invalid selector base classes to compare");
41
+ }
42
+
43
+ bool SelectorCombinator::operator== (const Selector& rhs) const
44
+ {
45
+ if (auto cpx = Cast<SelectorCombinator>(&rhs)) { return *this == *cpx; }
46
+ return false;
47
+ }
48
+
49
+ bool CompoundSelector::operator== (const Selector& rhs) const
50
+ {
51
+ if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
52
+ if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
53
+ if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
54
+ if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
55
+ throw std::runtime_error("invalid selector base classes to compare");
56
+ }
57
+
58
+ bool SimpleSelector::operator== (const Selector& rhs) const
59
+ {
60
+ if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
61
+ if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
62
+ if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
63
+ if (auto sel = Cast<SimpleSelector>(&rhs)) return *this == *sel;
64
+ throw std::runtime_error("invalid selector base classes to compare");
65
+ }
66
+
67
+ /*#########################################################################*/
68
+ /*#########################################################################*/
69
+
70
+ bool SelectorList::operator== (const SelectorList& rhs) const
71
+ {
72
+ if (&rhs == this) return true;
73
+ if (rhs.length() != length()) return false;
74
+ std::unordered_set<const ComplexSelector*, PtrObjHash, PtrObjEquality> lhs_set;
75
+ lhs_set.reserve(length());
76
+ for (const ComplexSelectorObj& element : elements()) {
77
+ lhs_set.insert(element.ptr());
78
+ }
79
+ for (const ComplexSelectorObj& element : rhs.elements()) {
80
+ if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
81
+ }
82
+ return true;
83
+ }
84
+
85
+
86
+
87
+ /*#########################################################################*/
88
+ // Compare SelectorList against all other selector types
89
+ /*#########################################################################*/
90
+
91
+ bool SelectorList::operator== (const ComplexSelector& rhs) const
92
+ {
93
+ // If both are empty they are equal
94
+ if (empty() && rhs.empty()) return true;
95
+ // Must have exactly one item
96
+ if (length() != 1) return false;
97
+ // Compare simple selectors
98
+ return *get(0) == rhs;
99
+ }
100
+
101
+ bool SelectorList::operator== (const CompoundSelector& rhs) const
102
+ {
103
+ // If both are empty they are equal
104
+ if (empty() && rhs.empty()) return true;
105
+ // Must have exactly one item
106
+ if (length() != 1) return false;
107
+ // Compare simple selectors
108
+ return *get(0) == rhs;
109
+ }
110
+
111
+ bool SelectorList::operator== (const SimpleSelector& rhs) const
112
+ {
113
+ // If both are empty they are equal
114
+ if (empty() && rhs.empty()) return true;
115
+ // Must have exactly one item
116
+ if (length() != 1) return false;
117
+ // Compare simple selectors
118
+ return *get(0) == rhs;
119
+ }
120
+
121
+ /*#########################################################################*/
122
+ // Compare ComplexSelector against itself
123
+ /*#########################################################################*/
124
+
125
+ bool ComplexSelector::operator== (const ComplexSelector& rhs) const
126
+ {
127
+ size_t len = length();
128
+ size_t rlen = rhs.length();
129
+ if (len != rlen) return false;
130
+ for (size_t i = 0; i < len; i += 1) {
131
+ if (*get(i) != *rhs.get(i)) return false;
132
+ }
133
+ return true;
134
+ }
135
+
136
+ /*#########################################################################*/
137
+ // Compare ComplexSelector against all other selector types
138
+ /*#########################################################################*/
139
+
140
+ bool ComplexSelector::operator== (const SelectorList& rhs) const
141
+ {
142
+ // If both are empty they are equal
143
+ if (empty() && rhs.empty()) return true;
144
+ // Must have exactly one item
145
+ if (rhs.length() != 1) return false;
146
+ // Compare complex selector
147
+ return *this == *rhs.get(0);
148
+ }
149
+
150
+ bool ComplexSelector::operator== (const CompoundSelector& rhs) const
151
+ {
152
+ // If both are empty they are equal
153
+ if (empty() && rhs.empty()) return true;
154
+ // Must have exactly one item
155
+ if (length() != 1) return false;
156
+ // Compare compound selector
157
+ return *get(0) == rhs;
158
+ }
159
+
160
+ bool ComplexSelector::operator== (const SimpleSelector& rhs) const
161
+ {
162
+ // If both are empty they are equal
163
+ if (empty() && rhs.empty()) return true;
164
+ // Must have exactly one item
165
+ if (length() != 1) return false;
166
+ // Compare simple selectors
167
+ return *get(0) == rhs;
168
+ }
169
+
170
+ /*#########################################################################*/
171
+ // Compare SelectorCombinator against itself
172
+ /*#########################################################################*/
173
+
174
+ bool SelectorCombinator::operator==(const SelectorCombinator& rhs) const
175
+ {
176
+ return combinator() == rhs.combinator();
177
+ }
178
+
179
+ /*#########################################################################*/
180
+ // Compare SelectorCombinator against SelectorComponent
181
+ /*#########################################################################*/
182
+
183
+ bool SelectorCombinator::operator==(const SelectorComponent& rhs) const
184
+ {
185
+ if (const SelectorCombinator * sel = rhs.getCombinator()) {
186
+ return *this == *sel;
187
+ }
188
+ return false;
189
+ }
190
+
191
+ bool CompoundSelector::operator==(const SelectorComponent& rhs) const
192
+ {
193
+ if (const CompoundSelector * sel = rhs.getCompound()) {
194
+ return *this == *sel;
195
+ }
196
+ return false;
197
+ }
198
+
199
+ /*#########################################################################*/
200
+ // Compare CompoundSelector against itself
201
+ /*#########################################################################*/
202
+ // ToDo: Verifiy implementation
203
+ /*#########################################################################*/
204
+
205
+ bool CompoundSelector::operator== (const CompoundSelector& rhs) const
206
+ {
207
+ // std::cerr << "comp vs comp\n";
208
+ if (&rhs == this) return true;
209
+ if (rhs.length() != length()) return false;
210
+ std::unordered_set<const SimpleSelector*, PtrObjHash, PtrObjEquality> lhs_set;
211
+ lhs_set.reserve(length());
212
+ for (const SimpleSelectorObj& element : elements()) {
213
+ lhs_set.insert(element.ptr());
214
+ }
215
+ // there is no break?!
216
+ for (const SimpleSelectorObj& element : rhs.elements()) {
217
+ if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
218
+ }
219
+ return true;
220
+ }
221
+
222
+
223
+ /*#########################################################################*/
224
+ // Compare CompoundSelector against all other selector types
225
+ /*#########################################################################*/
226
+
227
+ bool CompoundSelector::operator== (const SelectorList& rhs) const
228
+ {
229
+ // If both are empty they are equal
230
+ if (empty() && rhs.empty()) return true;
231
+ // Must have exactly one item
232
+ if (rhs.length() != 1) return false;
233
+ // Compare complex selector
234
+ return *this == *rhs.get(0);
235
+ }
236
+
237
+ bool CompoundSelector::operator== (const ComplexSelector& rhs) const
238
+ {
239
+ // If both are empty they are equal
240
+ if (empty() && rhs.empty()) return true;
241
+ // Must have exactly one item
242
+ if (rhs.length() != 1) return false;
243
+ // Compare compound selector
244
+ return *this == *rhs.get(0);
245
+ }
246
+
247
+ bool CompoundSelector::operator== (const SimpleSelector& rhs) const
248
+ {
249
+ // If both are empty they are equal
250
+ if (empty() && rhs.empty()) return false;
251
+ // Must have exactly one item
252
+ size_t rlen = length();
253
+ if (rlen > 1) return false;
254
+ if (rlen == 0) return true;
255
+ // Compare simple selectors
256
+ return *get(0) < rhs;
257
+ }
258
+
259
+ /*#########################################################################*/
260
+ // Compare SimpleSelector against itself (upcast from abstract base)
261
+ /*#########################################################################*/
262
+
263
+ // DOES NOT EXIST FOR ABSTRACT BASE CLASS
264
+
265
+ /*#########################################################################*/
266
+ // Compare SimpleSelector against all other selector types
267
+ /*#########################################################################*/
268
+
269
+ bool SimpleSelector::operator== (const SelectorList& rhs) const
270
+ {
271
+ // If both are empty they are equal
272
+ if (empty() && rhs.empty()) return true;
273
+ // Must have exactly one item
274
+ if (rhs.length() != 1) return false;
275
+ // Compare complex selector
276
+ return *this == *rhs.get(0);
277
+ }
278
+
279
+ bool SimpleSelector::operator== (const ComplexSelector& rhs) const
280
+ {
281
+ // If both are empty they are equal
282
+ if (empty() && rhs.empty()) return true;
283
+ // Must have exactly one item
284
+ if (rhs.length() != 1) return false;
285
+ // Compare compound selector
286
+ return *this == *rhs.get(0);
287
+ }
288
+
289
+ bool SimpleSelector::operator== (const CompoundSelector& rhs) const
290
+ {
291
+ // If both are empty they are equal
292
+ if (empty() && rhs.empty()) return false;
293
+ // Must have exactly one item
294
+ if (rhs.length() != 1) return false;
295
+ // Compare simple selector
296
+ return *this == *rhs.get(0);
297
+ }
298
+
299
+ /*#########################################################################*/
300
+ /*#########################################################################*/
301
+
302
+ bool IDSelector::operator== (const SimpleSelector& rhs) const
303
+ {
304
+ auto sel = Cast<IDSelector>(&rhs);
305
+ return sel ? *this == *sel : false;
306
+ }
307
+
308
+ bool TypeSelector::operator== (const SimpleSelector& rhs) const
309
+ {
310
+ auto sel = Cast<TypeSelector>(&rhs);
311
+ return sel ? *this == *sel : false;
312
+ }
313
+
314
+ bool ClassSelector::operator== (const SimpleSelector& rhs) const
315
+ {
316
+ auto sel = Cast<ClassSelector>(&rhs);
317
+ return sel ? *this == *sel : false;
318
+ }
319
+
320
+ bool PseudoSelector::operator== (const SimpleSelector& rhs) const
321
+ {
322
+ auto sel = Cast<PseudoSelector>(&rhs);
323
+ return sel ? *this == *sel : false;
324
+ }
325
+
326
+ bool AttributeSelector::operator== (const SimpleSelector& rhs) const
327
+ {
328
+ auto sel = Cast<AttributeSelector>(&rhs);
329
+ return sel ? *this == *sel : false;
330
+ }
331
+
332
+ bool PlaceholderSelector::operator== (const SimpleSelector& rhs) const
333
+ {
334
+ auto sel = Cast<PlaceholderSelector>(&rhs);
335
+ return sel ? *this == *sel : false;
336
+ }
337
+
338
+ /*#########################################################################*/
339
+ /*#########################################################################*/
340
+
341
+ bool IDSelector::operator== (const IDSelector& rhs) const
342
+ {
343
+ // ID has no namespacing
344
+ return name() == rhs.name();
345
+ }
346
+
347
+ bool TypeSelector::operator== (const TypeSelector& rhs) const
348
+ {
349
+ return is_ns_eq(rhs) && name() == rhs.name();
350
+ }
351
+
352
+ bool ClassSelector::operator== (const ClassSelector& rhs) const
353
+ {
354
+ // Class has no namespacing
355
+ return name() == rhs.name();
356
+ }
357
+
358
+ bool PlaceholderSelector::operator== (const PlaceholderSelector& rhs) const
359
+ {
360
+ // Placeholder has no namespacing
361
+ return name() == rhs.name();
362
+ }
363
+
364
+ bool AttributeSelector::operator== (const AttributeSelector& rhs) const
365
+ {
366
+ // smaller return, equal go on, bigger abort
367
+ if (is_ns_eq(rhs)) {
368
+ if (name() != rhs.name()) return false;
369
+ if (matcher() != rhs.matcher()) return false;
370
+ if (modifier() != rhs.modifier()) return false;
371
+ const String* lhs_val = value();
372
+ const String* rhs_val = rhs.value();
373
+ return PtrObjEquality()(lhs_val, rhs_val);
374
+ }
375
+ else { return false; }
376
+ }
377
+
378
+ bool PseudoSelector::operator== (const PseudoSelector& rhs) const
379
+ {
380
+ if (is_ns_eq(rhs)) {
381
+ if (name() != rhs.name()) return false;
382
+ if (isElement() != rhs.isElement()) return false;
383
+ const String* lhs_arg = argument();
384
+ const String* rhs_arg = rhs.argument();
385
+ if (!PtrObjEquality()(lhs_arg, rhs_arg)) return false;
386
+ const SelectorList* lhs_sel = selector();
387
+ const SelectorList* rhs_sel = rhs.selector();
388
+ return PtrObjEquality()(lhs_sel, rhs_sel);
389
+ }
390
+ else { return false; }
391
+ }
392
+
393
+ /*#########################################################################*/
394
+ /*#########################################################################*/
395
+
396
+ }