sassc 0.0.9 → 0.0.10

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 (111) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/ext/libsass/.gitignore +13 -6
  4. data/ext/libsass/Makefile +42 -26
  5. data/ext/libsass/Makefile.am +43 -30
  6. data/ext/libsass/Readme.md +4 -2
  7. data/ext/libsass/appveyor.yml +10 -14
  8. data/ext/libsass/ast.cpp +54 -44
  9. data/ext/libsass/ast.hpp +404 -236
  10. data/ext/libsass/ast_def_macros.hpp +5 -0
  11. data/ext/libsass/ast_factory.hpp +6 -3
  12. data/ext/libsass/ast_fwd_decl.hpp +12 -0
  13. data/ext/libsass/b64/encode.h +2 -2
  14. data/ext/libsass/backtrace.hpp +13 -17
  15. data/ext/libsass/base64vlq.hpp +4 -1
  16. data/ext/libsass/bind.cpp +12 -15
  17. data/ext/libsass/bind.hpp +6 -6
  18. data/ext/libsass/color_names.hpp +4 -1
  19. data/ext/libsass/configure.ac +7 -21
  20. data/ext/libsass/constants.cpp +6 -4
  21. data/ext/libsass/constants.hpp +10 -4
  22. data/ext/libsass/context.cpp +89 -58
  23. data/ext/libsass/context.hpp +28 -35
  24. data/ext/libsass/contextualize.cpp +20 -10
  25. data/ext/libsass/contextualize.hpp +8 -23
  26. data/ext/libsass/contrib/libsass.spec +66 -0
  27. data/ext/libsass/cssize.cpp +547 -0
  28. data/ext/libsass/cssize.hpp +82 -0
  29. data/ext/libsass/debug.hpp +3 -3
  30. data/ext/libsass/debugger.hpp +358 -0
  31. data/ext/libsass/emitter.cpp +255 -0
  32. data/ext/libsass/emitter.hpp +83 -0
  33. data/ext/libsass/environment.hpp +7 -3
  34. data/ext/libsass/error_handling.cpp +11 -14
  35. data/ext/libsass/error_handling.hpp +9 -7
  36. data/ext/libsass/eval.cpp +253 -161
  37. data/ext/libsass/eval.hpp +13 -13
  38. data/ext/libsass/expand.cpp +135 -64
  39. data/ext/libsass/expand.hpp +11 -13
  40. data/ext/libsass/extend.cpp +66 -20
  41. data/ext/libsass/extend.hpp +6 -11
  42. data/ext/libsass/file.cpp +31 -26
  43. data/ext/libsass/file.hpp +6 -1
  44. data/ext/libsass/functions.cpp +270 -287
  45. data/ext/libsass/functions.hpp +8 -11
  46. data/ext/libsass/inspect.cpp +385 -255
  47. data/ext/libsass/inspect.hpp +15 -26
  48. data/ext/libsass/kwd_arg_macros.hpp +5 -0
  49. data/ext/libsass/mapping.hpp +4 -3
  50. data/ext/libsass/memory_manager.hpp +5 -2
  51. data/ext/libsass/node.cpp +50 -50
  52. data/ext/libsass/node.hpp +26 -27
  53. data/ext/libsass/operation.hpp +15 -4
  54. data/ext/libsass/output.cpp +401 -0
  55. data/ext/libsass/output.hpp +56 -0
  56. data/ext/libsass/parser.cpp +573 -399
  57. data/ext/libsass/parser.hpp +122 -88
  58. data/ext/libsass/paths.hpp +7 -2
  59. data/ext/libsass/plugins.cpp +155 -0
  60. data/ext/libsass/plugins.hpp +56 -0
  61. data/ext/libsass/position.cpp +128 -0
  62. data/ext/libsass/position.hpp +108 -11
  63. data/ext/libsass/prelexer.cpp +184 -110
  64. data/ext/libsass/prelexer.hpp +131 -24
  65. data/ext/libsass/remove_placeholders.cpp +1 -1
  66. data/ext/libsass/remove_placeholders.hpp +6 -6
  67. data/ext/libsass/sass.cpp +3 -3
  68. data/ext/libsass/sass.h +12 -4
  69. data/ext/libsass/sass2scss.cpp +3 -2
  70. data/ext/libsass/sass2scss.h +5 -0
  71. data/ext/libsass/sass_context.cpp +136 -37
  72. data/ext/libsass/sass_context.h +19 -10
  73. data/ext/libsass/sass_functions.cpp +29 -2
  74. data/ext/libsass/sass_functions.h +8 -2
  75. data/ext/libsass/sass_interface.cpp +32 -23
  76. data/ext/libsass/sass_interface.h +9 -4
  77. data/ext/libsass/sass_util.cpp +19 -23
  78. data/ext/libsass/sass_util.hpp +28 -27
  79. data/ext/libsass/sass_values.cpp +6 -4
  80. data/ext/libsass/sass_values.h +3 -3
  81. data/ext/libsass/script/ci-build-libsass +13 -1
  82. data/ext/libsass/script/ci-report-coverage +2 -1
  83. data/ext/libsass/source_map.cpp +79 -28
  84. data/ext/libsass/source_map.hpp +35 -16
  85. data/ext/libsass/subset_map.hpp +6 -4
  86. data/ext/libsass/to_c.hpp +4 -4
  87. data/ext/libsass/to_string.cpp +13 -8
  88. data/ext/libsass/to_string.hpp +6 -4
  89. data/ext/libsass/units.cpp +2 -1
  90. data/ext/libsass/units.hpp +6 -1
  91. data/ext/libsass/utf8_string.cpp +0 -5
  92. data/ext/libsass/utf8_string.hpp +3 -2
  93. data/ext/libsass/util.cpp +461 -49
  94. data/ext/libsass/util.hpp +34 -13
  95. data/ext/libsass/version.sh +10 -0
  96. data/ext/libsass/win/libsass.filters +20 -11
  97. data/ext/libsass/win/libsass.vcxproj +11 -8
  98. data/lib/sassc/importer.rb +1 -8
  99. data/lib/sassc/native.rb +7 -0
  100. data/lib/sassc/native/native_context_api.rb +5 -5
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/native_test.rb +1 -1
  103. metadata +14 -10
  104. data/ext/libsass/copy_c_str.cpp +0 -13
  105. data/ext/libsass/copy_c_str.hpp +0 -5
  106. data/ext/libsass/output_compressed.cpp +0 -401
  107. data/ext/libsass/output_compressed.hpp +0 -95
  108. data/ext/libsass/output_nested.cpp +0 -364
  109. data/ext/libsass/output_nested.hpp +0 -108
  110. data/ext/libsass/test-driver +0 -127
  111. data/ext/libsass/token.hpp +0 -32
@@ -1,29 +1,24 @@
1
- #define SASS_FUNCTIONS
1
+ #ifndef SASS_FUNCTIONS_H
2
+ #define SASS_FUNCTIONS_H
2
3
 
3
4
  #include <string>
4
5
 
5
- #ifndef SASS_ENVIRONMENT
6
- #include "environment.hpp"
7
- #endif
8
-
9
- #ifndef SASS_POSITION
10
6
  #include "position.hpp"
11
- #endif
12
-
7
+ #include "environment.hpp"
13
8
  #include "sass_functions.h"
14
9
 
15
10
  #define BUILT_IN(name) Expression*\
16
- name(Env& env, Env& d_env, Context& ctx, Signature sig, const string& path, Position position, Backtrace* backtrace)
11
+ name(Env& env, Env& d_env, Context& ctx, Signature sig, ParserState pstate, Backtrace* backtrace)
17
12
 
18
13
  namespace Sass {
19
- struct Context;
14
+ class Context;
20
15
  struct Backtrace;
21
16
  class AST_Node;
22
17
  class Expression;
23
18
  class Definition;
24
19
  typedef Environment<AST_Node*> Env;
25
20
  typedef const char* Signature;
26
- typedef Expression* (*Native_Function)(Env&, Env&, Context&, Signature, const string&, Position, Backtrace*);
21
+ typedef Expression* (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtrace*);
27
22
 
28
23
  Definition* make_native_function(Signature, Native_Function, Context&);
29
24
  Definition* make_c_function(Signature sig, Sass_C_Function f, void* cookie, Context& ctx);
@@ -185,3 +180,5 @@ namespace Sass {
185
180
 
186
181
  }
187
182
  }
183
+
184
+ #endif
@@ -1,43 +1,39 @@
1
1
  #include "inspect.hpp"
2
2
  #include "ast.hpp"
3
3
  #include "context.hpp"
4
+ #include "utf8/checked.h"
4
5
  #include <cmath>
6
+ #include <string>
5
7
  #include <iostream>
6
8
  #include <iomanip>
9
+ #include <stdint.h>
10
+ #include <stdint.h>
7
11
 
8
12
  namespace Sass {
9
13
  using namespace std;
10
14
 
11
- Inspect::Inspect(Context* ctx) : buffer(""), indentation(0), ctx(ctx) { }
15
+ Inspect::Inspect(Emitter emi)
16
+ : Emitter(emi)
17
+ { }
12
18
  Inspect::~Inspect() { }
13
19
 
14
20
  // statements
15
21
  void Inspect::operator()(Block* block)
16
22
  {
17
23
  if (!block->is_root()) {
18
- append_to_buffer(" {\n");
19
- ++indentation;
24
+ add_open_mapping(block);
25
+ append_scope_opener();
20
26
  }
27
+ if (output_style() == NESTED) indentation += block->tabs();
21
28
  for (size_t i = 0, L = block->length(); i < L; ++i) {
22
- indent();
23
29
  (*block)[i]->perform(this);
24
- // extra newline at the end of top-level statements
25
- if (block->is_root()) append_to_buffer("\n");
26
- append_to_buffer("\n");
27
30
  }
31
+ if (output_style() == NESTED) indentation -= block->tabs();
28
32
  if (!block->is_root()) {
29
- --indentation;
30
- indent();
31
- append_to_buffer("}");
32
- }
33
- // remove extra newline that gets added after the last top-level block
34
- if (block->is_root()) {
35
- size_t l = buffer.length();
36
- if (l > 2 && buffer[l-1] == '\n' && buffer[l-2] == '\n') {
37
- buffer.erase(l-1);
38
- if (ctx) ctx->source_map.remove_line();
39
- }
33
+ append_scope_closer();
34
+ add_close_mapping(block);
40
35
  }
36
+
41
37
  }
42
38
 
43
39
  void Inspect::operator()(Ruleset* ruleset)
@@ -46,206 +42,288 @@ namespace Sass {
46
42
  ruleset->block()->perform(this);
47
43
  }
48
44
 
45
+ void Inspect::operator()(Keyframe_Rule* rule)
46
+ {
47
+ append_indentation();
48
+ if (rule->rules()) rule->rules()->perform(this);
49
+ rule->block()->perform(this);
50
+ }
51
+
49
52
  void Inspect::operator()(Propset* propset)
50
53
  {
51
54
  propset->property_fragment()->perform(this);
52
- append_to_buffer(": ");
55
+ append_colon_separator();
53
56
  propset->block()->perform(this);
54
57
  }
55
58
 
59
+ void Inspect::operator()(Bubble* bubble)
60
+ {
61
+ append_indentation();
62
+ append_token("Bubble", bubble);
63
+ append_optional_space();
64
+ append_string("(");
65
+ append_optional_space();
66
+ bubble->node()->perform(this);
67
+ append_optional_space();
68
+ append_string(")");
69
+ append_optional_space();
70
+ }
71
+
56
72
  void Inspect::operator()(Media_Block* media_block)
57
73
  {
58
- if (ctx) ctx->source_map.add_mapping(media_block);
59
- append_to_buffer("@media ");
74
+ append_indentation();
75
+ append_token("@media", media_block);
76
+ append_mandatory_space();
77
+ in_media_block = true;
60
78
  media_block->media_queries()->perform(this);
79
+ in_media_block = false;
61
80
  media_block->block()->perform(this);
62
81
  }
63
82
 
64
83
  void Inspect::operator()(Feature_Block* feature_block)
65
84
  {
66
- if (ctx) ctx->source_map.add_mapping(feature_block);
67
- append_to_buffer("@supports ");
85
+ append_indentation();
86
+ append_token("@supports", feature_block);
87
+ append_mandatory_space();
68
88
  feature_block->feature_queries()->perform(this);
69
89
  feature_block->block()->perform(this);
70
90
  }
71
91
 
92
+ void Inspect::operator()(At_Root_Block* at_root_block)
93
+ {
94
+ append_indentation();
95
+ append_token("@at-root ", at_root_block);
96
+ append_mandatory_space();
97
+ if(at_root_block->expression()) at_root_block->expression()->perform(this);
98
+ at_root_block->block()->perform(this);
99
+ }
100
+
72
101
  void Inspect::operator()(At_Rule* at_rule)
73
102
  {
74
- append_to_buffer(at_rule->keyword());
103
+ append_indentation();
104
+ append_token(at_rule->keyword(), at_rule);
75
105
  if (at_rule->selector()) {
76
- append_to_buffer(" ");
106
+ append_mandatory_space();
107
+ in_at_rule = true;
77
108
  at_rule->selector()->perform(this);
109
+ in_at_rule = false;
78
110
  }
79
111
  if (at_rule->block()) {
80
112
  at_rule->block()->perform(this);
81
113
  }
82
114
  else {
83
- append_to_buffer(";");
115
+ append_delimiter();
84
116
  }
85
117
  }
86
118
 
87
119
  void Inspect::operator()(Declaration* dec)
88
120
  {
89
121
  if (dec->value()->concrete_type() == Expression::NULL_VAL) return;
90
- if (ctx) ctx->source_map.add_mapping(dec->property());
122
+ in_declaration = true;
123
+ if (output_style() == NESTED)
124
+ indentation += dec->tabs();
125
+ append_indentation();
91
126
  dec->property()->perform(this);
92
- append_to_buffer(": ");
93
- if (ctx) ctx->source_map.add_mapping(dec->value());
127
+ append_colon_separator();
94
128
  dec->value()->perform(this);
95
- if (dec->is_important()) append_to_buffer(" !important");
96
- append_to_buffer(";");
129
+ if (dec->is_important()) {
130
+ append_optional_space();
131
+ append_string("!important");
132
+ }
133
+ append_delimiter();
134
+ if (output_style() == NESTED)
135
+ indentation -= dec->tabs();
136
+ in_declaration = false;
97
137
  }
98
138
 
99
139
  void Inspect::operator()(Assignment* assn)
100
140
  {
101
- append_to_buffer(assn->variable());
102
- append_to_buffer(": ");
141
+ append_token(assn->variable(), assn);
142
+ append_colon_separator();
103
143
  assn->value()->perform(this);
104
- if (assn->is_guarded()) append_to_buffer(" !default");
105
- append_to_buffer(";");
144
+ if (assn->is_guarded()) {
145
+ append_optional_space();
146
+ append_string("!default");
147
+ }
148
+ append_delimiter();
106
149
  }
107
150
 
108
151
  void Inspect::operator()(Import* import)
109
152
  {
110
153
  if (!import->urls().empty()) {
111
- if (ctx) ctx->source_map.add_mapping(import);
112
- append_to_buffer("@import ");
154
+ append_token("@import", import);
155
+ append_mandatory_space();
156
+
157
+ if (String_Quoted* strq = dynamic_cast<String_Quoted*>(import->urls().front())) {
158
+ strq->is_delayed(false);
159
+ }
160
+
113
161
  import->urls().front()->perform(this);
114
- append_to_buffer(";");
162
+ append_delimiter();
115
163
  for (size_t i = 1, S = import->urls().size(); i < S; ++i) {
116
- append_to_buffer("\n");
117
- if (ctx) ctx->source_map.add_mapping(import);
118
- append_to_buffer("@import ");
164
+ append_mandatory_linefeed();
165
+ append_token("@import", import);
166
+ append_mandatory_space();
167
+
168
+ if (String_Quoted* strq = dynamic_cast<String_Quoted*>(import->urls()[i])) {
169
+ strq->is_delayed(false);
170
+ }
171
+
119
172
  import->urls()[i]->perform(this);
120
- append_to_buffer(";");
173
+ append_delimiter();
121
174
  }
122
175
  }
123
176
  }
124
177
 
125
178
  void Inspect::operator()(Import_Stub* import)
126
179
  {
127
- if (ctx) ctx->source_map.add_mapping(import);
128
- append_to_buffer("@import ");
129
- append_to_buffer(import->file_name());
130
- append_to_buffer(";");
180
+ append_indentation();
181
+ append_token("@import", import);
182
+ append_mandatory_space();
183
+ append_string(import->file_name());
184
+ append_delimiter();
131
185
  }
132
186
 
133
187
  void Inspect::operator()(Warning* warning)
134
188
  {
135
- if (ctx) ctx->source_map.add_mapping(warning);
136
- append_to_buffer("@warn ");
189
+ append_indentation();
190
+ append_token("@warn", warning);
191
+ append_mandatory_space();
137
192
  warning->message()->perform(this);
138
- append_to_buffer(";");
193
+ append_delimiter();
139
194
  }
140
195
 
141
196
  void Inspect::operator()(Error* error)
142
197
  {
143
- if (ctx) ctx->source_map.add_mapping(error);
144
- append_to_buffer("@error ");
198
+ append_indentation();
199
+ append_token("@error", error);
200
+ append_mandatory_space();
145
201
  error->message()->perform(this);
146
- append_to_buffer(";");
202
+ append_delimiter();
147
203
  }
148
204
 
149
205
  void Inspect::operator()(Debug* debug)
150
206
  {
151
- if (ctx) ctx->source_map.add_mapping(debug);
152
- append_to_buffer("@debug ");
207
+ append_indentation();
208
+ append_token("@debug", debug);
209
+ append_mandatory_space();
153
210
  debug->value()->perform(this);
154
- append_to_buffer(";");
211
+ append_delimiter();
155
212
  }
156
213
 
157
214
  void Inspect::operator()(Comment* comment)
158
215
  {
216
+ in_comment = true;
159
217
  comment->text()->perform(this);
218
+ in_comment = false;
160
219
  }
161
220
 
162
221
  void Inspect::operator()(If* cond)
163
222
  {
164
- append_to_buffer("@if ");
223
+ append_indentation();
224
+ append_token("@if", cond);
225
+ append_mandatory_space();
165
226
  cond->predicate()->perform(this);
166
227
  cond->consequent()->perform(this);
167
228
  if (cond->alternative()) {
168
- append_to_buffer("\n");
169
- indent();
170
- append_to_buffer("else");
229
+ append_optional_linefeed();
230
+ append_indentation();
231
+ append_string("else");
171
232
  cond->alternative()->perform(this);
172
233
  }
173
234
  }
174
235
 
175
236
  void Inspect::operator()(For* loop)
176
237
  {
177
- append_to_buffer("@for ");
178
- append_to_buffer(loop->variable());
179
- append_to_buffer(" from ");
238
+ append_indentation();
239
+ append_token("@for", loop);
240
+ append_mandatory_space();
241
+ append_string(loop->variable());
242
+ append_string(" from ");
180
243
  loop->lower_bound()->perform(this);
181
- append_to_buffer((loop->is_inclusive() ? " through " : " to "));
244
+ append_string(loop->is_inclusive() ? " through " : " to ");
182
245
  loop->upper_bound()->perform(this);
183
246
  loop->block()->perform(this);
184
247
  }
185
248
 
186
249
  void Inspect::operator()(Each* loop)
187
250
  {
188
- append_to_buffer("@each ");
189
- append_to_buffer(loop->variables()[0]);
251
+ append_indentation();
252
+ append_token("@each", loop);
253
+ append_mandatory_space();
254
+ append_string(loop->variables()[0]);
190
255
  for (size_t i = 1, L = loop->variables().size(); i < L; ++i) {
191
- append_to_buffer(", ");
192
- append_to_buffer(loop->variables()[i]);
256
+ append_comma_separator();
257
+ append_string(loop->variables()[i]);
193
258
  }
194
- append_to_buffer(" in ");
259
+ append_string(" in ");
195
260
  loop->list()->perform(this);
196
261
  loop->block()->perform(this);
197
262
  }
198
263
 
199
264
  void Inspect::operator()(While* loop)
200
265
  {
201
- append_to_buffer("@while ");
266
+ append_indentation();
267
+ append_token("@while", loop);
268
+ append_mandatory_space();
202
269
  loop->predicate()->perform(this);
203
270
  loop->block()->perform(this);
204
271
  }
205
272
 
206
273
  void Inspect::operator()(Return* ret)
207
274
  {
208
- append_to_buffer("@return ");
275
+ append_indentation();
276
+ append_token("@return", ret);
277
+ append_mandatory_space();
209
278
  ret->value()->perform(this);
210
- append_to_buffer(";");
279
+ append_delimiter();
211
280
  }
212
281
 
213
282
  void Inspect::operator()(Extension* extend)
214
283
  {
215
- append_to_buffer("@extend ");
284
+ append_indentation();
285
+ append_token("@extend", extend);
286
+ append_mandatory_space();
216
287
  extend->selector()->perform(this);
217
- append_to_buffer(";");
288
+ append_delimiter();
218
289
  }
219
290
 
220
291
  void Inspect::operator()(Definition* def)
221
292
  {
293
+ append_indentation();
222
294
  if (def->type() == Definition::MIXIN) {
223
- append_to_buffer("@mixin ");
295
+ append_token("@mixin", def);
296
+ append_mandatory_space();
224
297
  } else {
225
- append_to_buffer("@function ");
298
+ append_token("@function", def);
299
+ append_mandatory_space();
226
300
  }
227
- append_to_buffer(def->name());
301
+ append_string(def->name());
228
302
  def->parameters()->perform(this);
229
303
  def->block()->perform(this);
230
304
  }
231
305
 
232
306
  void Inspect::operator()(Mixin_Call* call)
233
307
  {
234
- append_to_buffer(string("@include ") += call->name());
308
+ append_indentation();
309
+ append_token("@include", call);
310
+ append_mandatory_space();
311
+ append_string(call->name());
235
312
  if (call->arguments()) {
236
313
  call->arguments()->perform(this);
237
314
  }
238
315
  if (call->block()) {
239
- append_to_buffer(" ");
316
+ append_optional_space();
240
317
  call->block()->perform(this);
241
318
  }
242
- if (!call->block()) append_to_buffer(";");
319
+ if (!call->block()) append_delimiter();
243
320
  }
244
321
 
245
322
  void Inspect::operator()(Content* content)
246
323
  {
247
- if (ctx) ctx->source_map.add_mapping(content);
248
- append_to_buffer("@content;");
324
+ append_indentation();
325
+ append_token("@content", content);
326
+ append_delimiter();
249
327
  }
250
328
 
251
329
  void Inspect::operator()(Map* map)
@@ -253,52 +331,60 @@ namespace Sass {
253
331
  if (map->empty()) return;
254
332
  if (map->is_invisible()) return;
255
333
  bool items_output = false;
256
- append_to_buffer("(");
334
+ append_string("(");
257
335
  for (auto key : map->keys()) {
258
336
  if (key->is_invisible()) continue;
259
337
  if (map->at(key)->is_invisible()) continue;
260
- if (items_output) append_to_buffer(", ");
338
+ if (items_output) append_comma_separator();
261
339
  key->perform(this);
262
- append_to_buffer(": ");
340
+ append_colon_separator();
263
341
  map->at(key)->perform(this);
264
342
  items_output = true;
265
343
  }
266
- append_to_buffer(")");
344
+ append_string(")");
267
345
  }
268
346
 
269
347
  void Inspect::operator()(List* list)
270
348
  {
271
- string sep(list->separator() == List::SPACE ? " " : ", ");
349
+ string sep(list->separator() == List::SPACE ? " " : ",");
350
+ if (output_style() != COMPRESSED && sep == ",") sep += " ";
351
+ else if (in_media_block && sep != " ") sep += " "; // verified
272
352
  if (list->empty()) return;
273
353
  bool items_output = false;
354
+ in_declaration_list = in_declaration;
274
355
  for (size_t i = 0, L = list->length(); i < L; ++i) {
275
356
  Expression* list_item = (*list)[i];
276
357
  if (list_item->is_invisible()) {
277
358
  continue;
278
359
  }
279
- if (items_output) append_to_buffer(sep);
360
+ if (items_output) {
361
+ append_string(sep);
362
+ }
363
+ if (items_output && sep != " ")
364
+ append_optional_space();
280
365
  list_item->perform(this);
281
366
  items_output = true;
282
367
  }
368
+ in_declaration_list = false;
283
369
  }
284
370
 
285
371
  void Inspect::operator()(Binary_Expression* expr)
286
372
  {
287
373
  expr->left()->perform(this);
288
374
  switch (expr->type()) {
289
- case Binary_Expression::AND: append_to_buffer(" and "); break;
290
- case Binary_Expression::OR: append_to_buffer(" or "); break;
291
- case Binary_Expression::EQ: append_to_buffer(" == "); break;
292
- case Binary_Expression::NEQ: append_to_buffer(" != "); break;
293
- case Binary_Expression::GT: append_to_buffer(" > "); break;
294
- case Binary_Expression::GTE: append_to_buffer(" >= "); break;
295
- case Binary_Expression::LT: append_to_buffer(" < "); break;
296
- case Binary_Expression::LTE: append_to_buffer(" <= "); break;
297
- case Binary_Expression::ADD: append_to_buffer(" + "); break;
298
- case Binary_Expression::SUB: append_to_buffer(" - "); break;
299
- case Binary_Expression::MUL: append_to_buffer(" * "); break;
300
- case Binary_Expression::DIV: append_to_buffer("/"); break;
301
- case Binary_Expression::MOD: append_to_buffer(" % "); break;
375
+ case Binary_Expression::AND: append_string(" and "); break;
376
+ case Binary_Expression::OR: append_string(" or "); break;
377
+ case Binary_Expression::EQ: append_string(" == "); break;
378
+ case Binary_Expression::NEQ: append_string(" != "); break;
379
+ case Binary_Expression::GT: append_string(" > "); break;
380
+ case Binary_Expression::GTE: append_string(" >= "); break;
381
+ case Binary_Expression::LT: append_string(" < "); break;
382
+ case Binary_Expression::LTE: append_string(" <= "); break;
383
+ case Binary_Expression::ADD: append_string(" + "); break;
384
+ case Binary_Expression::SUB: append_string(" - "); break;
385
+ case Binary_Expression::MUL: append_string(" * "); break;
386
+ case Binary_Expression::DIV: append_string("/"); break;
387
+ case Binary_Expression::MOD: append_string(" % "); break;
302
388
  default: break; // shouldn't get here
303
389
  }
304
390
  expr->right()->perform(this);
@@ -306,14 +392,14 @@ namespace Sass {
306
392
 
307
393
  void Inspect::operator()(Unary_Expression* expr)
308
394
  {
309
- if (expr->type() == Unary_Expression::PLUS) append_to_buffer("+");
310
- else append_to_buffer("-");
395
+ if (expr->type() == Unary_Expression::PLUS) append_string("+");
396
+ else append_string("-");
311
397
  expr->operand()->perform(this);
312
398
  }
313
399
 
314
400
  void Inspect::operator()(Function_Call* call)
315
401
  {
316
- append_to_buffer(call->name());
402
+ append_token(call->name(), call);
317
403
  call->arguments()->perform(this);
318
404
  }
319
405
 
@@ -325,34 +411,13 @@ namespace Sass {
325
411
 
326
412
  void Inspect::operator()(Variable* var)
327
413
  {
328
- append_to_buffer(var->name());
414
+ append_token(var->name(), var);
329
415
  }
330
416
 
331
417
  void Inspect::operator()(Textual* txt)
332
418
  {
333
- append_to_buffer(txt->value());
334
- }
335
-
336
- // helper functions for serializing numbers
337
- // string frac_to_string(double f, size_t p) {
338
- // stringstream ss;
339
- // ss.setf(ios::fixed, ios::floatfield);
340
- // ss.precision(p);
341
- // ss << f;
342
- // string result(ss.str().substr(f < 0 ? 2 : 1));
343
- // size_t i = result.size() - 1;
344
- // while (result[i] == '0') --i;
345
- // result = result.substr(0, i+1);
346
- // return result;
347
- // }
348
- // string double_to_string(double d, size_t p) {
349
- // stringstream ss;
350
- // double ipart;
351
- // double fpart = std::modf(d, &ipart);
352
- // ss << ipart;
353
- // if (fpart != 0) ss << frac_to_string(fpart, 5);
354
- // return ss.str();
355
- // }
419
+ append_token(txt->value(), txt);
420
+ }
356
421
 
357
422
  void Inspect::operator()(Number* n)
358
423
  {
@@ -368,10 +433,14 @@ namespace Sass {
368
433
  d.resize(d.length()-1);
369
434
  }
370
435
  if (d[d.length()-1] == '.') d.resize(d.length()-1);
371
- if (n->numerator_units().size() > 1 || n->denominator_units().size() > 0) {
372
- error(d + n->unit() + " is not a valid CSS value", n->path(), n->position());
373
- }
374
- if (!n->zero()) {
436
+ if (n->numerator_units().size() > 1 ||
437
+ n->denominator_units().size() > 0 ||
438
+ (n->numerator_units().size() && n->numerator_units()[0].find_first_of('/') != string::npos) ||
439
+ (n->numerator_units().size() && n->numerator_units()[0].find_first_of('*') != string::npos)
440
+ ) {
441
+ error(d + n->unit() + " isn't a valid CSS value.", n->pstate());
442
+ }
443
+ if (!n->zero() && !in_declaration_list) {
375
444
  if (d.substr(0, 3) == "-0.") d.erase(1, 1);
376
445
  if (d.substr(0, 2) == "0.") d.erase(0, 1);
377
446
  }
@@ -381,8 +450,7 @@ namespace Sass {
381
450
  // a value before it got truncated
382
451
  if (d == "0" && nonzero) d = "0.0";
383
452
  // append number and unit
384
- append_to_buffer(d);
385
- append_to_buffer(n->unit());
453
+ append_token(d + n->unit(), n);
386
454
  }
387
455
 
388
456
  // helper function for serializing colors
@@ -396,47 +464,85 @@ namespace Sass {
396
464
  void Inspect::operator()(Color* c)
397
465
  {
398
466
  stringstream ss;
467
+
468
+ // check if we prefer short hex colors
469
+ bool want_short = output_style() == COMPRESSED;
470
+
471
+ // original color name
472
+ // maybe an unknown token
473
+ string name = c->disp();
474
+
475
+ // resolved color
476
+ string res_name = name;
477
+
399
478
  double r = round(cap_channel<0xff>(c->r()));
400
479
  double g = round(cap_channel<0xff>(c->g()));
401
480
  double b = round(cap_channel<0xff>(c->b()));
402
481
  double a = cap_channel<1> (c->a());
403
482
 
483
+ // get color from given name (if one was given at all)
484
+ if (name != "" && ctx && ctx->names_to_colors.count(name)) {
485
+ Color* n = ctx->names_to_colors[name];
486
+ r = round(cap_channel<0xff>(n->r()));
487
+ g = round(cap_channel<0xff>(n->g()));
488
+ b = round(cap_channel<0xff>(n->b()));
489
+ a = cap_channel<1> (n->a());
490
+ }
491
+ // otherwise get the possible resolved color name
492
+ else {
493
+ int numval = static_cast<int>(r) * 0x10000 + static_cast<int>(g) * 0x100 + static_cast<int>(b);
494
+ if (ctx && ctx->colors_to_names.count(numval))
495
+ res_name = ctx->colors_to_names[numval];
496
+ }
497
+
498
+ stringstream hexlet;
499
+ hexlet << '#' << setw(1) << setfill('0');
500
+ // create a short color hexlet if there is any need for it
501
+ if (want_short && is_color_doublet(r, g, b) && a == 1) {
502
+ hexlet << hex << setw(1) << (static_cast<unsigned long>(r) >> 4);
503
+ hexlet << hex << setw(1) << (static_cast<unsigned long>(g) >> 4);
504
+ hexlet << hex << setw(1) << (static_cast<unsigned long>(b) >> 4);
505
+ } else {
506
+ hexlet << hex << setw(2) << static_cast<unsigned long>(r);
507
+ hexlet << hex << setw(2) << static_cast<unsigned long>(g);
508
+ hexlet << hex << setw(2) << static_cast<unsigned long>(b);
509
+ }
510
+
404
511
  // retain the originally specified color definition if unchanged
405
- if (!c->disp().empty()) {
406
- ss << c->disp();
512
+ if (name != "") {
513
+ ss << name;
407
514
  }
408
515
  else if (r == 0 && g == 0 && b == 0 && a == 0) {
409
516
  ss << "transparent";
410
517
  }
411
518
  else if (a >= 1) {
412
- // see if it's a named color
413
- int numval = r * 0x10000;
414
- numval += g * 0x100;
415
- numval += b;
416
- if (ctx && ctx->colors_to_names.count(numval)) {
417
- ss << ctx->colors_to_names[numval];
519
+ if (res_name != "") {
520
+ if (want_short && hexlet.str().size() < res_name.size()) {
521
+ ss << hexlet.str();
522
+ } else {
523
+ ss << res_name;
524
+ }
418
525
  }
419
526
  else {
420
- // otherwise output the hex triplet
421
- ss << '#' << setw(2) << setfill('0');
422
- ss << hex << setw(2) << static_cast<unsigned long>(r);
423
- ss << hex << setw(2) << static_cast<unsigned long>(g);
424
- ss << hex << setw(2) << static_cast<unsigned long>(b);
527
+ ss << hexlet.str();
425
528
  }
426
529
  }
427
530
  else {
428
531
  ss << "rgba(";
429
- ss << static_cast<unsigned long>(r) << ", ";
430
- ss << static_cast<unsigned long>(g) << ", ";
431
- ss << static_cast<unsigned long>(b) << ", ";
532
+ ss << static_cast<unsigned long>(r) << ",";
533
+ if (output_style() != COMPRESSED) ss << " ";
534
+ ss << static_cast<unsigned long>(g) << ",";
535
+ if (output_style() != COMPRESSED) ss << " ";
536
+ ss << static_cast<unsigned long>(b) << ",";
537
+ if (output_style() != COMPRESSED) ss << " ";
432
538
  ss << a << ')';
433
539
  }
434
- append_to_buffer(ss.str());
540
+ append_token(ss.str(), c);
435
541
  }
436
542
 
437
543
  void Inspect::operator()(Boolean* b)
438
544
  {
439
- append_to_buffer(b->value() ? "true" : "false");
545
+ append_token(b->value() ? "true" : "false", b);
440
546
  }
441
547
 
442
548
  void Inspect::operator()(String_Schema* ss)
@@ -444,15 +550,27 @@ namespace Sass {
444
550
  // Evaluation should turn these into String_Constants, so this method is
445
551
  // only for inspection purposes.
446
552
  for (size_t i = 0, L = ss->length(); i < L; ++i) {
447
- if ((*ss)[i]->is_interpolant()) append_to_buffer("#{");
553
+ if ((*ss)[i]->is_interpolant()) append_string("#{");
448
554
  (*ss)[i]->perform(this);
449
- if ((*ss)[i]->is_interpolant()) append_to_buffer("}");
555
+ if ((*ss)[i]->is_interpolant()) append_string("}");
450
556
  }
451
557
  }
452
558
 
453
559
  void Inspect::operator()(String_Constant* s)
454
560
  {
455
- append_to_buffer(s->needs_unquoting() ? unquote(s->value()) : s->value());
561
+ if (String_Quoted* quoted = dynamic_cast<String_Quoted*>(s)) {
562
+ return Inspect::operator()(quoted);
563
+ }
564
+ append_token(s->value(), s);
565
+ }
566
+
567
+ void Inspect::operator()(String_Quoted* s)
568
+ {
569
+ if (s->quote_mark()) {
570
+ append_token(quote(s->value(), s->quote_mark()), s);
571
+ } else {
572
+ append_token(s->value(), s);
573
+ }
456
574
  }
457
575
 
458
576
  void Inspect::operator()(Feature_Query* fq)
@@ -466,40 +584,46 @@ namespace Sass {
466
584
 
467
585
  void Inspect::operator()(Feature_Query_Condition* fqc)
468
586
  {
469
- if (fqc->operand() == Feature_Query_Condition::AND)
470
- append_to_buffer(" and ");
471
- else if (fqc->operand() == Feature_Query_Condition::OR)
472
- append_to_buffer(" or ");
473
- else if (fqc->operand() == Feature_Query_Condition::NOT)
474
- append_to_buffer(" not ");
587
+ if (fqc->operand() == Feature_Query_Condition::AND) {
588
+ append_mandatory_space();
589
+ append_token("and", fqc);
590
+ append_mandatory_space();
591
+ } else if (fqc->operand() == Feature_Query_Condition::OR) {
592
+ append_mandatory_space();
593
+ append_token("or", fqc);
594
+ append_mandatory_space();
595
+ } else if (fqc->operand() == Feature_Query_Condition::NOT) {
596
+ append_mandatory_space();
597
+ append_token("not", fqc);
598
+ append_mandatory_space();
599
+ }
475
600
 
476
- if (!fqc->is_root()) append_to_buffer("(");
601
+ if (!fqc->is_root()) append_string("(");
477
602
 
478
603
  if (!fqc->length()) {
479
604
  fqc->feature()->perform(this);
480
- append_to_buffer(": ");
605
+ append_string(": "); // verified
481
606
  fqc->value()->perform(this);
482
607
  }
483
- // else
484
608
  for (size_t i = 0, L = fqc->length(); i < L; ++i)
485
609
  (*fqc)[i]->perform(this);
486
610
 
487
- if (!fqc->is_root()) append_to_buffer(")");
611
+ if (!fqc->is_root()) append_string(")");
488
612
  }
489
613
 
490
614
  void Inspect::operator()(Media_Query* mq)
491
615
  {
492
616
  size_t i = 0;
493
617
  if (mq->media_type()) {
494
- if (mq->is_negated()) append_to_buffer("not ");
495
- else if (mq->is_restricted()) append_to_buffer("only ");
618
+ if (mq->is_negated()) append_string("not ");
619
+ else if (mq->is_restricted()) append_string("only ");
496
620
  mq->media_type()->perform(this);
497
621
  }
498
622
  else {
499
623
  (*mq)[i++]->perform(this);
500
624
  }
501
625
  for (size_t L = mq->length(); i < L; ++i) {
502
- append_to_buffer(" and ");
626
+ append_string(" and ");
503
627
  (*mq)[i]->perform(this);
504
628
  }
505
629
  }
@@ -510,77 +634,96 @@ namespace Sass {
510
634
  mqe->feature()->perform(this);
511
635
  }
512
636
  else {
513
- append_to_buffer("(");
637
+ append_string("(");
514
638
  mqe->feature()->perform(this);
515
639
  if (mqe->value()) {
516
- append_to_buffer(": ");
640
+ append_string(": "); // verified
517
641
  mqe->value()->perform(this);
518
642
  }
519
- append_to_buffer(")");
643
+ append_string(")");
644
+ }
645
+ }
646
+
647
+ void Inspect::operator()(At_Root_Expression* ae)
648
+ {
649
+ if (ae->is_interpolated()) {
650
+ ae->feature()->perform(this);
651
+ }
652
+ else {
653
+ append_string("(");
654
+ ae->feature()->perform(this);
655
+ if (ae->value()) {
656
+ append_colon_separator();
657
+ ae->value()->perform(this);
658
+ }
659
+ append_string(")");
520
660
  }
521
661
  }
522
662
 
523
663
  void Inspect::operator()(Null* n)
524
664
  {
525
- append_to_buffer("null");
665
+ append_token("null", n);
526
666
  }
527
667
 
528
668
  // parameters and arguments
529
669
  void Inspect::operator()(Parameter* p)
530
670
  {
531
- append_to_buffer(p->name());
671
+ append_token(p->name(), p);
532
672
  if (p->default_value()) {
533
- append_to_buffer(": ");
673
+ append_colon_separator();
534
674
  p->default_value()->perform(this);
535
675
  }
536
676
  else if (p->is_rest_parameter()) {
537
- append_to_buffer("...");
677
+ append_string("...");
538
678
  }
539
679
  }
540
680
 
541
681
  void Inspect::operator()(Parameters* p)
542
682
  {
543
- append_to_buffer("(");
683
+ append_string("(");
544
684
  if (!p->empty()) {
545
685
  (*p)[0]->perform(this);
546
686
  for (size_t i = 1, L = p->length(); i < L; ++i) {
547
- append_to_buffer(", ");
687
+ append_comma_separator();
548
688
  (*p)[i]->perform(this);
549
689
  }
550
690
  }
551
- append_to_buffer(")");
691
+ append_string(")");
552
692
  }
553
693
 
554
694
  void Inspect::operator()(Argument* a)
555
695
  {
556
696
  if (!a->name().empty()) {
557
- append_to_buffer(a->name());
558
- append_to_buffer(": ");
697
+ append_token(a->name(), a);
698
+ append_colon_separator();
559
699
  }
560
700
  // Special case: argument nulls can be ignored
561
701
  if (a->value()->concrete_type() == Expression::NULL_VAL) {
562
702
  return;
563
703
  }
564
- a->value()->perform(this);
704
+ if (a->value()->concrete_type() == Expression::STRING) {
705
+ String_Constant* s = static_cast<String_Constant*>(a->value());
706
+ s->perform(this);
707
+ } else a->value()->perform(this);
565
708
  if (a->is_rest_argument()) {
566
- append_to_buffer("...");
709
+ append_string("...");
567
710
  }
568
711
  }
569
712
 
570
713
  void Inspect::operator()(Arguments* a)
571
714
  {
572
- append_to_buffer("(");
715
+ append_string("(");
573
716
  if (!a->empty()) {
574
717
  (*a)[0]->perform(this);
575
718
  for (size_t i = 1, L = a->length(); i < L; ++i) {
576
- append_to_buffer(", ");
719
+ append_string(", "); // verified
720
+ // Sass Bug? append_comma_separator();
577
721
  (*a)[i]->perform(this);
578
722
  }
579
723
  }
580
- append_to_buffer(")");
724
+ append_string(")");
581
725
  }
582
726
 
583
- // selectors
584
727
  void Inspect::operator()(Selector_Schema* s)
585
728
  {
586
729
  s->contents()->perform(this);
@@ -589,57 +732,58 @@ namespace Sass {
589
732
  void Inspect::operator()(Selector_Reference* ref)
590
733
  {
591
734
  if (ref->selector()) ref->selector()->perform(this);
592
- else append_to_buffer("&");
735
+ else append_string("&");
593
736
  }
594
737
 
595
738
  void Inspect::operator()(Selector_Placeholder* s)
596
739
  {
597
- append_to_buffer(s->name());
740
+ append_token(s->name(), s);
741
+ if (s->has_line_break()) append_optional_linefeed();
742
+ if (s->has_line_break()) append_indentation();
743
+
598
744
  }
599
745
 
600
746
  void Inspect::operator()(Type_Selector* s)
601
747
  {
602
- if (ctx) ctx->source_map.add_mapping(s);
603
- append_to_buffer(s->name());
748
+ append_token(s->name(), s);
604
749
  }
605
750
 
606
751
  void Inspect::operator()(Selector_Qualifier* s)
607
752
  {
608
- if (ctx) ctx->source_map.add_mapping(s);
609
- append_to_buffer(s->name());
753
+ append_token(s->name(), s);
754
+ if (s->has_line_break()) append_optional_linefeed();
755
+ if (s->has_line_break()) append_indentation();
610
756
  }
611
757
 
612
758
  void Inspect::operator()(Attribute_Selector* s)
613
759
  {
614
- if (ctx) ctx->source_map.add_mapping(s);
615
- append_to_buffer("[");
616
- append_to_buffer(s->name());
760
+ append_string("[");
761
+ add_open_mapping(s);
762
+ append_token(s->name(), s);
617
763
  if (!s->matcher().empty()) {
618
- append_to_buffer(s->matcher());
764
+ append_string(s->matcher());
619
765
  if (s->value()) {
620
766
  s->value()->perform(this);
621
767
  }
622
- // append_to_buffer(s->value());
623
768
  }
624
- append_to_buffer("]");
769
+ add_close_mapping(s);
770
+ append_string("]");
625
771
  }
626
772
 
627
773
  void Inspect::operator()(Pseudo_Selector* s)
628
774
  {
629
- if (ctx) ctx->source_map.add_mapping(s);
630
- append_to_buffer(s->name());
775
+ append_token(s->name(), s);
631
776
  if (s->expression()) {
632
777
  s->expression()->perform(this);
633
- append_to_buffer(")");
778
+ append_string(")");
634
779
  }
635
780
  }
636
781
 
637
782
  void Inspect::operator()(Wrapped_Selector* s)
638
783
  {
639
- if (ctx) ctx->source_map.add_mapping(s);
640
- append_to_buffer(s->name());
784
+ append_token(s->name(), s);
641
785
  s->selector()->perform(this);
642
- append_to_buffer(")");
786
+ append_string(")");
643
787
  }
644
788
 
645
789
  void Inspect::operator()(Compound_Selector* s)
@@ -647,6 +791,9 @@ namespace Sass {
647
791
  for (size_t i = 0, L = s->length(); i < L; ++i) {
648
792
  (*s)[i]->perform(this);
649
793
  }
794
+ if (s->has_line_break()) {
795
+ append_optional_linefeed();
796
+ }
650
797
  }
651
798
 
652
799
  void Inspect::operator()(Complex_Selector* c)
@@ -655,15 +802,34 @@ namespace Sass {
655
802
  Complex_Selector* tail = c->tail();
656
803
  Complex_Selector::Combinator comb = c->combinator();
657
804
  if (head && !head->is_empty_reference()) head->perform(this);
658
- if (head && !head->is_empty_reference() && tail) append_to_buffer(" ");
805
+ bool is_empty = head && head->is_empty_reference();
806
+ bool is_tail = head && !head->is_empty_reference() && tail;
807
+ if (output_style() == COMPRESSED && comb != Complex_Selector::ANCESTOR_OF) scheduled_space = 0;
808
+
659
809
  switch (comb) {
660
- case Complex_Selector::ANCESTOR_OF: break;
661
- case Complex_Selector::PARENT_OF: append_to_buffer(">"); break;
662
- case Complex_Selector::PRECEDES: append_to_buffer("~"); break;
663
- case Complex_Selector::ADJACENT_TO: append_to_buffer("+"); break;
810
+ case Complex_Selector::ANCESTOR_OF:
811
+ if (is_tail) append_mandatory_space();
812
+ break;
813
+ case Complex_Selector::PARENT_OF:
814
+ append_optional_space();
815
+ append_string(">");
816
+ append_optional_space();
817
+ break;
818
+ case Complex_Selector::ADJACENT_TO:
819
+ append_optional_space();
820
+ append_string("+");
821
+ append_optional_space();
822
+ break;
823
+ case Complex_Selector::PRECEDES:
824
+ if (is_empty) append_optional_space();
825
+ else append_mandatory_space();
826
+ append_string("~");
827
+ if (tail) append_mandatory_space();
828
+ else append_optional_space();
829
+ break;
664
830
  }
665
831
  if (tail && comb != Complex_Selector::ANCESTOR_OF) {
666
- append_to_buffer(" ");
832
+ if (c->has_line_break()) append_optional_linefeed();
667
833
  }
668
834
  if (tail) tail->perform(this);
669
835
  }
@@ -671,57 +837,21 @@ namespace Sass {
671
837
  void Inspect::operator()(Selector_List* g)
672
838
  {
673
839
  if (g->empty()) return;
674
- (*g)[0]->perform(this);
675
- for (size_t i = 1, L = g->length(); i < L; ++i) {
676
- append_to_buffer(", ");
840
+ for (size_t i = 0, L = g->length(); i < L; ++i) {
841
+ if (!in_at_rule && i == 0) append_indentation();
677
842
  (*g)[i]->perform(this);
843
+ if (i < L - 1) {
844
+ append_comma_separator();
845
+ if ((*g)[i]->has_line_feed()) {
846
+ append_optional_linefeed();
847
+ append_indentation();
848
+ }
849
+ }
678
850
  }
679
851
  }
680
852
 
681
- inline void Inspect::fallback_impl(AST_Node* n)
682
- { }
683
-
684
- void Inspect::indent()
685
- { append_to_buffer(string(2*indentation, ' ')); }
686
-
687
- string unquote(const string& s)
688
- {
689
- if (s.empty()) return "";
690
- if (s.length() == 1) {
691
- if (s[0] == '"' || s[0] == '\'') return "";
692
- }
693
- char q;
694
- if (*s.begin() == '"' && *s.rbegin() == '"') q = '"';
695
- else if (*s.begin() == '\'' && *s.rbegin() == '\'') q = '\'';
696
- else return s;
697
- string t;
698
- t.reserve(s.length()-2);
699
- for (size_t i = 1, L = s.length()-1; i < L; ++i) {
700
- // if we see a quote, we need to remove the preceding backslash from t
701
- if (s[i-1] == '\\' && s[i] == q) t.erase(t.length()-1);
702
- t.push_back(s[i]);
703
- }
704
- return t;
705
- }
706
-
707
- string quote(const string& s, char q)
708
- {
709
- if (s.empty()) return string(2, q);
710
- if (!q || s[0] == '"' || s[0] == '\'') return s;
711
- string t;
712
- t.reserve(s.length()+2);
713
- t.push_back(q);
714
- for (size_t i = 0, L = s.length(); i < L; ++i) {
715
- if (s[i] == q) t.push_back('\\');
716
- t.push_back(s[i]);
717
- }
718
- t.push_back(q);
719
- return t;
720
- }
721
-
722
- void Inspect::append_to_buffer(const string& text)
853
+ void Inspect::fallback_impl(AST_Node* n)
723
854
  {
724
- buffer += text;
725
855
  }
726
856
 
727
857
  }