sassc 0.0.1

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 (151) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +24 -0
  8. data/Rakefile +21 -0
  9. data/ext/libsass/.editorconfig +15 -0
  10. data/ext/libsass/.gitattributes +2 -0
  11. data/ext/libsass/.gitignore +61 -0
  12. data/ext/libsass/.travis.yml +38 -0
  13. data/ext/libsass/COPYING +25 -0
  14. data/ext/libsass/INSTALL +1 -0
  15. data/ext/libsass/LICENSE +25 -0
  16. data/ext/libsass/Makefile +223 -0
  17. data/ext/libsass/Makefile.am +145 -0
  18. data/ext/libsass/Readme.md +93 -0
  19. data/ext/libsass/appveyor.yml +76 -0
  20. data/ext/libsass/ast.cpp +581 -0
  21. data/ext/libsass/ast.hpp +1949 -0
  22. data/ext/libsass/ast_def_macros.hpp +16 -0
  23. data/ext/libsass/ast_factory.hpp +87 -0
  24. data/ext/libsass/ast_fwd_decl.hpp +72 -0
  25. data/ext/libsass/b64/cencode.h +32 -0
  26. data/ext/libsass/b64/encode.h +77 -0
  27. data/ext/libsass/backtrace.hpp +81 -0
  28. data/ext/libsass/base64vlq.cpp +43 -0
  29. data/ext/libsass/base64vlq.hpp +28 -0
  30. data/ext/libsass/bind.cpp +187 -0
  31. data/ext/libsass/bind.hpp +18 -0
  32. data/ext/libsass/cencode.c +102 -0
  33. data/ext/libsass/color_names.hpp +324 -0
  34. data/ext/libsass/configure.ac +130 -0
  35. data/ext/libsass/constants.cpp +144 -0
  36. data/ext/libsass/constants.hpp +145 -0
  37. data/ext/libsass/context.cpp +507 -0
  38. data/ext/libsass/context.hpp +150 -0
  39. data/ext/libsass/contextualize.cpp +157 -0
  40. data/ext/libsass/contextualize.hpp +65 -0
  41. data/ext/libsass/copy_c_str.cpp +13 -0
  42. data/ext/libsass/copy_c_str.hpp +5 -0
  43. data/ext/libsass/debug.hpp +39 -0
  44. data/ext/libsass/environment.hpp +75 -0
  45. data/ext/libsass/error_handling.cpp +28 -0
  46. data/ext/libsass/error_handling.hpp +28 -0
  47. data/ext/libsass/eval.cpp +1149 -0
  48. data/ext/libsass/eval.hpp +80 -0
  49. data/ext/libsass/expand.cpp +430 -0
  50. data/ext/libsass/expand.hpp +77 -0
  51. data/ext/libsass/extconf.rb +6 -0
  52. data/ext/libsass/extend.cpp +1962 -0
  53. data/ext/libsass/extend.hpp +50 -0
  54. data/ext/libsass/file.cpp +291 -0
  55. data/ext/libsass/file.hpp +18 -0
  56. data/ext/libsass/functions.cpp +1565 -0
  57. data/ext/libsass/functions.hpp +187 -0
  58. data/ext/libsass/inspect.cpp +727 -0
  59. data/ext/libsass/inspect.hpp +108 -0
  60. data/ext/libsass/json.cpp +1411 -0
  61. data/ext/libsass/json.hpp +117 -0
  62. data/ext/libsass/kwd_arg_macros.hpp +23 -0
  63. data/ext/libsass/m4/.gitkeep +0 -0
  64. data/ext/libsass/mapping.hpp +17 -0
  65. data/ext/libsass/memory_manager.hpp +54 -0
  66. data/ext/libsass/node.cpp +251 -0
  67. data/ext/libsass/node.hpp +122 -0
  68. data/ext/libsass/operation.hpp +153 -0
  69. data/ext/libsass/output_compressed.cpp +401 -0
  70. data/ext/libsass/output_compressed.hpp +95 -0
  71. data/ext/libsass/output_nested.cpp +364 -0
  72. data/ext/libsass/output_nested.hpp +108 -0
  73. data/ext/libsass/parser.cpp +2016 -0
  74. data/ext/libsass/parser.hpp +264 -0
  75. data/ext/libsass/paths.hpp +69 -0
  76. data/ext/libsass/position.hpp +22 -0
  77. data/ext/libsass/posix/getopt.c +562 -0
  78. data/ext/libsass/posix/getopt.h +95 -0
  79. data/ext/libsass/prelexer.cpp +688 -0
  80. data/ext/libsass/prelexer.hpp +513 -0
  81. data/ext/libsass/remove_placeholders.cpp +59 -0
  82. data/ext/libsass/remove_placeholders.hpp +43 -0
  83. data/ext/libsass/res/resource.rc +35 -0
  84. data/ext/libsass/sass.cpp +33 -0
  85. data/ext/libsass/sass.h +60 -0
  86. data/ext/libsass/sass2scss.cpp +834 -0
  87. data/ext/libsass/sass2scss.h +110 -0
  88. data/ext/libsass/sass_context.cpp +709 -0
  89. data/ext/libsass/sass_context.h +120 -0
  90. data/ext/libsass/sass_functions.cpp +137 -0
  91. data/ext/libsass/sass_functions.h +90 -0
  92. data/ext/libsass/sass_interface.cpp +277 -0
  93. data/ext/libsass/sass_interface.h +97 -0
  94. data/ext/libsass/sass_util.cpp +136 -0
  95. data/ext/libsass/sass_util.hpp +259 -0
  96. data/ext/libsass/sass_values.cpp +337 -0
  97. data/ext/libsass/sass_values.h +124 -0
  98. data/ext/libsass/script/bootstrap +10 -0
  99. data/ext/libsass/script/branding +10 -0
  100. data/ext/libsass/script/ci-build-libsass +72 -0
  101. data/ext/libsass/script/ci-install-compiler +4 -0
  102. data/ext/libsass/script/ci-install-deps +19 -0
  103. data/ext/libsass/script/ci-report-coverage +25 -0
  104. data/ext/libsass/script/coveralls-debug +32 -0
  105. data/ext/libsass/script/spec +5 -0
  106. data/ext/libsass/script/tap-driver +652 -0
  107. data/ext/libsass/script/tap-runner +1 -0
  108. data/ext/libsass/source_map.cpp +133 -0
  109. data/ext/libsass/source_map.hpp +46 -0
  110. data/ext/libsass/subset_map.hpp +145 -0
  111. data/ext/libsass/support/libsass.pc.in +11 -0
  112. data/ext/libsass/test-driver +127 -0
  113. data/ext/libsass/test/test_node.cpp +98 -0
  114. data/ext/libsass/test/test_paths.cpp +29 -0
  115. data/ext/libsass/test/test_selector_difference.cpp +28 -0
  116. data/ext/libsass/test/test_specificity.cpp +28 -0
  117. data/ext/libsass/test/test_subset_map.cpp +472 -0
  118. data/ext/libsass/test/test_superselector.cpp +71 -0
  119. data/ext/libsass/test/test_unification.cpp +33 -0
  120. data/ext/libsass/to_c.cpp +61 -0
  121. data/ext/libsass/to_c.hpp +44 -0
  122. data/ext/libsass/to_string.cpp +29 -0
  123. data/ext/libsass/to_string.hpp +32 -0
  124. data/ext/libsass/token.hpp +32 -0
  125. data/ext/libsass/units.cpp +54 -0
  126. data/ext/libsass/units.hpp +10 -0
  127. data/ext/libsass/utf8.h +34 -0
  128. data/ext/libsass/utf8/checked.h +327 -0
  129. data/ext/libsass/utf8/core.h +329 -0
  130. data/ext/libsass/utf8/unchecked.h +228 -0
  131. data/ext/libsass/utf8_string.cpp +102 -0
  132. data/ext/libsass/utf8_string.hpp +36 -0
  133. data/ext/libsass/util.cpp +189 -0
  134. data/ext/libsass/util.hpp +26 -0
  135. data/ext/libsass/win/libsass.filters +291 -0
  136. data/ext/libsass/win/libsass.sln +28 -0
  137. data/ext/libsass/win/libsass.vcxproj +255 -0
  138. data/lib/sassc.rb +6 -0
  139. data/lib/sassc/engine.rb +13 -0
  140. data/lib/sassc/native.rb +44 -0
  141. data/lib/sassc/native/native_context_api.rb +140 -0
  142. data/lib/sassc/native/native_functions_api.rb +41 -0
  143. data/lib/sassc/native/sass_input_style.rb +11 -0
  144. data/lib/sassc/native/sass_output_style.rb +10 -0
  145. data/lib/sassc/native/sass_value.rb +95 -0
  146. data/lib/sassc/native/string_list.rb +8 -0
  147. data/lib/sassc/version.rb +3 -0
  148. data/sassc.gemspec +43 -0
  149. data/test/smoke_test.rb +171 -0
  150. data/test/test_helper.rb +4 -0
  151. metadata +281 -0
@@ -0,0 +1,95 @@
1
+ #include <string>
2
+
3
+ #ifndef SASS_OPERATION
4
+ #include "operation.hpp"
5
+ #endif
6
+
7
+ namespace Sass {
8
+ using namespace std;
9
+
10
+ struct Context;
11
+
12
+ class Output_Compressed : public Operation_CRTP<void, Output_Compressed> {
13
+ // import all the class-specific methods and override as desired
14
+ using Operation_CRTP<void, Output_Compressed>::operator();
15
+
16
+ string buffer;
17
+ string rendered_imports;
18
+ Context* ctx;
19
+ bool seen_utf8;
20
+
21
+ void fallback_impl(AST_Node* n);
22
+
23
+ void append_singleline_part_to_buffer(const string& text);
24
+
25
+ public:
26
+ Output_Compressed(Context* ctx = 0);
27
+ virtual ~Output_Compressed();
28
+
29
+ string get_buffer() {
30
+ return (seen_utf8 ? "@charset \"UTF-8\";\n" : "")
31
+ + rendered_imports + buffer;
32
+ }
33
+
34
+ // statements
35
+ virtual void operator()(Block*);
36
+ virtual void operator()(Ruleset*);
37
+ // virtual void operator()(Propset*);
38
+ virtual void operator()(Media_Block*);
39
+ virtual void operator()(At_Rule*);
40
+ virtual void operator()(Declaration*);
41
+ // virtual void operator()(Assignment*);
42
+ virtual void operator()(Import*);
43
+ // virtual void operator()(Import_Stub*);
44
+ // virtual void operator()(Warning*);
45
+ // virtual void operator()(Error*);
46
+ // virtual void operator()(Debug*);
47
+ virtual void operator()(Comment*);
48
+ // virtual void operator()(If*);
49
+ // virtual void operator()(For*);
50
+ // virtual void operator()(Each*);
51
+ // virtual void operator()(While*);
52
+ // virtual void operator()(Return*);
53
+ // virtual void operator()(Extension*);
54
+ // virtual void operator()(Definition*);
55
+ // virtual void operator()(Mixin_Call*);
56
+ // virtual void operator()(Content*);
57
+ // // expressions
58
+ virtual void operator()(List*);
59
+ // virtual void operator()(Binary_Expression*);
60
+ // virtual void operator()(Unary_Expression*);
61
+ // virtual void operator()(Function_Call*);
62
+ // virtual void operator()(Function_Call_Schema*);
63
+ // virtual void operator()(Variable*);
64
+ // virtual void operator()(Textual*);
65
+ // virtual void operator()(Number*);
66
+ virtual void operator()(Color*);
67
+ // virtual void operator()(Boolean*);
68
+ // virtual void operator()(String_Schema*);
69
+ // virtual void operator()(String_Constant* x);
70
+ // virtual void operator()(Media_Query*);
71
+ virtual void operator()(Media_Query_Expression*);
72
+ virtual void operator()(Null*);
73
+ // // parameters and arguments
74
+ // virtual void operator()(Parameter*);
75
+ // virtual void operator()(Parameters*);
76
+ virtual void operator()(Argument*);
77
+ virtual void operator()(Arguments*);
78
+ // // selectors
79
+ // virtual void operator()(Selector_Schema*);
80
+ // virtual void operator()(Selector_Reference*);
81
+ // virtual void operator()(Selector_Placeholder*);
82
+ // virtual void operator()(Type_Selector*);
83
+ // virtual void operator()(Selector_Qualifier*);
84
+ // virtual void operator()(Attribute_Selector*);
85
+ // virtual void operator()(Pseudo_Selector*);
86
+ // virtual void operator()(Wrapped_Selector*);
87
+ // virtual void operator()(Compound_Selector*);
88
+ virtual void operator()(Complex_Selector*);
89
+ virtual void operator()(Selector_List*);
90
+
91
+ template <typename U>
92
+ void fallback(U x) { fallback_impl(x); }
93
+ };
94
+
95
+ }
@@ -0,0 +1,364 @@
1
+ #include "output_nested.hpp"
2
+ #include "inspect.hpp"
3
+ #include "ast.hpp"
4
+ #include "context.hpp"
5
+ #include "to_string.hpp"
6
+ #include "util.hpp"
7
+ #include <iostream>
8
+ #include <sstream>
9
+ #include <typeinfo>
10
+
11
+ namespace Sass {
12
+ using namespace std;
13
+
14
+ Output_Nested::Output_Nested(bool source_comments, Context* ctx)
15
+ : buffer(""), rendered_imports(""), indentation(0), source_comments(source_comments), ctx(ctx), seen_utf8(false)
16
+ { }
17
+ Output_Nested::~Output_Nested() { }
18
+
19
+ inline void Output_Nested::fallback_impl(AST_Node* n)
20
+ {
21
+ Inspect i(ctx);
22
+ n->perform(&i);
23
+ const string& text = i.get_buffer();
24
+ for(const char& chr : text) {
25
+ // abort clause
26
+ if (seen_utf8) break;
27
+ // skip all normal ascii chars
28
+ if (Util::isAscii(chr)) continue;
29
+ // singleton
30
+ seen_utf8 = true;
31
+ }
32
+ buffer += text;
33
+ if (ctx && !ctx->_skip_source_map_update)
34
+ ctx->source_map.update_column(text);
35
+ }
36
+
37
+ void Output_Nested::operator()(Import* imp)
38
+ {
39
+ Inspect insp(ctx);
40
+ imp->perform(&insp);
41
+ if (!rendered_imports.empty()) {
42
+ rendered_imports += "\n";
43
+ }
44
+ rendered_imports += insp.get_buffer();
45
+ }
46
+
47
+ void Output_Nested::operator()(Block* b)
48
+ {
49
+ if (!b->is_root()) return;
50
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
51
+ size_t old_len = buffer.length();
52
+ (*b)[i]->perform(this);
53
+ if (i < L-1 && old_len < buffer.length()) append_to_buffer("\n");
54
+ }
55
+ }
56
+
57
+ void Output_Nested::operator()(Ruleset* r)
58
+ {
59
+ Selector* s = r->selector();
60
+ Block* b = r->block();
61
+ bool decls = false;
62
+
63
+ // disabled to avoid clang warning [-Wunused-function]
64
+ // Selector_List* sl = static_cast<Selector_List*>(s);
65
+
66
+ // Filter out rulesets that aren't printable (process its children though)
67
+ if (!Util::isPrintable(r)) {
68
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
69
+ Statement* stm = (*b)[i];
70
+ if (dynamic_cast<Has_Block*>(stm)) {
71
+ stm->perform(this);
72
+ }
73
+ }
74
+ return;
75
+ }
76
+
77
+ if (b->has_non_hoistable()) {
78
+ decls = true;
79
+ indent();
80
+ if (source_comments) {
81
+ stringstream ss;
82
+ ss << "/* line " << r->position().line << ", " << r->path() << " */" << endl;
83
+ append_to_buffer(ss.str());
84
+ indent();
85
+ }
86
+ s->perform(this);
87
+ append_to_buffer(" {\n");
88
+ ++indentation;
89
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
90
+ Statement* stm = (*b)[i];
91
+ bool bPrintExpression = true;
92
+ // Check print conditions
93
+ if (typeid(*stm) == typeid(Declaration)) {
94
+ Declaration* dec = static_cast<Declaration*>(stm);
95
+ if (dec->value()->concrete_type() == Expression::STRING) {
96
+ String_Constant* valConst = static_cast<String_Constant*>(dec->value());
97
+ string val(valConst->value());
98
+ if (val.empty()) {
99
+ bPrintExpression = false;
100
+ }
101
+ }
102
+ else if (dec->value()->concrete_type() == Expression::LIST) {
103
+ List* list = static_cast<List*>(dec->value());
104
+ bool all_invisible = true;
105
+ for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
106
+ Expression* item = (*list)[list_i];
107
+ if (!item->is_invisible()) all_invisible = false;
108
+ }
109
+ if (all_invisible) bPrintExpression = false;
110
+ }
111
+ }
112
+ // Print if OK
113
+ if (!stm->is_hoistable() && bPrintExpression) {
114
+ if (!stm->block()) indent();
115
+ stm->perform(this);
116
+ append_to_buffer("\n");
117
+ }
118
+ }
119
+ --indentation;
120
+ buffer.erase(buffer.length()-1);
121
+ if (ctx) ctx->source_map.remove_line();
122
+ append_to_buffer(" }\n");
123
+ }
124
+
125
+ if (b->has_hoistable()) {
126
+ if (decls) ++indentation;
127
+ // indent();
128
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
129
+ Statement* stm = (*b)[i];
130
+ if (stm->is_hoistable()) {
131
+ stm->perform(this);
132
+ }
133
+ }
134
+ if (decls) --indentation;
135
+ }
136
+ }
137
+
138
+ void Output_Nested::operator()(Feature_Block* f)
139
+ {
140
+ Feature_Query* q = f->feature_queries();
141
+ Block* b = f->block();
142
+
143
+ // Filter out feature blocks that aren't printable (process its children though)
144
+ if (!Util::isPrintable(f)) {
145
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
146
+ Statement* stm = (*b)[i];
147
+ if (dynamic_cast<Has_Block*>(stm)) {
148
+ stm->perform(this);
149
+ }
150
+ }
151
+ return;
152
+ }
153
+
154
+ indent();
155
+ ctx->source_map.add_mapping(f);
156
+ append_to_buffer("@supports ");
157
+ q->perform(this);
158
+ append_to_buffer(" {\n");
159
+
160
+ Selector* e = f->selector();
161
+ if (e && b->has_non_hoistable()) {
162
+ // JMA - hoisted, output the non-hoistable in a nested block, followed by the hoistable
163
+ ++indentation;
164
+ indent();
165
+ e->perform(this);
166
+ append_to_buffer(" {\n");
167
+
168
+ ++indentation;
169
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
170
+ Statement* stm = (*b)[i];
171
+ if (!stm->is_hoistable()) {
172
+ if (!stm->block()) indent();
173
+ stm->perform(this);
174
+ append_to_buffer("\n");
175
+ }
176
+ }
177
+ --indentation;
178
+
179
+ buffer.erase(buffer.length()-1);
180
+ if (ctx) ctx->source_map.remove_line();
181
+ append_to_buffer(" }\n");
182
+ --indentation;
183
+
184
+ ++indentation;
185
+ ++indentation;
186
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
187
+ Statement* stm = (*b)[i];
188
+ if (stm->is_hoistable()) {
189
+ stm->perform(this);
190
+ }
191
+ }
192
+ --indentation;
193
+ --indentation;
194
+ }
195
+ else {
196
+ // JMA - not hoisted, just output in order
197
+ ++indentation;
198
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
199
+ Statement* stm = (*b)[i];
200
+ if (!stm->is_hoistable()) {
201
+ if (!stm->block()) indent();
202
+ }
203
+ stm->perform(this);
204
+ if (!stm->is_hoistable()) append_to_buffer("\n");
205
+ }
206
+ --indentation;
207
+ }
208
+
209
+ buffer.erase(buffer.length()-1);
210
+ if (ctx) ctx->source_map.remove_line();
211
+ append_to_buffer(" }\n");
212
+ }
213
+
214
+ void Output_Nested::operator()(Media_Block* m)
215
+ {
216
+ List* q = m->media_queries();
217
+ Block* b = m->block();
218
+
219
+ // Filter out media blocks that aren't printable (process its children though)
220
+ if (!Util::isPrintable(m)) {
221
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
222
+ Statement* stm = (*b)[i];
223
+ if (dynamic_cast<Has_Block*>(stm)) {
224
+ stm->perform(this);
225
+ }
226
+ }
227
+ return;
228
+ }
229
+
230
+ indent();
231
+ ctx->source_map.add_mapping(m);
232
+ append_to_buffer("@media ");
233
+ q->perform(this);
234
+ append_to_buffer(" {\n");
235
+
236
+ Selector* e = m->selector();
237
+ if (e && b->has_non_hoistable()) {
238
+ // JMA - hoisted, output the non-hoistable in a nested block, followed by the hoistable
239
+ ++indentation;
240
+ indent();
241
+ e->perform(this);
242
+ append_to_buffer(" {\n");
243
+
244
+ ++indentation;
245
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
246
+ Statement* stm = (*b)[i];
247
+ if (!stm->is_hoistable()) {
248
+ if (!stm->block()) indent();
249
+ stm->perform(this);
250
+ append_to_buffer("\n");
251
+ }
252
+ }
253
+ --indentation;
254
+
255
+ buffer.erase(buffer.length()-1);
256
+ if (ctx) ctx->source_map.remove_line();
257
+ append_to_buffer(" }\n");
258
+ --indentation;
259
+
260
+ ++indentation;
261
+ ++indentation;
262
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
263
+ Statement* stm = (*b)[i];
264
+ if (stm->is_hoistable()) {
265
+ stm->perform(this);
266
+ }
267
+ }
268
+ --indentation;
269
+ --indentation;
270
+ }
271
+ else {
272
+ // JMA - not hoisted, just output in order
273
+ ++indentation;
274
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
275
+ Statement* stm = (*b)[i];
276
+ if (!stm->is_hoistable()) {
277
+ if (!stm->block()) indent();
278
+ }
279
+ stm->perform(this);
280
+ if (!stm->is_hoistable()) append_to_buffer("\n");
281
+ }
282
+ --indentation;
283
+ }
284
+
285
+ buffer.erase(buffer.length()-1);
286
+ if (ctx) ctx->source_map.remove_line();
287
+ append_to_buffer(" }\n");
288
+ }
289
+
290
+ void Output_Nested::operator()(At_Rule* a)
291
+ {
292
+ string kwd = a->keyword();
293
+ Selector* s = a->selector();
294
+ Expression* v = a->value();
295
+ Block* b = a->block();
296
+ bool decls = false;
297
+
298
+ // indent();
299
+ append_to_buffer(kwd);
300
+ if (s) {
301
+ append_to_buffer(" ");
302
+ s->perform(this);
303
+ }
304
+ else if (v) {
305
+ append_to_buffer(" ");
306
+ v->perform(this);
307
+ }
308
+
309
+ if (!b) {
310
+ append_to_buffer(";");
311
+ return;
312
+ }
313
+
314
+ append_to_buffer(" {\n");
315
+ ++indentation;
316
+ decls = true;
317
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
318
+ Statement* stm = (*b)[i];
319
+ if (!stm->is_hoistable()) {
320
+ if (!stm->block()) indent();
321
+ stm->perform(this);
322
+ append_to_buffer("\n");
323
+ }
324
+ }
325
+ --indentation;
326
+
327
+ if (decls) ++indentation;
328
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
329
+ Statement* stm = (*b)[i];
330
+ if (stm->is_hoistable()) {
331
+ stm->perform(this);
332
+ append_to_buffer("\n");
333
+ }
334
+ }
335
+ if (decls) --indentation;
336
+
337
+ buffer.erase(buffer.length()-1);
338
+ if (ctx) ctx->source_map.remove_line();
339
+ if (b->has_hoistable()) {
340
+ buffer.erase(buffer.length()-1);
341
+ if (ctx) ctx->source_map.remove_line();
342
+ }
343
+ append_to_buffer(" }\n");
344
+ }
345
+
346
+ void Output_Nested::indent()
347
+ { append_to_buffer(string(2*indentation, ' ')); }
348
+
349
+ void Output_Nested::append_to_buffer(const string& text)
350
+ {
351
+ buffer += text;
352
+ if (ctx && !ctx->_skip_source_map_update)
353
+ ctx->source_map.update_column(text);
354
+ for(const char& chr : text) {
355
+ // abort clause
356
+ if (seen_utf8) break;
357
+ // skip all normal ascii chars
358
+ if (Util::isAscii(chr)) continue;
359
+ // singleton
360
+ seen_utf8 = true;
361
+ }
362
+ }
363
+
364
+ }