precompiled-sassc 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/cibuildgem.yaml +67 -0
  3. data/.gitignore +18 -0
  4. data/.gitmodules +3 -0
  5. data/.travis.yml +16 -0
  6. data/CHANGELOG.md +97 -0
  7. data/CODE_OF_CONDUCT.md +10 -0
  8. data/Gemfile +2 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +80 -0
  11. data/Rakefile +51 -0
  12. data/ext/depend +4 -0
  13. data/ext/extconf.rb +92 -0
  14. data/ext/libsass/VERSION +1 -0
  15. data/ext/libsass/contrib/plugin.cpp +60 -0
  16. data/ext/libsass/include/sass/base.h +97 -0
  17. data/ext/libsass/include/sass/context.h +174 -0
  18. data/ext/libsass/include/sass/functions.h +139 -0
  19. data/ext/libsass/include/sass/values.h +145 -0
  20. data/ext/libsass/include/sass/version.h +12 -0
  21. data/ext/libsass/include/sass.h +15 -0
  22. data/ext/libsass/include/sass2scss.h +120 -0
  23. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  24. data/ext/libsass/src/ast.cpp +953 -0
  25. data/ext/libsass/src/ast.hpp +1064 -0
  26. data/ext/libsass/src/ast2c.cpp +80 -0
  27. data/ext/libsass/src/ast2c.hpp +39 -0
  28. data/ext/libsass/src/ast_def_macros.hpp +140 -0
  29. data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
  30. data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
  31. data/ext/libsass/src/ast_helpers.hpp +292 -0
  32. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  33. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  34. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  35. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  36. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  37. data/ext/libsass/src/ast_selectors.hpp +522 -0
  38. data/ext/libsass/src/ast_supports.cpp +114 -0
  39. data/ext/libsass/src/ast_supports.hpp +121 -0
  40. data/ext/libsass/src/ast_values.cpp +1154 -0
  41. data/ext/libsass/src/ast_values.hpp +498 -0
  42. data/ext/libsass/src/b64/cencode.h +32 -0
  43. data/ext/libsass/src/b64/encode.h +79 -0
  44. data/ext/libsass/src/backtrace.cpp +50 -0
  45. data/ext/libsass/src/backtrace.hpp +29 -0
  46. data/ext/libsass/src/base64vlq.cpp +47 -0
  47. data/ext/libsass/src/base64vlq.hpp +30 -0
  48. data/ext/libsass/src/bind.cpp +312 -0
  49. data/ext/libsass/src/bind.hpp +15 -0
  50. data/ext/libsass/src/c2ast.cpp +64 -0
  51. data/ext/libsass/src/c2ast.hpp +14 -0
  52. data/ext/libsass/src/c99func.c +54 -0
  53. data/ext/libsass/src/cencode.c +106 -0
  54. data/ext/libsass/src/check_nesting.cpp +393 -0
  55. data/ext/libsass/src/check_nesting.hpp +70 -0
  56. data/ext/libsass/src/color_maps.cpp +652 -0
  57. data/ext/libsass/src/color_maps.hpp +323 -0
  58. data/ext/libsass/src/constants.cpp +199 -0
  59. data/ext/libsass/src/constants.hpp +200 -0
  60. data/ext/libsass/src/context.cpp +863 -0
  61. data/ext/libsass/src/context.hpp +140 -0
  62. data/ext/libsass/src/cssize.cpp +521 -0
  63. data/ext/libsass/src/cssize.hpp +71 -0
  64. data/ext/libsass/src/dart_helpers.hpp +199 -0
  65. data/ext/libsass/src/debug.hpp +43 -0
  66. data/ext/libsass/src/debugger.hpp +963 -0
  67. data/ext/libsass/src/emitter.cpp +297 -0
  68. data/ext/libsass/src/emitter.hpp +101 -0
  69. data/ext/libsass/src/environment.cpp +260 -0
  70. data/ext/libsass/src/environment.hpp +124 -0
  71. data/ext/libsass/src/error_handling.cpp +233 -0
  72. data/ext/libsass/src/error_handling.hpp +239 -0
  73. data/ext/libsass/src/eval.cpp +1543 -0
  74. data/ext/libsass/src/eval.hpp +110 -0
  75. data/ext/libsass/src/eval_selectors.cpp +75 -0
  76. data/ext/libsass/src/expand.cpp +875 -0
  77. data/ext/libsass/src/expand.hpp +98 -0
  78. data/ext/libsass/src/extender.cpp +1188 -0
  79. data/ext/libsass/src/extender.hpp +399 -0
  80. data/ext/libsass/src/extension.cpp +43 -0
  81. data/ext/libsass/src/extension.hpp +89 -0
  82. data/ext/libsass/src/file.cpp +531 -0
  83. data/ext/libsass/src/file.hpp +124 -0
  84. data/ext/libsass/src/fn_colors.cpp +596 -0
  85. data/ext/libsass/src/fn_colors.hpp +85 -0
  86. data/ext/libsass/src/fn_lists.cpp +285 -0
  87. data/ext/libsass/src/fn_lists.hpp +34 -0
  88. data/ext/libsass/src/fn_maps.cpp +94 -0
  89. data/ext/libsass/src/fn_maps.hpp +30 -0
  90. data/ext/libsass/src/fn_miscs.cpp +244 -0
  91. data/ext/libsass/src/fn_miscs.hpp +40 -0
  92. data/ext/libsass/src/fn_numbers.cpp +227 -0
  93. data/ext/libsass/src/fn_numbers.hpp +45 -0
  94. data/ext/libsass/src/fn_selectors.cpp +205 -0
  95. data/ext/libsass/src/fn_selectors.hpp +35 -0
  96. data/ext/libsass/src/fn_strings.cpp +268 -0
  97. data/ext/libsass/src/fn_strings.hpp +34 -0
  98. data/ext/libsass/src/fn_utils.cpp +158 -0
  99. data/ext/libsass/src/fn_utils.hpp +62 -0
  100. data/ext/libsass/src/inspect.cpp +1125 -0
  101. data/ext/libsass/src/inspect.hpp +101 -0
  102. data/ext/libsass/src/json.cpp +1436 -0
  103. data/ext/libsass/src/json.hpp +117 -0
  104. data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
  105. data/ext/libsass/src/lexer.cpp +122 -0
  106. data/ext/libsass/src/lexer.hpp +304 -0
  107. data/ext/libsass/src/listize.cpp +70 -0
  108. data/ext/libsass/src/listize.hpp +37 -0
  109. data/ext/libsass/src/mapping.hpp +19 -0
  110. data/ext/libsass/src/memory/allocator.cpp +48 -0
  111. data/ext/libsass/src/memory/allocator.hpp +138 -0
  112. data/ext/libsass/src/memory/config.hpp +20 -0
  113. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  114. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  115. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  116. data/ext/libsass/src/memory.hpp +12 -0
  117. data/ext/libsass/src/operation.hpp +223 -0
  118. data/ext/libsass/src/operators.cpp +267 -0
  119. data/ext/libsass/src/operators.hpp +30 -0
  120. data/ext/libsass/src/ordered_map.hpp +112 -0
  121. data/ext/libsass/src/output.cpp +320 -0
  122. data/ext/libsass/src/output.hpp +47 -0
  123. data/ext/libsass/src/parser.cpp +2965 -0
  124. data/ext/libsass/src/parser.hpp +394 -0
  125. data/ext/libsass/src/parser_selectors.cpp +189 -0
  126. data/ext/libsass/src/permutate.hpp +164 -0
  127. data/ext/libsass/src/plugins.cpp +188 -0
  128. data/ext/libsass/src/plugins.hpp +57 -0
  129. data/ext/libsass/src/position.cpp +165 -0
  130. data/ext/libsass/src/position.hpp +147 -0
  131. data/ext/libsass/src/prelexer.cpp +1780 -0
  132. data/ext/libsass/src/prelexer.hpp +484 -0
  133. data/ext/libsass/src/remove_placeholders.cpp +86 -0
  134. data/ext/libsass/src/remove_placeholders.hpp +37 -0
  135. data/ext/libsass/src/sass.cpp +156 -0
  136. data/ext/libsass/src/sass.hpp +147 -0
  137. data/ext/libsass/src/sass2scss.cpp +895 -0
  138. data/ext/libsass/src/sass_context.cpp +741 -0
  139. data/ext/libsass/src/sass_context.hpp +129 -0
  140. data/ext/libsass/src/sass_functions.cpp +210 -0
  141. data/ext/libsass/src/sass_functions.hpp +50 -0
  142. data/ext/libsass/src/sass_values.cpp +362 -0
  143. data/ext/libsass/src/sass_values.hpp +82 -0
  144. data/ext/libsass/src/settings.hpp +19 -0
  145. data/ext/libsass/src/source.cpp +69 -0
  146. data/ext/libsass/src/source.hpp +95 -0
  147. data/ext/libsass/src/source_data.hpp +32 -0
  148. data/ext/libsass/src/source_map.cpp +202 -0
  149. data/ext/libsass/src/source_map.hpp +65 -0
  150. data/ext/libsass/src/stylesheet.cpp +22 -0
  151. data/ext/libsass/src/stylesheet.hpp +57 -0
  152. data/ext/libsass/src/to_value.cpp +114 -0
  153. data/ext/libsass/src/to_value.hpp +46 -0
  154. data/ext/libsass/src/units.cpp +507 -0
  155. data/ext/libsass/src/units.hpp +110 -0
  156. data/ext/libsass/src/utf8/checked.h +336 -0
  157. data/ext/libsass/src/utf8/core.h +332 -0
  158. data/ext/libsass/src/utf8/unchecked.h +235 -0
  159. data/ext/libsass/src/utf8.h +34 -0
  160. data/ext/libsass/src/utf8_string.cpp +104 -0
  161. data/ext/libsass/src/utf8_string.hpp +38 -0
  162. data/ext/libsass/src/util.cpp +723 -0
  163. data/ext/libsass/src/util.hpp +105 -0
  164. data/ext/libsass/src/util_string.cpp +125 -0
  165. data/ext/libsass/src/util_string.hpp +73 -0
  166. data/ext/libsass/src/values.cpp +140 -0
  167. data/ext/libsass/src/values.hpp +12 -0
  168. data/lib/sassc/dependency.rb +17 -0
  169. data/lib/sassc/engine.rb +141 -0
  170. data/lib/sassc/error.rb +37 -0
  171. data/lib/sassc/functions_handler.rb +73 -0
  172. data/lib/sassc/import_handler.rb +50 -0
  173. data/lib/sassc/importer.rb +31 -0
  174. data/lib/sassc/native/native_context_api.rb +147 -0
  175. data/lib/sassc/native/native_functions_api.rb +159 -0
  176. data/lib/sassc/native/sass2scss_api.rb +10 -0
  177. data/lib/sassc/native/sass_input_style.rb +13 -0
  178. data/lib/sassc/native/sass_output_style.rb +12 -0
  179. data/lib/sassc/native/sass_value.rb +97 -0
  180. data/lib/sassc/native/string_list.rb +10 -0
  181. data/lib/sassc/native.rb +65 -0
  182. data/lib/sassc/sass_2_scss.rb +9 -0
  183. data/lib/sassc/script/functions.rb +8 -0
  184. data/lib/sassc/script/value/bool.rb +32 -0
  185. data/lib/sassc/script/value/color.rb +95 -0
  186. data/lib/sassc/script/value/list.rb +136 -0
  187. data/lib/sassc/script/value/map.rb +69 -0
  188. data/lib/sassc/script/value/number.rb +389 -0
  189. data/lib/sassc/script/value/string.rb +96 -0
  190. data/lib/sassc/script/value.rb +137 -0
  191. data/lib/sassc/script/value_conversion/base.rb +13 -0
  192. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  193. data/lib/sassc/script/value_conversion/color.rb +18 -0
  194. data/lib/sassc/script/value_conversion/list.rb +25 -0
  195. data/lib/sassc/script/value_conversion/map.rb +21 -0
  196. data/lib/sassc/script/value_conversion/number.rb +13 -0
  197. data/lib/sassc/script/value_conversion/string.rb +17 -0
  198. data/lib/sassc/script/value_conversion.rb +69 -0
  199. data/lib/sassc/script.rb +17 -0
  200. data/lib/sassc/util/normalized_map.rb +117 -0
  201. data/lib/sassc/util.rb +231 -0
  202. data/lib/sassc/version.rb +5 -0
  203. data/lib/sassc.rb +57 -0
  204. data/sassc.gemspec +69 -0
  205. data/test/custom_importer_test.rb +127 -0
  206. data/test/engine_test.rb +314 -0
  207. data/test/error_test.rb +29 -0
  208. data/test/fixtures/paths.scss +10 -0
  209. data/test/functions_test.rb +340 -0
  210. data/test/native_test.rb +213 -0
  211. data/test/output_style_test.rb +107 -0
  212. data/test/sass_2_scss_test.rb +14 -0
  213. data/test/test_helper.rb +45 -0
  214. metadata +391 -0
@@ -0,0 +1,1125 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include <cmath>
6
+ #include <string>
7
+ #include <iostream>
8
+ #include <iomanip>
9
+ #include <stdint.h>
10
+ #include <stdint.h>
11
+
12
+ #include "ast.hpp"
13
+ #include "inspect.hpp"
14
+ #include "context.hpp"
15
+ #include "listize.hpp"
16
+ #include "color_maps.hpp"
17
+ #include "utf8/checked.h"
18
+
19
+ namespace Sass {
20
+
21
+ Inspect::Inspect(const Emitter& emi)
22
+ : Emitter(emi)
23
+ { }
24
+ Inspect::~Inspect() { }
25
+
26
+ // statements
27
+ void Inspect::operator()(Block* block)
28
+ {
29
+ if (!block->is_root()) {
30
+ add_open_mapping(block);
31
+ append_scope_opener();
32
+ }
33
+ if (output_style() == NESTED) indentation += block->tabs();
34
+ for (size_t i = 0, L = block->length(); i < L; ++i) {
35
+ (*block)[i]->perform(this);
36
+ }
37
+ if (output_style() == NESTED) indentation -= block->tabs();
38
+ if (!block->is_root()) {
39
+ append_scope_closer();
40
+ add_close_mapping(block);
41
+ }
42
+
43
+ }
44
+
45
+ void Inspect::operator()(StyleRule* ruleset)
46
+ {
47
+ if (ruleset->selector()) {
48
+ ruleset->selector()->perform(this);
49
+ }
50
+ if (ruleset->block()) {
51
+ ruleset->block()->perform(this);
52
+ }
53
+ }
54
+
55
+ void Inspect::operator()(Keyframe_Rule* rule)
56
+ {
57
+ if (rule->name()) rule->name()->perform(this);
58
+ if (rule->block()) rule->block()->perform(this);
59
+ }
60
+
61
+ void Inspect::operator()(Bubble* bubble)
62
+ {
63
+ append_indentation();
64
+ append_token("::BUBBLE", bubble);
65
+ append_scope_opener();
66
+ bubble->node()->perform(this);
67
+ append_scope_closer();
68
+ }
69
+
70
+ void Inspect::operator()(MediaRule* rule)
71
+ {
72
+ append_indentation();
73
+ append_token("@media", rule);
74
+ append_mandatory_space();
75
+ if (rule->block()) {
76
+ rule->block()->perform(this);
77
+ }
78
+ }
79
+
80
+ void Inspect::operator()(CssMediaRule* rule)
81
+ {
82
+ if (output_style() == NESTED)
83
+ indentation += rule->tabs();
84
+ append_indentation();
85
+ append_token("@media", rule);
86
+ append_mandatory_space();
87
+ in_media_block = true;
88
+ bool joinIt = false;
89
+ for (auto query : rule->elements()) {
90
+ if (joinIt) {
91
+ append_comma_separator();
92
+ append_optional_space();
93
+ }
94
+ operator()(query);
95
+ joinIt = true;
96
+ }
97
+ if (rule->block()) {
98
+ rule->block()->perform(this);
99
+ }
100
+ in_media_block = false;
101
+ if (output_style() == NESTED)
102
+ indentation -= rule->tabs();
103
+ }
104
+
105
+ void Inspect::operator()(CssMediaQuery* query)
106
+ {
107
+ bool joinIt = false;
108
+ if (!query->modifier().empty()) {
109
+ append_string(query->modifier());
110
+ append_mandatory_space();
111
+ }
112
+ if (!query->type().empty()) {
113
+ append_string(query->type());
114
+ joinIt = true;
115
+ }
116
+ for (auto feature : query->features()) {
117
+ if (joinIt) {
118
+ append_mandatory_space();
119
+ append_string("and");
120
+ append_mandatory_space();
121
+ }
122
+ append_string(feature);
123
+ joinIt = true;
124
+ }
125
+ }
126
+
127
+ void Inspect::operator()(SupportsRule* feature_block)
128
+ {
129
+ append_indentation();
130
+ append_token("@supports", feature_block);
131
+ append_mandatory_space();
132
+ feature_block->condition()->perform(this);
133
+ feature_block->block()->perform(this);
134
+ }
135
+
136
+ void Inspect::operator()(AtRootRule* at_root_block)
137
+ {
138
+ append_indentation();
139
+ append_token("@at-root ", at_root_block);
140
+ append_mandatory_space();
141
+ if(at_root_block->expression()) at_root_block->expression()->perform(this);
142
+ if(at_root_block->block()) at_root_block->block()->perform(this);
143
+ }
144
+
145
+ void Inspect::operator()(AtRule* at_rule)
146
+ {
147
+ append_indentation();
148
+ append_token(at_rule->keyword(), at_rule);
149
+ if (at_rule->selector()) {
150
+ append_mandatory_space();
151
+ bool was_wrapped = in_wrapped;
152
+ in_wrapped = true;
153
+ at_rule->selector()->perform(this);
154
+ in_wrapped = was_wrapped;
155
+ }
156
+ if (at_rule->value()) {
157
+ append_mandatory_space();
158
+ at_rule->value()->perform(this);
159
+ }
160
+ if (at_rule->block()) {
161
+ at_rule->block()->perform(this);
162
+ }
163
+ else {
164
+ append_delimiter();
165
+ }
166
+ }
167
+
168
+ void Inspect::operator()(Declaration* dec)
169
+ {
170
+ if (dec->value()->concrete_type() == Expression::NULL_VAL) return;
171
+ bool was_decl = in_declaration;
172
+ in_declaration = true;
173
+ LOCAL_FLAG(in_custom_property, dec->is_custom_property());
174
+
175
+ if (output_style() == NESTED)
176
+ indentation += dec->tabs();
177
+ append_indentation();
178
+ if (dec->property())
179
+ dec->property()->perform(this);
180
+ append_colon_separator();
181
+
182
+ if (dec->value()->concrete_type() == Expression::SELECTOR) {
183
+ ExpressionObj ls = Listize::perform(dec->value());
184
+ ls->perform(this);
185
+ } else {
186
+ dec->value()->perform(this);
187
+ }
188
+
189
+ if (dec->is_important()) {
190
+ append_optional_space();
191
+ append_string("!important");
192
+ }
193
+ append_delimiter();
194
+ if (output_style() == NESTED)
195
+ indentation -= dec->tabs();
196
+ in_declaration = was_decl;
197
+ }
198
+
199
+ void Inspect::operator()(Assignment* assn)
200
+ {
201
+ append_token(assn->variable(), assn);
202
+ append_colon_separator();
203
+ assn->value()->perform(this);
204
+ if (assn->is_default()) {
205
+ append_optional_space();
206
+ append_string("!default");
207
+ }
208
+ append_delimiter();
209
+ }
210
+
211
+ void Inspect::operator()(Import* import)
212
+ {
213
+ if (!import->urls().empty()) {
214
+ append_token("@import", import);
215
+ append_mandatory_space();
216
+
217
+ import->urls().front()->perform(this);
218
+ if (import->urls().size() == 1) {
219
+ if (import->import_queries()) {
220
+ append_mandatory_space();
221
+ import->import_queries()->perform(this);
222
+ }
223
+ }
224
+ append_delimiter();
225
+ for (size_t i = 1, S = import->urls().size(); i < S; ++i) {
226
+ append_mandatory_linefeed();
227
+ append_token("@import", import);
228
+ append_mandatory_space();
229
+
230
+ import->urls()[i]->perform(this);
231
+ if (import->urls().size() - 1 == i) {
232
+ if (import->import_queries()) {
233
+ append_mandatory_space();
234
+ import->import_queries()->perform(this);
235
+ }
236
+ }
237
+ append_delimiter();
238
+ }
239
+ }
240
+ }
241
+
242
+ void Inspect::operator()(Import_Stub* import)
243
+ {
244
+ append_indentation();
245
+ append_token("@import", import);
246
+ append_mandatory_space();
247
+ append_string(import->imp_path());
248
+ append_delimiter();
249
+ }
250
+
251
+ void Inspect::operator()(WarningRule* warning)
252
+ {
253
+ append_indentation();
254
+ append_token("@warn", warning);
255
+ append_mandatory_space();
256
+ warning->message()->perform(this);
257
+ append_delimiter();
258
+ }
259
+
260
+ void Inspect::operator()(ErrorRule* error)
261
+ {
262
+ append_indentation();
263
+ append_token("@error", error);
264
+ append_mandatory_space();
265
+ error->message()->perform(this);
266
+ append_delimiter();
267
+ }
268
+
269
+ void Inspect::operator()(DebugRule* debug)
270
+ {
271
+ append_indentation();
272
+ append_token("@debug", debug);
273
+ append_mandatory_space();
274
+ debug->value()->perform(this);
275
+ append_delimiter();
276
+ }
277
+
278
+ void Inspect::operator()(Comment* comment)
279
+ {
280
+ in_comment = true;
281
+ comment->text()->perform(this);
282
+ in_comment = false;
283
+ }
284
+
285
+ void Inspect::operator()(If* cond)
286
+ {
287
+ append_indentation();
288
+ append_token("@if", cond);
289
+ append_mandatory_space();
290
+ cond->predicate()->perform(this);
291
+ cond->block()->perform(this);
292
+ if (cond->alternative()) {
293
+ append_optional_linefeed();
294
+ append_indentation();
295
+ append_string("else");
296
+ cond->alternative()->perform(this);
297
+ }
298
+ }
299
+
300
+ void Inspect::operator()(ForRule* loop)
301
+ {
302
+ append_indentation();
303
+ append_token("@for", loop);
304
+ append_mandatory_space();
305
+ append_string(loop->variable());
306
+ append_string(" from ");
307
+ loop->lower_bound()->perform(this);
308
+ append_string(loop->is_inclusive() ? " through " : " to ");
309
+ loop->upper_bound()->perform(this);
310
+ loop->block()->perform(this);
311
+ }
312
+
313
+ void Inspect::operator()(EachRule* loop)
314
+ {
315
+ append_indentation();
316
+ append_token("@each", loop);
317
+ append_mandatory_space();
318
+ append_string(loop->variables()[0]);
319
+ for (size_t i = 1, L = loop->variables().size(); i < L; ++i) {
320
+ append_comma_separator();
321
+ append_string(loop->variables()[i]);
322
+ }
323
+ append_string(" in ");
324
+ loop->list()->perform(this);
325
+ loop->block()->perform(this);
326
+ }
327
+
328
+ void Inspect::operator()(WhileRule* loop)
329
+ {
330
+ append_indentation();
331
+ append_token("@while", loop);
332
+ append_mandatory_space();
333
+ loop->predicate()->perform(this);
334
+ loop->block()->perform(this);
335
+ }
336
+
337
+ void Inspect::operator()(Return* ret)
338
+ {
339
+ append_indentation();
340
+ append_token("@return", ret);
341
+ append_mandatory_space();
342
+ ret->value()->perform(this);
343
+ append_delimiter();
344
+ }
345
+
346
+ void Inspect::operator()(ExtendRule* extend)
347
+ {
348
+ append_indentation();
349
+ append_token("@extend", extend);
350
+ append_mandatory_space();
351
+ extend->selector()->perform(this);
352
+ append_delimiter();
353
+ }
354
+
355
+ void Inspect::operator()(Definition* def)
356
+ {
357
+ append_indentation();
358
+ if (def->type() == Definition::MIXIN) {
359
+ append_token("@mixin", def);
360
+ append_mandatory_space();
361
+ } else {
362
+ append_token("@function", def);
363
+ append_mandatory_space();
364
+ }
365
+ append_string(def->name());
366
+ def->parameters()->perform(this);
367
+ def->block()->perform(this);
368
+ }
369
+
370
+ void Inspect::operator()(Mixin_Call* call)
371
+ {
372
+ append_indentation();
373
+ append_token("@include", call);
374
+ append_mandatory_space();
375
+ append_string(call->name());
376
+ if (call->arguments()) {
377
+ call->arguments()->perform(this);
378
+ }
379
+ if (call->block()) {
380
+ append_optional_space();
381
+ call->block()->perform(this);
382
+ }
383
+ if (!call->block()) append_delimiter();
384
+ }
385
+
386
+ void Inspect::operator()(Content* content)
387
+ {
388
+ append_indentation();
389
+ append_token("@content", content);
390
+ append_delimiter();
391
+ }
392
+
393
+ void Inspect::operator()(Map* map)
394
+ {
395
+ if (output_style() == TO_SASS && map->empty()) {
396
+ append_string("()");
397
+ return;
398
+ }
399
+ if (map->empty()) return;
400
+ if (map->is_invisible()) return;
401
+ bool items_output = false;
402
+ append_string("(");
403
+ for (auto key : map->keys()) {
404
+ if (items_output) append_comma_separator();
405
+ key->perform(this);
406
+ append_colon_separator();
407
+ LOCAL_FLAG(in_space_array, true);
408
+ LOCAL_FLAG(in_comma_array, true);
409
+ map->at(key)->perform(this);
410
+ items_output = true;
411
+ }
412
+ append_string(")");
413
+ }
414
+
415
+ sass::string Inspect::lbracket(List* list) {
416
+ return list->is_bracketed() ? "[" : "(";
417
+ }
418
+
419
+ sass::string Inspect::rbracket(List* list) {
420
+ return list->is_bracketed() ? "]" : ")";
421
+ }
422
+
423
+ void Inspect::operator()(List* list)
424
+ {
425
+ if (list->empty() && (output_style() == TO_SASS || list->is_bracketed())) {
426
+ append_string(lbracket(list));
427
+ append_string(rbracket(list));
428
+ return;
429
+ }
430
+ sass::string sep(list->separator() == SASS_SPACE ? " " : ",");
431
+ if ((output_style() != COMPRESSED) && sep == ",") sep += " ";
432
+ else if (in_media_block && sep != " ") sep += " "; // verified
433
+ if (list->empty()) return;
434
+ bool items_output = false;
435
+
436
+ bool was_space_array = in_space_array;
437
+ bool was_comma_array = in_comma_array;
438
+ // if the list is bracketed, always include the left bracket
439
+ if (list->is_bracketed()) {
440
+ append_string(lbracket(list));
441
+ }
442
+ // probably ruby sass eqivalent of element_needs_parens
443
+ else if (output_style() == TO_SASS &&
444
+ list->length() == 1 &&
445
+ !list->from_selector() &&
446
+ !Cast<List>(list->at(0)) &&
447
+ !Cast<SelectorList>(list->at(0))
448
+ ) {
449
+ append_string(lbracket(list));
450
+ }
451
+ else if (!in_declaration && (list->separator() == SASS_HASH ||
452
+ (list->separator() == SASS_SPACE && in_space_array) ||
453
+ (list->separator() == SASS_COMMA && in_comma_array)
454
+ )) {
455
+ append_string(lbracket(list));
456
+ }
457
+
458
+ if (list->separator() == SASS_SPACE) in_space_array = true;
459
+ else if (list->separator() == SASS_COMMA) in_comma_array = true;
460
+
461
+ for (size_t i = 0, L = list->size(); i < L; ++i) {
462
+ if (list->separator() == SASS_HASH)
463
+ { sep[0] = i % 2 ? ':' : ','; }
464
+ ExpressionObj list_item = list->at(i);
465
+ if (output_style() != TO_SASS) {
466
+ if (list_item->is_invisible()) {
467
+ // this fixes an issue with "" in a list
468
+ if (!Cast<String_Constant>(list_item)) {
469
+ continue;
470
+ }
471
+ }
472
+ }
473
+ if (items_output) {
474
+ append_string(sep);
475
+ }
476
+ if (items_output && sep != " ")
477
+ append_optional_space();
478
+ list_item->perform(this);
479
+ items_output = true;
480
+ }
481
+
482
+ in_comma_array = was_comma_array;
483
+ in_space_array = was_space_array;
484
+
485
+ // if the list is bracketed, always include the right bracket
486
+ if (list->is_bracketed()) {
487
+ if (list->separator() == SASS_COMMA && list->size() == 1) {
488
+ append_string(",");
489
+ }
490
+ append_string(rbracket(list));
491
+ }
492
+ // probably ruby sass eqivalent of element_needs_parens
493
+ else if (output_style() == TO_SASS &&
494
+ list->length() == 1 &&
495
+ !list->from_selector() &&
496
+ !Cast<List>(list->at(0)) &&
497
+ !Cast<SelectorList>(list->at(0))
498
+ ) {
499
+ append_string(",");
500
+ append_string(rbracket(list));
501
+ }
502
+ else if (!in_declaration && (list->separator() == SASS_HASH ||
503
+ (list->separator() == SASS_SPACE && in_space_array) ||
504
+ (list->separator() == SASS_COMMA && in_comma_array)
505
+ )) {
506
+ append_string(rbracket(list));
507
+ }
508
+
509
+ }
510
+
511
+ void Inspect::operator()(Binary_Expression* expr)
512
+ {
513
+ expr->left()->perform(this);
514
+ if ( in_media_block ||
515
+ (output_style() == INSPECT) || (
516
+ expr->op().ws_before
517
+ && (!expr->is_interpolant())
518
+ && (expr->is_left_interpolant() ||
519
+ expr->is_right_interpolant())
520
+
521
+ )) append_string(" ");
522
+ switch (expr->optype()) {
523
+ case Sass_OP::AND: append_string("&&"); break;
524
+ case Sass_OP::OR: append_string("||"); break;
525
+ case Sass_OP::EQ: append_string("=="); break;
526
+ case Sass_OP::NEQ: append_string("!="); break;
527
+ case Sass_OP::GT: append_string(">"); break;
528
+ case Sass_OP::GTE: append_string(">="); break;
529
+ case Sass_OP::LT: append_string("<"); break;
530
+ case Sass_OP::LTE: append_string("<="); break;
531
+ case Sass_OP::ADD: append_string("+"); break;
532
+ case Sass_OP::SUB: append_string("-"); break;
533
+ case Sass_OP::MUL: append_string("*"); break;
534
+ case Sass_OP::DIV: append_string("/"); break;
535
+ case Sass_OP::MOD: append_string("%"); break;
536
+ default: break; // shouldn't get here
537
+ }
538
+ if ( in_media_block ||
539
+ (output_style() == INSPECT) || (
540
+ expr->op().ws_after
541
+ && (!expr->is_interpolant())
542
+ && (expr->is_left_interpolant() ||
543
+ expr->is_right_interpolant())
544
+ )) append_string(" ");
545
+ expr->right()->perform(this);
546
+ }
547
+
548
+ void Inspect::operator()(Unary_Expression* expr)
549
+ {
550
+ if (expr->optype() == Unary_Expression::PLUS) append_string("+");
551
+ else if (expr->optype() == Unary_Expression::SLASH) append_string("/");
552
+ else append_string("-");
553
+ expr->operand()->perform(this);
554
+ }
555
+
556
+ void Inspect::operator()(Function_Call* call)
557
+ {
558
+ append_token(call->name(), call);
559
+ call->arguments()->perform(this);
560
+ }
561
+
562
+ void Inspect::operator()(Variable* var)
563
+ {
564
+ append_token(var->name(), var);
565
+ }
566
+
567
+ void Inspect::operator()(Number* n)
568
+ {
569
+
570
+ // reduce units
571
+ n->reduce();
572
+
573
+ sass::ostream ss;
574
+ ss.precision(opt.precision);
575
+ ss << std::fixed << n->value();
576
+
577
+ sass::string res = ss.str();
578
+ size_t s = res.length();
579
+
580
+ // delete trailing zeros
581
+ for(s = s - 1; s > 0; --s)
582
+ {
583
+ if(res[s] == '0') {
584
+ res.erase(s, 1);
585
+ }
586
+ else break;
587
+ }
588
+
589
+ // delete trailing decimal separator
590
+ if(res[s] == '.') res.erase(s, 1);
591
+
592
+ // some final cosmetics
593
+ if (res == "0.0") res = "0";
594
+ else if (res == "") res = "0";
595
+ else if (res == "-0") res = "0";
596
+ else if (res == "-0.0") res = "0";
597
+ else if (opt.output_style == COMPRESSED)
598
+ {
599
+ if (n->zero()) {
600
+ // check if handling negative nr
601
+ size_t off = res[0] == '-' ? 1 : 0;
602
+ // remove leading zero from floating point in compressed mode
603
+ if (res[off] == '0' && res[off+1] == '.') res.erase(off, 1);
604
+ }
605
+ }
606
+
607
+ // add unit now
608
+ res += n->unit();
609
+
610
+ if (opt.output_style == TO_CSS && !n->is_valid_css_unit()) {
611
+ // traces.push_back(Backtrace(nr->pstate()));
612
+ throw Exception::InvalidValue({}, *n);
613
+ }
614
+
615
+ // output the final token
616
+ append_token(res, n);
617
+ }
618
+
619
+ // helper function for serializing colors
620
+ template <size_t range>
621
+ static double cap_channel(double c) {
622
+ if (c > range) return range;
623
+ else if (c < 0) return 0;
624
+ else return c;
625
+ }
626
+
627
+ void Inspect::operator()(Color_RGBA* c)
628
+ {
629
+ // output the final token
630
+ sass::ostream ss;
631
+
632
+ // original color name
633
+ // maybe an unknown token
634
+ sass::string name = c->disp();
635
+
636
+ // resolved color
637
+ sass::string res_name = name;
638
+
639
+ double r = Sass::round(cap_channel<0xff>(c->r()), opt.precision);
640
+ double g = Sass::round(cap_channel<0xff>(c->g()), opt.precision);
641
+ double b = Sass::round(cap_channel<0xff>(c->b()), opt.precision);
642
+ double a = cap_channel<1> (c->a());
643
+
644
+ // get color from given name (if one was given at all)
645
+ if (name != "" && name_to_color(name)) {
646
+ const Color_RGBA* n = name_to_color(name);
647
+ r = Sass::round(cap_channel<0xff>(n->r()), opt.precision);
648
+ g = Sass::round(cap_channel<0xff>(n->g()), opt.precision);
649
+ b = Sass::round(cap_channel<0xff>(n->b()), opt.precision);
650
+ a = cap_channel<1> (n->a());
651
+ }
652
+ // otherwise get the possible resolved color name
653
+ else {
654
+ double numval = r * 0x10000 + g * 0x100 + b;
655
+ if (color_to_name(numval))
656
+ res_name = color_to_name(numval);
657
+ }
658
+
659
+ sass::ostream hexlet;
660
+ // dart sass compressed all colors in regular css always
661
+ // ruby sass and libsass does it only when not delayed
662
+ // since color math is going to be removed, this can go too
663
+ bool compressed = opt.output_style == COMPRESSED;
664
+ hexlet << '#' << std::setw(1) << std::setfill('0');
665
+ // create a short color hexlet if there is any need for it
666
+ if (compressed && is_color_doublet(r, g, b) && a == 1) {
667
+ hexlet << std::hex << std::setw(1) << (static_cast<unsigned long>(r) >> 4);
668
+ hexlet << std::hex << std::setw(1) << (static_cast<unsigned long>(g) >> 4);
669
+ hexlet << std::hex << std::setw(1) << (static_cast<unsigned long>(b) >> 4);
670
+ } else {
671
+ hexlet << std::hex << std::setw(2) << static_cast<unsigned long>(r);
672
+ hexlet << std::hex << std::setw(2) << static_cast<unsigned long>(g);
673
+ hexlet << std::hex << std::setw(2) << static_cast<unsigned long>(b);
674
+ }
675
+
676
+ if (compressed && !c->is_delayed()) name = "";
677
+ if (opt.output_style == INSPECT && a >= 1) {
678
+ append_token(hexlet.str(), c);
679
+ return;
680
+ }
681
+
682
+ // retain the originally specified color definition if unchanged
683
+ if (name != "") {
684
+ ss << name;
685
+ }
686
+ else if (a >= 1) {
687
+ if (res_name != "") {
688
+ if (compressed && hexlet.str().size() < res_name.size()) {
689
+ ss << hexlet.str();
690
+ } else {
691
+ ss << res_name;
692
+ }
693
+ }
694
+ else {
695
+ ss << hexlet.str();
696
+ }
697
+ }
698
+ else {
699
+ ss << "rgba(";
700
+ ss << static_cast<unsigned long>(r) << ",";
701
+ if (!compressed) ss << " ";
702
+ ss << static_cast<unsigned long>(g) << ",";
703
+ if (!compressed) ss << " ";
704
+ ss << static_cast<unsigned long>(b) << ",";
705
+ if (!compressed) ss << " ";
706
+ ss << a << ')';
707
+ }
708
+
709
+ append_token(ss.str(), c);
710
+
711
+ }
712
+
713
+ void Inspect::operator()(Color_HSLA* c)
714
+ {
715
+ Color_RGBA_Obj rgba = c->toRGBA();
716
+ operator()(rgba);
717
+ }
718
+
719
+ void Inspect::operator()(Boolean* b)
720
+ {
721
+ // output the final token
722
+ append_token(b->value() ? "true" : "false", b);
723
+ }
724
+
725
+ void Inspect::operator()(String_Schema* ss)
726
+ {
727
+ // Evaluation should turn these into String_Constants,
728
+ // so this method is only for inspection purposes.
729
+ for (size_t i = 0, L = ss->length(); i < L; ++i) {
730
+ if ((*ss)[i]->is_interpolant()) append_string("#{");
731
+ (*ss)[i]->perform(this);
732
+ if ((*ss)[i]->is_interpolant()) append_string("}");
733
+ }
734
+ }
735
+
736
+ void Inspect::operator()(String_Constant* s)
737
+ {
738
+ append_token(s->value(), s);
739
+ }
740
+
741
+ void Inspect::operator()(String_Quoted* s)
742
+ {
743
+ if (const char q = s->quote_mark()) {
744
+ append_token(quote(s->value(), q), s);
745
+ } else {
746
+ append_token(s->value(), s);
747
+ }
748
+ }
749
+
750
+ void Inspect::operator()(Custom_Error* e)
751
+ {
752
+ append_token(e->message(), e);
753
+ }
754
+
755
+ void Inspect::operator()(Custom_Warning* w)
756
+ {
757
+ append_token(w->message(), w);
758
+ }
759
+
760
+ void Inspect::operator()(SupportsOperation* so)
761
+ {
762
+
763
+ if (so->needs_parens(so->left())) append_string("(");
764
+ so->left()->perform(this);
765
+ if (so->needs_parens(so->left())) append_string(")");
766
+
767
+ if (so->operand() == SupportsOperation::AND) {
768
+ append_mandatory_space();
769
+ append_token("and", so);
770
+ append_mandatory_space();
771
+ } else if (so->operand() == SupportsOperation::OR) {
772
+ append_mandatory_space();
773
+ append_token("or", so);
774
+ append_mandatory_space();
775
+ }
776
+
777
+ if (so->needs_parens(so->right())) append_string("(");
778
+ so->right()->perform(this);
779
+ if (so->needs_parens(so->right())) append_string(")");
780
+ }
781
+
782
+ void Inspect::operator()(SupportsNegation* sn)
783
+ {
784
+ append_token("not", sn);
785
+ append_mandatory_space();
786
+ if (sn->needs_parens(sn->condition())) append_string("(");
787
+ sn->condition()->perform(this);
788
+ if (sn->needs_parens(sn->condition())) append_string(")");
789
+ }
790
+
791
+ void Inspect::operator()(SupportsDeclaration* sd)
792
+ {
793
+ append_string("(");
794
+ sd->feature()->perform(this);
795
+ append_string(": ");
796
+ sd->value()->perform(this);
797
+ append_string(")");
798
+ }
799
+
800
+ void Inspect::operator()(Supports_Interpolation* sd)
801
+ {
802
+ sd->value()->perform(this);
803
+ }
804
+
805
+ void Inspect::operator()(Media_Query* mq)
806
+ {
807
+ size_t i = 0;
808
+ if (mq->media_type()) {
809
+ if (mq->is_negated()) append_string("not ");
810
+ else if (mq->is_restricted()) append_string("only ");
811
+ mq->media_type()->perform(this);
812
+ }
813
+ else {
814
+ (*mq)[i++]->perform(this);
815
+ }
816
+ for (size_t L = mq->length(); i < L; ++i) {
817
+ append_string(" and ");
818
+ (*mq)[i]->perform(this);
819
+ }
820
+ }
821
+
822
+ void Inspect::operator()(Media_Query_Expression* mqe)
823
+ {
824
+ if (mqe->is_interpolated()) {
825
+ mqe->feature()->perform(this);
826
+ }
827
+ else {
828
+ append_string("(");
829
+ mqe->feature()->perform(this);
830
+ if (mqe->value()) {
831
+ append_string(": "); // verified
832
+ mqe->value()->perform(this);
833
+ }
834
+ append_string(")");
835
+ }
836
+ }
837
+
838
+ void Inspect::operator()(At_Root_Query* ae)
839
+ {
840
+ if (ae->feature()) {
841
+ append_string("(");
842
+ ae->feature()->perform(this);
843
+ if (ae->value()) {
844
+ append_colon_separator();
845
+ ae->value()->perform(this);
846
+ }
847
+ append_string(")");
848
+ }
849
+ }
850
+
851
+ void Inspect::operator()(Function* f)
852
+ {
853
+ append_token("get-function", f);
854
+ append_string("(");
855
+ append_string(quote(f->name()));
856
+ append_string(")");
857
+ }
858
+
859
+ void Inspect::operator()(Null* n)
860
+ {
861
+ // output the final token
862
+ append_token("null", n);
863
+ }
864
+
865
+ // parameters and arguments
866
+ void Inspect::operator()(Parameter* p)
867
+ {
868
+ append_token(p->name(), p);
869
+ if (p->default_value()) {
870
+ append_colon_separator();
871
+ p->default_value()->perform(this);
872
+ }
873
+ else if (p->is_rest_parameter()) {
874
+ append_string("...");
875
+ }
876
+ }
877
+
878
+ void Inspect::operator()(Parameters* p)
879
+ {
880
+ append_string("(");
881
+ if (!p->empty()) {
882
+ (*p)[0]->perform(this);
883
+ for (size_t i = 1, L = p->length(); i < L; ++i) {
884
+ append_comma_separator();
885
+ (*p)[i]->perform(this);
886
+ }
887
+ }
888
+ append_string(")");
889
+ }
890
+
891
+ void Inspect::operator()(Argument* a)
892
+ {
893
+ if (!a->name().empty()) {
894
+ append_token(a->name(), a);
895
+ append_colon_separator();
896
+ }
897
+ if (!a->value()) return;
898
+ // Special case: argument nulls can be ignored
899
+ if (a->value()->concrete_type() == Expression::NULL_VAL) {
900
+ return;
901
+ }
902
+ if (a->value()->concrete_type() == Expression::STRING) {
903
+ String_Constant* s = Cast<String_Constant>(a->value());
904
+ if (s) s->perform(this);
905
+ } else {
906
+ a->value()->perform(this);
907
+ }
908
+ if (a->is_rest_argument()) {
909
+ append_string("...");
910
+ }
911
+ }
912
+
913
+ void Inspect::operator()(Arguments* a)
914
+ {
915
+ append_string("(");
916
+ if (!a->empty()) {
917
+ (*a)[0]->perform(this);
918
+ for (size_t i = 1, L = a->length(); i < L; ++i) {
919
+ append_string(", "); // verified
920
+ // Sass Bug? append_comma_separator();
921
+ (*a)[i]->perform(this);
922
+ }
923
+ }
924
+ append_string(")");
925
+ }
926
+
927
+ void Inspect::operator()(Selector_Schema* s)
928
+ {
929
+ s->contents()->perform(this);
930
+ }
931
+
932
+ void Inspect::operator()(Parent_Reference* p)
933
+ {
934
+ append_string("&");
935
+ }
936
+
937
+ void Inspect::operator()(PlaceholderSelector* s)
938
+ {
939
+ append_token(s->name(), s);
940
+
941
+ }
942
+
943
+ void Inspect::operator()(TypeSelector* s)
944
+ {
945
+ append_token(s->ns_name(), s);
946
+ }
947
+
948
+ void Inspect::operator()(ClassSelector* s)
949
+ {
950
+ append_token(s->ns_name(), s);
951
+ }
952
+
953
+ void Inspect::operator()(IDSelector* s)
954
+ {
955
+ append_token(s->ns_name(), s);
956
+ }
957
+
958
+ void Inspect::operator()(AttributeSelector* s)
959
+ {
960
+ append_string("[");
961
+ add_open_mapping(s);
962
+ append_token(s->ns_name(), s);
963
+ if (!s->matcher().empty()) {
964
+ append_string(s->matcher());
965
+ if (s->value() && *s->value()) {
966
+ s->value()->perform(this);
967
+ }
968
+ }
969
+ add_close_mapping(s);
970
+ if (s->modifier() != 0) {
971
+ append_mandatory_space();
972
+ append_char(s->modifier());
973
+ }
974
+ append_string("]");
975
+ }
976
+
977
+ void Inspect::operator()(PseudoSelector* s)
978
+ {
979
+
980
+ if (s->name() != "") {
981
+ append_string(":");
982
+ if (s->isSyntacticElement()) {
983
+ append_string(":");
984
+ }
985
+ append_token(s->ns_name(), s);
986
+ if (s->selector() || s->argument()) {
987
+ bool was = in_wrapped;
988
+ in_wrapped = true;
989
+ append_string("(");
990
+ if (s->argument()) {
991
+ s->argument()->perform(this);
992
+ }
993
+ if (s->selector() && s->argument()) {
994
+ append_mandatory_space();
995
+ }
996
+ bool was_comma_array = in_comma_array;
997
+ in_comma_array = false;
998
+ if (s->selector()) {
999
+ s->selector()->perform(this);
1000
+ }
1001
+ in_comma_array = was_comma_array;
1002
+ append_string(")");
1003
+ in_wrapped = was;
1004
+ }
1005
+ }
1006
+ }
1007
+
1008
+ void Inspect::operator()(SelectorList* g)
1009
+ {
1010
+
1011
+ if (g->empty()) {
1012
+ if (output_style() == TO_SASS) {
1013
+ append_token("()", g);
1014
+ }
1015
+ return;
1016
+ }
1017
+
1018
+
1019
+ bool was_comma_array = in_comma_array;
1020
+ // probably ruby sass eqivalent of element_needs_parens
1021
+ if (output_style() == TO_SASS && g->length() == 1 &&
1022
+ (!Cast<List>((*g)[0]) &&
1023
+ !Cast<SelectorList>((*g)[0]))) {
1024
+ append_string("(");
1025
+ }
1026
+ else if (!in_declaration && in_comma_array) {
1027
+ append_string("(");
1028
+ }
1029
+
1030
+ if (in_declaration) in_comma_array = true;
1031
+
1032
+ for (size_t i = 0, L = g->length(); i < L; ++i) {
1033
+
1034
+ if (!in_wrapped && i == 0) append_indentation();
1035
+ if ((*g)[i] == nullptr) continue;
1036
+ if (g->at(i)->length() == 0) continue;
1037
+ schedule_mapping(g->at(i)->last());
1038
+ // add_open_mapping((*g)[i]->last());
1039
+ (*g)[i]->perform(this);
1040
+ // add_close_mapping((*g)[i]->last());
1041
+ if (i < L - 1) {
1042
+ scheduled_space = 0;
1043
+ append_comma_separator();
1044
+ }
1045
+ }
1046
+
1047
+ in_comma_array = was_comma_array;
1048
+ // probably ruby sass eqivalent of element_needs_parens
1049
+ if (output_style() == TO_SASS && g->length() == 1 &&
1050
+ (!Cast<List>((*g)[0]) &&
1051
+ !Cast<SelectorList>((*g)[0]))) {
1052
+ append_string(",)");
1053
+ }
1054
+ else if (!in_declaration && in_comma_array) {
1055
+ append_string(")");
1056
+ }
1057
+
1058
+ }
1059
+ void Inspect::operator()(ComplexSelector* sel)
1060
+ {
1061
+ if (sel->hasPreLineFeed()) {
1062
+ append_optional_linefeed();
1063
+ if (!in_wrapped && output_style() == NESTED) {
1064
+ append_indentation();
1065
+ }
1066
+ }
1067
+ const SelectorComponent* prev = nullptr;
1068
+ for (auto& item : sel->elements()) {
1069
+ if (prev != nullptr) {
1070
+ if (item->getCombinator() || prev->getCombinator()) {
1071
+ append_optional_space();
1072
+ } else {
1073
+ append_mandatory_space();
1074
+ }
1075
+ }
1076
+ item->perform(this);
1077
+ prev = item.ptr();
1078
+ }
1079
+ }
1080
+
1081
+ void Inspect::operator()(SelectorComponent* sel)
1082
+ {
1083
+ // You should probably never call this method directly
1084
+ // But in case anyone does, we will do the upcasting
1085
+ if (auto comp = Cast<CompoundSelector>(sel)) operator()(comp);
1086
+ if (auto comb = Cast<SelectorCombinator>(sel)) operator()(comb);
1087
+ }
1088
+
1089
+ void Inspect::operator()(CompoundSelector* sel)
1090
+ {
1091
+ if (sel->hasRealParent()) {
1092
+ append_string("&");
1093
+ }
1094
+ sel->sortChildren();
1095
+ for (auto& item : sel->elements()) {
1096
+ item->perform(this);
1097
+ }
1098
+ // Add the post line break (from ruby sass)
1099
+ // Dart sass uses another logic for newlines
1100
+ if (sel->hasPostLineBreak()) {
1101
+ if (output_style() != COMPACT) {
1102
+ append_optional_linefeed();
1103
+ }
1104
+ }
1105
+ }
1106
+
1107
+ void Inspect::operator()(SelectorCombinator* sel)
1108
+ {
1109
+ append_optional_space();
1110
+ switch (sel->combinator()) {
1111
+ case SelectorCombinator::Combinator::CHILD: append_string(">"); break;
1112
+ case SelectorCombinator::Combinator::GENERAL: append_string("~"); break;
1113
+ case SelectorCombinator::Combinator::ADJACENT: append_string("+"); break;
1114
+ }
1115
+ append_optional_space();
1116
+ // Add the post line break (from ruby sass)
1117
+ // Dart sass uses another logic for newlines
1118
+ if (sel->hasPostLineBreak()) {
1119
+ if (output_style() != COMPACT) {
1120
+ // append_optional_linefeed();
1121
+ }
1122
+ }
1123
+ }
1124
+
1125
+ }