sassc 2.3.0 → 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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +5 -0
  4. data/ext/libsass/VERSION +1 -1
  5. data/ext/libsass/include/sass/context.h +3 -0
  6. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  7. data/ext/libsass/src/ast.cpp +117 -117
  8. data/ext/libsass/src/ast.hpp +160 -162
  9. data/ext/libsass/src/ast_def_macros.hpp +10 -10
  10. data/ext/libsass/src/ast_fwd_decl.cpp +2 -2
  11. data/ext/libsass/src/ast_fwd_decl.hpp +61 -52
  12. data/ext/libsass/src/ast_helpers.hpp +5 -5
  13. data/ext/libsass/src/ast_sel_cmp.cpp +18 -18
  14. data/ext/libsass/src/ast_sel_super.cpp +52 -52
  15. data/ext/libsass/src/ast_sel_unify.cpp +16 -16
  16. data/ext/libsass/src/ast_sel_weave.cpp +62 -62
  17. data/ext/libsass/src/ast_selectors.cpp +87 -77
  18. data/ext/libsass/src/ast_selectors.hpp +72 -62
  19. data/ext/libsass/src/ast_supports.cpp +35 -35
  20. data/ext/libsass/src/ast_supports.hpp +29 -29
  21. data/ext/libsass/src/ast_values.cpp +58 -58
  22. data/ext/libsass/src/ast_values.hpp +75 -75
  23. data/ext/libsass/src/backtrace.cpp +9 -9
  24. data/ext/libsass/src/backtrace.hpp +5 -5
  25. data/ext/libsass/src/base64vlq.cpp +2 -2
  26. data/ext/libsass/src/base64vlq.hpp +1 -1
  27. data/ext/libsass/src/bind.cpp +17 -17
  28. data/ext/libsass/src/bind.hpp +1 -1
  29. data/ext/libsass/src/c2ast.cpp +3 -3
  30. data/ext/libsass/src/c2ast.hpp +1 -1
  31. data/ext/libsass/src/check_nesting.cpp +36 -36
  32. data/ext/libsass/src/check_nesting.hpp +2 -2
  33. data/ext/libsass/src/color_maps.cpp +5 -5
  34. data/ext/libsass/src/color_maps.hpp +1 -1
  35. data/ext/libsass/src/context.cpp +63 -60
  36. data/ext/libsass/src/context.hpp +33 -33
  37. data/ext/libsass/src/cssize.cpp +30 -29
  38. data/ext/libsass/src/cssize.hpp +13 -13
  39. data/ext/libsass/src/dart_helpers.hpp +5 -5
  40. data/ext/libsass/src/debugger.hpp +127 -128
  41. data/ext/libsass/src/emitter.cpp +12 -12
  42. data/ext/libsass/src/emitter.hpp +10 -10
  43. data/ext/libsass/src/environment.cpp +27 -27
  44. data/ext/libsass/src/environment.hpp +24 -24
  45. data/ext/libsass/src/error_handling.cpp +42 -42
  46. data/ext/libsass/src/error_handling.hpp +38 -50
  47. data/ext/libsass/src/eval.cpp +138 -132
  48. data/ext/libsass/src/eval.hpp +17 -17
  49. data/ext/libsass/src/eval_selectors.cpp +3 -3
  50. data/ext/libsass/src/expand.cpp +70 -64
  51. data/ext/libsass/src/expand.hpp +12 -12
  52. data/ext/libsass/src/extender.cpp +55 -53
  53. data/ext/libsass/src/extender.hpp +14 -14
  54. data/ext/libsass/src/file.cpp +66 -58
  55. data/ext/libsass/src/file.hpp +23 -25
  56. data/ext/libsass/src/fn_colors.cpp +9 -9
  57. data/ext/libsass/src/fn_lists.cpp +18 -18
  58. data/ext/libsass/src/fn_maps.cpp +3 -3
  59. data/ext/libsass/src/fn_miscs.cpp +15 -15
  60. data/ext/libsass/src/fn_numbers.cpp +7 -7
  61. data/ext/libsass/src/fn_selectors.cpp +8 -8
  62. data/ext/libsass/src/fn_strings.cpp +34 -22
  63. data/ext/libsass/src/fn_utils.cpp +29 -26
  64. data/ext/libsass/src/fn_utils.hpp +10 -10
  65. data/ext/libsass/src/inspect.cpp +35 -34
  66. data/ext/libsass/src/inspect.hpp +21 -21
  67. data/ext/libsass/src/lexer.cpp +3 -1
  68. data/ext/libsass/src/listize.cpp +2 -2
  69. data/ext/libsass/src/mapping.hpp +1 -0
  70. data/ext/libsass/src/memory.hpp +12 -0
  71. data/ext/libsass/src/memory/allocator.cpp +48 -0
  72. data/ext/libsass/src/memory/allocator.hpp +138 -0
  73. data/ext/libsass/src/memory/config.hpp +20 -0
  74. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  75. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  76. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +18 -6
  77. data/ext/libsass/src/operation.hpp +44 -44
  78. data/ext/libsass/src/operators.cpp +18 -18
  79. data/ext/libsass/src/operators.hpp +11 -11
  80. data/ext/libsass/src/ordered_map.hpp +18 -18
  81. data/ext/libsass/src/output.cpp +16 -16
  82. data/ext/libsass/src/output.hpp +5 -5
  83. data/ext/libsass/src/parser.cpp +327 -345
  84. data/ext/libsass/src/parser.hpp +77 -87
  85. data/ext/libsass/src/parser_selectors.cpp +6 -6
  86. data/ext/libsass/src/permutate.hpp +39 -15
  87. data/ext/libsass/src/plugins.cpp +7 -7
  88. data/ext/libsass/src/plugins.hpp +8 -8
  89. data/ext/libsass/src/position.cpp +7 -26
  90. data/ext/libsass/src/position.hpp +44 -21
  91. data/ext/libsass/src/remove_placeholders.cpp +4 -4
  92. data/ext/libsass/src/remove_placeholders.hpp +3 -3
  93. data/ext/libsass/src/sass.cpp +16 -15
  94. data/ext/libsass/src/sass.hpp +9 -5
  95. data/ext/libsass/src/sass_context.cpp +52 -34
  96. data/ext/libsass/src/sass_values.cpp +8 -10
  97. data/ext/libsass/src/settings.hpp +19 -0
  98. data/ext/libsass/src/source.cpp +69 -0
  99. data/ext/libsass/src/source.hpp +95 -0
  100. data/ext/libsass/src/source_data.hpp +32 -0
  101. data/ext/libsass/src/source_map.cpp +22 -18
  102. data/ext/libsass/src/source_map.hpp +12 -9
  103. data/ext/libsass/src/units.cpp +19 -19
  104. data/ext/libsass/src/units.hpp +8 -8
  105. data/ext/libsass/src/utf8_string.cpp +9 -10
  106. data/ext/libsass/src/utf8_string.hpp +7 -6
  107. data/ext/libsass/src/util.cpp +38 -38
  108. data/ext/libsass/src/util.hpp +18 -18
  109. data/ext/libsass/src/util_string.cpp +13 -13
  110. data/ext/libsass/src/util_string.hpp +9 -8
  111. data/ext/libsass/src/values.cpp +12 -12
  112. data/lib/sassc/native.rb +3 -5
  113. data/lib/sassc/version.rb +1 -1
  114. data/test/native_test.rb +4 -4
  115. metadata +14 -5
  116. data/lib/sassc/native/lib_c.rb +0 -21
@@ -30,7 +30,7 @@ namespace Sass {
30
30
  throw Exception::InvalidValue({}, *n);
31
31
  }
32
32
  // use values to_string facility
33
- std::string res = n->to_string(opt);
33
+ sass::string res = n->to_string(opt);
34
34
  // output the final token
35
35
  append_token(res, n);
36
36
  }
@@ -77,7 +77,7 @@ namespace Sass {
77
77
  // declare the charset
78
78
  if (output_style() != COMPRESSED)
79
79
  charset = "@charset \"UTF-8\";"
80
- + std::string(opt.linefeed);
80
+ + sass::string(opt.linefeed);
81
81
  else charset = "\xEF\xBB\xBF";
82
82
  // abort search
83
83
  break;
@@ -111,7 +111,7 @@ namespace Sass {
111
111
  }
112
112
  }
113
113
 
114
- void Output::operator()(Ruleset* r)
114
+ void Output::operator()(StyleRule* r)
115
115
  {
116
116
  Block_Obj b = r->block();
117
117
  SelectorListObj s = r->selector();
@@ -122,7 +122,7 @@ namespace Sass {
122
122
  if (!Util::isPrintable(r, output_style())) {
123
123
  for (size_t i = 0, L = b->length(); i < L; ++i) {
124
124
  const Statement_Obj& stm = b->get(i);
125
- if (Cast<Has_Block>(stm)) {
125
+ if (Cast<ParentStatement>(stm)) {
126
126
  if (!Cast<Declaration>(stm)) {
127
127
  stm->perform(this);
128
128
  }
@@ -135,10 +135,10 @@ namespace Sass {
135
135
  indentation += r->tabs();
136
136
  }
137
137
  if (opt.source_comments) {
138
- std::stringstream ss;
138
+ sass::ostream ss;
139
139
  append_indentation();
140
- std::string path(File::abs2rel(r->pstate().path));
141
- ss << "/* line " << r->pstate().line + 1 << ", " << path << " */";
140
+ sass::string path(File::abs2rel(r->pstate().getPath()));
141
+ ss << "/* line " << r->pstate().getLine() << ", " << path << " */";
142
142
  append_string(ss.str());
143
143
  append_optional_linefeed();
144
144
  }
@@ -151,7 +151,7 @@ namespace Sass {
151
151
  // Check print conditions
152
152
  if (Declaration* dec = Cast<Declaration>(stm)) {
153
153
  if (const String_Constant* valConst = Cast<String_Constant>(dec->value())) {
154
- const std::string& val = valConst->value();
154
+ const sass::string& val = valConst->value();
155
155
  if (const String_Quoted* qstr = Cast<const String_Quoted>(valConst)) {
156
156
  if (!qstr->quote_mark() && val.empty()) {
157
157
  bPrintExpression = false;
@@ -199,18 +199,18 @@ namespace Sass {
199
199
  append_scope_closer();
200
200
  }
201
201
 
202
- void Output::operator()(Supports_Block* f)
202
+ void Output::operator()(SupportsRule* f)
203
203
  {
204
204
  if (f->is_invisible()) return;
205
205
 
206
- Supports_Condition_Obj c = f->condition();
206
+ SupportsConditionObj c = f->condition();
207
207
  Block_Obj b = f->block();
208
208
 
209
209
  // Filter out feature blocks that aren't printable (process its children though)
210
210
  if (!Util::isPrintable(f, output_style())) {
211
211
  for (size_t i = 0, L = b->length(); i < L; ++i) {
212
212
  Statement_Obj stm = b->get(i);
213
- if (Cast<Has_Block>(stm)) {
213
+ if (Cast<ParentStatement>(stm)) {
214
214
  stm->perform(this);
215
215
  }
216
216
  }
@@ -253,11 +253,11 @@ namespace Sass {
253
253
  }
254
254
  }
255
255
 
256
- void Output::operator()(Directive* a)
256
+ void Output::operator()(AtRule* a)
257
257
  {
258
- std::string kwd = a->keyword();
258
+ sass::string kwd = a->keyword();
259
259
  Selector_Obj s = a->selector();
260
- Expression_Obj v = a->value();
260
+ ExpressionObj v = a->value();
261
261
  Block_Obj b = a->block();
262
262
 
263
263
  append_indentation();
@@ -289,7 +289,7 @@ namespace Sass {
289
289
 
290
290
  for (size_t i = 0, L = b->length(); i < L; ++i) {
291
291
  Statement_Obj stm = b->get(i);
292
- stm->perform(this);
292
+ if (stm) stm->perform(this);
293
293
  if (i < L - 1 && format) append_special_linefeed();
294
294
  }
295
295
 
@@ -309,7 +309,7 @@ namespace Sass {
309
309
 
310
310
  void Output::operator()(String_Constant* s)
311
311
  {
312
- std::string value(s->value());
312
+ sass::string value(s->value());
313
313
  if (!in_comment && !in_custom_property) {
314
314
  append_token(string_to_output(value), s);
315
315
  } else {
@@ -20,17 +20,17 @@ namespace Sass {
20
20
  virtual ~Output();
21
21
 
22
22
  protected:
23
- std::string charset;
24
- std::vector<AST_Node*> top_nodes;
23
+ sass::string charset;
24
+ sass::vector<AST_Node*> top_nodes;
25
25
 
26
26
  public:
27
27
  OutputBuffer get_buffer(void);
28
28
 
29
29
  virtual void operator()(Map*);
30
- virtual void operator()(Ruleset*);
31
- virtual void operator()(Supports_Block*);
30
+ virtual void operator()(StyleRule*);
31
+ virtual void operator()(SupportsRule*);
32
32
  virtual void operator()(CssMediaRule*);
33
- virtual void operator()(Directive*);
33
+ virtual void operator()(AtRule*);
34
34
  virtual void operator()(Keyframe_Rule*);
35
35
  virtual void operator()(Import*);
36
36
  virtual void operator()(Comment*);
@@ -23,45 +23,39 @@ namespace Sass {
23
23
  using namespace Constants;
24
24
  using namespace Prelexer;
25
25
 
26
- Parser Parser::from_c_str(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
27
- {
28
- pstate.offset.column = 0;
29
- pstate.offset.line = 0;
30
- Parser p(ctx, pstate, traces, allow_parent);
31
- p.source = source ? source : beg;
32
- p.position = beg ? beg : p.source;
33
- p.end = p.position + strlen(p.position);
34
- Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
35
- p.block_stack.push_back(root);
36
- root->is_root(true);
37
- return p;
38
- }
39
26
 
40
- Parser Parser::from_c_str(const char* beg, const char* end, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
27
+ Parser::Parser(SourceData* source, Context& ctx, Backtraces traces, bool allow_parent) :
28
+ SourceSpan(source),
29
+ ctx(ctx),
30
+ source(source),
31
+ begin(source->begin()),
32
+ position(source->begin()),
33
+ end(source->end()),
34
+ before_token(0, 0),
35
+ after_token(0, 0),
36
+ pstate(source->getSourceSpan()),
37
+ traces(traces),
38
+ indentation(0),
39
+ nestings(0),
40
+ allow_parent(allow_parent)
41
41
  {
42
- pstate.offset.column = 0;
43
- pstate.offset.line = 0;
44
- Parser p(ctx, pstate, traces, allow_parent);
45
- p.source = source ? source : beg;
46
- p.position = beg ? beg : p.source;
47
- p.end = end ? end : p.position + strlen(p.position);
48
42
  Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
49
- p.block_stack.push_back(root);
43
+ stack.push_back(Scope::Root);
44
+ block_stack.push_back(root);
50
45
  root->is_root(true);
51
- return p;
52
46
  }
53
47
 
54
- void Parser::advanceToNextToken() {
48
+ void Parser::advanceToNextToken() {
55
49
  lex < css_comments >(false);
56
50
  // advance to position
57
- pstate += pstate.offset;
51
+ pstate.position += pstate.offset;
58
52
  pstate.offset.column = 0;
59
53
  pstate.offset.line = 0;
60
54
  }
61
55
 
62
- SelectorListObj Parser::parse_selector(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
56
+ SelectorListObj Parser::parse_selector(SourceData* source, Context& ctx, Backtraces traces, bool allow_parent)
63
57
  {
64
- Parser p = Parser::from_c_str(beg, ctx, traces, pstate, source, allow_parent);
58
+ Parser p(source, ctx, traces, allow_parent);
65
59
  // ToDo: remap the source-map entries somehow
66
60
  return p.parseSelectorList(false);
67
61
  }
@@ -72,18 +66,6 @@ namespace Sass {
72
66
  && ! peek_css<exactly<'{'>>(start);
73
67
  }
74
68
 
75
- Parser Parser::from_token(Token t, Context& ctx, Backtraces traces, ParserState pstate, const char* source)
76
- {
77
- Parser p(ctx, pstate, traces);
78
- p.source = source ? source : t.begin;
79
- p.position = t.begin ? t.begin : p.source;
80
- p.end = t.end ? t.end : p.position + strlen(p.position);
81
- Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
82
- p.block_stack.push_back(root);
83
- root->is_root(true);
84
- return p;
85
- }
86
-
87
69
  /* main entry point to parse root block */
88
70
  Block_Obj Parser::parse()
89
71
  {
@@ -96,7 +78,7 @@ namespace Sass {
96
78
 
97
79
  // report invalid utf8
98
80
  if (it != end) {
99
- pstate += Offset::init(position, it);
81
+ pstate.position += Offset::init(position, it);
100
82
  traces.push_back(Backtrace(pstate));
101
83
  throw Exception::InvalidSass(pstate, traces, "Invalid UTF-8 sequence");
102
84
  }
@@ -107,7 +89,7 @@ namespace Sass {
107
89
  // check seems a bit esoteric but works
108
90
  if (ctx.resources.size() == 1) {
109
91
  // apply headers only on very first include
110
- ctx.apply_custom_headers(root, path, pstate);
92
+ ctx.apply_custom_headers(root, getPath(), pstate);
111
93
  }
112
94
 
113
95
  // parse children nodes
@@ -327,33 +309,33 @@ namespace Sass {
327
309
  Import_Obj Parser::parse_import()
328
310
  {
329
311
  Import_Obj imp = SASS_MEMORY_NEW(Import, pstate);
330
- std::vector<std::pair<std::string,Function_Call_Obj>> to_import;
312
+ sass::vector<std::pair<sass::string,Function_Call_Obj>> to_import;
331
313
  bool first = true;
332
314
  do {
333
315
  while (lex< block_comment >());
334
316
  if (lex< quoted_string >()) {
335
- to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed), {}));
317
+ to_import.push_back(std::pair<sass::string,Function_Call_Obj>(sass::string(lexed), {}));
336
318
  }
337
319
  else if (lex< uri_prefix >()) {
338
320
  Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
339
- Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, std::string("url"), args);
321
+ Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, sass::string("url"), args);
340
322
 
341
323
  if (lex< quoted_string >()) {
342
- Expression_Obj quoted_url = parse_string();
324
+ ExpressionObj quoted_url = parse_string();
343
325
  args->append(SASS_MEMORY_NEW(Argument, quoted_url->pstate(), quoted_url));
344
326
  }
345
327
  else if (String_Obj string_url = parse_url_function_argument()) {
346
328
  args->append(SASS_MEMORY_NEW(Argument, string_url->pstate(), string_url));
347
329
  }
348
330
  else if (peek < skip_over_scopes < exactly < '(' >, exactly < ')' > > >(position)) {
349
- Expression_Obj braced_url = parse_list(); // parse_interpolated_chunk(lexed);
331
+ ExpressionObj braced_url = parse_list(); // parse_interpolated_chunk(lexed);
350
332
  args->append(SASS_MEMORY_NEW(Argument, braced_url->pstate(), braced_url));
351
333
  }
352
334
  else {
353
335
  error("malformed URL");
354
336
  }
355
337
  if (!lex< exactly<')'> >()) error("URI is missing ')'");
356
- to_import.push_back(std::pair<std::string, Function_Call_Obj>("", result));
338
+ to_import.push_back(std::pair<sass::string, Function_Call_Obj>("", result));
357
339
  }
358
340
  else {
359
341
  if (first) error("@import directive requires a url or quoted path");
@@ -372,9 +354,9 @@ namespace Sass {
372
354
  imp->urls().push_back(location.second);
373
355
  }
374
356
  // check if custom importers want to take over the handling
375
- else if (!ctx.call_importers(unquote(location.first), path, pstate, imp)) {
357
+ else if (!ctx.call_importers(unquote(location.first), getPath(), pstate, imp)) {
376
358
  // nobody wants it, so we do our import
377
- ctx.import_url(imp, location.first, path);
359
+ ctx.import_url(imp, location.first, getPath());
378
360
  }
379
361
  }
380
362
 
@@ -383,12 +365,12 @@ namespace Sass {
383
365
 
384
366
  Definition_Obj Parser::parse_definition(Definition::Type which_type)
385
367
  {
386
- std::string which_str(lexed);
368
+ sass::string which_str(lexed);
387
369
  if (!lex< identifier >()) error("invalid name in " + which_str + " definition");
388
- std::string name(Util::normalize_underscores(lexed));
370
+ sass::string name(Util::normalize_underscores(lexed));
389
371
  if (which_type == Definition::FUNCTION && (name == "and" || name == "or" || name == "not"))
390
372
  { error("Invalid function name \"" + name + "\"."); }
391
- ParserState source_position_of_def = pstate;
373
+ SourceSpan source_position_of_def = pstate;
392
374
  Parameters_Obj params = parse_parameters();
393
375
  if (which_type == Definition::MIXIN) stack.push_back(Scope::Mixin);
394
376
  else stack.push_back(Scope::Function);
@@ -422,9 +404,9 @@ namespace Sass {
422
404
  }
423
405
  while (lex< alternatives < spaces, block_comment > >());
424
406
  lex < variable >();
425
- std::string name(Util::normalize_underscores(lexed));
426
- ParserState pos = pstate;
427
- Expression_Obj val;
407
+ sass::string name(Util::normalize_underscores(lexed));
408
+ SourceSpan pos = pstate;
409
+ ExpressionObj val;
428
410
  bool is_rest = false;
429
411
  while (lex< alternatives < spaces, block_comment > >());
430
412
  if (lex< exactly<':'> >()) { // there's a default value
@@ -468,16 +450,16 @@ namespace Sass {
468
450
  Argument_Obj arg;
469
451
  if (peek_css< sequence < variable, optional_css_comments, exactly<':'> > >()) {
470
452
  lex_css< variable >();
471
- std::string name(Util::normalize_underscores(lexed));
472
- ParserState p = pstate;
453
+ sass::string name(Util::normalize_underscores(lexed));
454
+ SourceSpan p = pstate;
473
455
  lex_css< exactly<':'> >();
474
- Expression_Obj val = parse_space_list();
456
+ ExpressionObj val = parse_space_list();
475
457
  arg = SASS_MEMORY_NEW(Argument, p, val, name);
476
458
  }
477
459
  else {
478
460
  bool is_arglist = false;
479
461
  bool is_keyword = false;
480
- Expression_Obj val = parse_space_list();
462
+ ExpressionObj val = parse_space_list();
481
463
  List* l = Cast<List>(val);
482
464
  if (lex_css< exactly< ellipsis > >()) {
483
465
  if (val->concrete_type() == Expression::MAP || (
@@ -492,13 +474,13 @@ namespace Sass {
492
474
 
493
475
  Assignment_Obj Parser::parse_assignment()
494
476
  {
495
- std::string name(Util::normalize_underscores(lexed));
496
- ParserState var_source_position = pstate;
477
+ sass::string name(Util::normalize_underscores(lexed));
478
+ SourceSpan var_source_position = pstate;
497
479
  if (!lex< exactly<':'> >()) error("expected ':' after " + name + " in assignment statement");
498
480
  if (peek_css< alternatives < exactly<';'>, end_of_file > >()) {
499
481
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
500
482
  }
501
- Expression_Obj val;
483
+ ExpressionObj val;
502
484
  Lookahead lookahead = lookahead_for_value(position);
503
485
  if (lookahead.has_interpolants && lookahead.found) {
504
486
  val = parse_value_schema(lookahead.found);
@@ -515,7 +497,7 @@ namespace Sass {
515
497
  }
516
498
 
517
499
  // a ruleset connects a selector and a block
518
- Ruleset_Obj Parser::parse_ruleset(Lookahead lookahead)
500
+ StyleRuleObj Parser::parse_ruleset(Lookahead lookahead)
519
501
  {
520
502
  NESTING_GUARD(nestings);
521
503
  // inherit is_root from parent block
@@ -524,7 +506,7 @@ namespace Sass {
524
506
  // make sure to move up the the last position
525
507
  lex < optional_css_whitespace >(false, true);
526
508
  // create the connector object (add parts later)
527
- Ruleset_Obj ruleset = SASS_MEMORY_NEW(Ruleset, pstate);
509
+ StyleRuleObj ruleset = SASS_MEMORY_NEW(StyleRule, pstate);
528
510
  // parse selector static or as schema to be evaluated later
529
511
  if (lookahead.parsable) {
530
512
  ruleset->selector(parseSelectorList(false));
@@ -569,9 +551,9 @@ namespace Sass {
569
551
  if (const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, end_of_selector)) {
570
552
  // accumulate the preceding segment if the position has advanced
571
553
  if (i < p) {
572
- std::string parsed(i, p);
554
+ sass::string parsed(i, p);
573
555
  String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed);
574
- pstate += Offset(parsed);
556
+ pstate.position += Offset(parsed);
575
557
  str->update_pstate(pstate);
576
558
  schema->append(str);
577
559
  }
@@ -584,15 +566,16 @@ namespace Sass {
584
566
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
585
567
  }
586
568
  // pass inner expression to the parser to resolve nested interpolations
587
- pstate.add(p, p+2);
588
- Expression_Obj interpolant = Parser::from_c_str(p+2, j, ctx, traces, pstate).parse_list();
569
+ LocalOption<const char*> partEnd(end, j);
570
+ LocalOption<const char*> partBeg(position, p + 2);
571
+ ExpressionObj interpolant = parse_list();
589
572
  // set status on the list expression
590
573
  interpolant->is_interpolant(true);
591
574
  // schema->has_interpolants(true);
592
575
  // add to the string schema
593
576
  schema->append(interpolant);
594
577
  // advance parser state
595
- pstate.add(p+2, j);
578
+ pstate.position.add(p+2, j);
596
579
  // advance position
597
580
  i = j;
598
581
  }
@@ -601,9 +584,9 @@ namespace Sass {
601
584
  else {
602
585
  // make sure to add the last bits of the string up to the end (if any)
603
586
  if (i < end_of_selector) {
604
- std::string parsed(i, end_of_selector);
587
+ sass::string parsed(i, end_of_selector);
605
588
  String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed);
606
- pstate += Offset(parsed);
589
+ pstate.position += Offset(parsed);
607
590
  str->update_pstate(pstate);
608
591
  i = end_of_selector;
609
592
  schema->append(str);
@@ -620,7 +603,7 @@ namespace Sass {
620
603
  selector_schema->update_pstate(pstate);
621
604
  schema->update_pstate(pstate);
622
605
 
623
- after_token = before_token = pstate;
606
+ after_token = before_token = pstate.position;
624
607
 
625
608
  // return parsed result
626
609
  return selector_schema.detach();
@@ -644,9 +627,9 @@ namespace Sass {
644
627
  // lex identifier into `lexed` var
645
628
  lex_identifier(); // may error out
646
629
  // normalize underscores to hyphens
647
- std::string name(Util::normalize_underscores(lexed));
630
+ sass::string name(Util::normalize_underscores(lexed));
648
631
  // create the initial mixin call object
649
- Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, {}, {}, {});
632
+ Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, Arguments_Obj{});
650
633
  // parse mandatory arguments
651
634
  call->arguments(parse_arguments());
652
635
  // parse using and optional block parameters
@@ -677,13 +660,13 @@ namespace Sass {
677
660
  {
678
661
  lex < css_comments >(false);
679
662
  if (lex< class_name >()) {
680
- return SASS_MEMORY_NEW(Class_Selector, pstate, lexed);
663
+ return SASS_MEMORY_NEW(ClassSelector, pstate, lexed);
681
664
  }
682
665
  else if (lex< id_name >()) {
683
- return SASS_MEMORY_NEW(Id_Selector, pstate, lexed);
666
+ return SASS_MEMORY_NEW(IDSelector, pstate, lexed);
684
667
  }
685
668
  else if (lex< alternatives < variable, number, static_reference_combinator > >()) {
686
- return SASS_MEMORY_NEW(Type_Selector, pstate, lexed);
669
+ return SASS_MEMORY_NEW(TypeSelector, pstate, lexed);
687
670
  }
688
671
  else if (peek< pseudo_not >()) {
689
672
  return parse_negated_selector2();
@@ -698,7 +681,7 @@ namespace Sass {
698
681
  return parse_attribute_selector();
699
682
  }
700
683
  else if (lex< placeholder >()) {
701
- return SASS_MEMORY_NEW(Placeholder_Selector, pstate, lexed);
684
+ return SASS_MEMORY_NEW(PlaceholderSelector, pstate, lexed);
702
685
  }
703
686
  else {
704
687
  css_error("Invalid CSS", " after ", ": expected selector, was ");
@@ -707,18 +690,18 @@ namespace Sass {
707
690
  return {};
708
691
  }
709
692
 
710
- Pseudo_Selector_Obj Parser::parse_negated_selector2()
693
+ PseudoSelectorObj Parser::parse_negated_selector2()
711
694
  {
712
695
  lex< pseudo_not >();
713
- std::string name(lexed);
714
- ParserState nsource_position = pstate;
696
+ sass::string name(lexed);
697
+ SourceSpan nsource_position = pstate;
715
698
  SelectorListObj negated = parseSelectorList(true);
716
699
  if (!lex< exactly<')'> >()) {
717
700
  error("negated selector is missing ')'");
718
701
  }
719
702
  name.erase(name.size() - 1);
720
703
 
721
- Pseudo_Selector* sel = SASS_MEMORY_NEW(Pseudo_Selector, nsource_position, name.substr(1));
704
+ PseudoSelector* sel = SASS_MEMORY_NEW(PseudoSelector, nsource_position, name.substr(1));
722
705
  sel->selector(negated);
723
706
  return sel;
724
707
  }
@@ -732,7 +715,7 @@ namespace Sass {
732
715
 
733
716
  // Lex one or two colon characters
734
717
  if (lex<pseudo_prefix>()) {
735
- std::string colons(lexed);
718
+ sass::string colons(lexed);
736
719
  // Check if it is a pseudo element
737
720
  bool element = colons.size() == 2;
738
721
 
@@ -744,16 +727,16 @@ namespace Sass {
744
727
  > >())
745
728
  {
746
729
 
747
- std::string name(lexed);
730
+ sass::string name(lexed);
748
731
  name.erase(name.size() - 1);
749
- ParserState p = pstate;
732
+ SourceSpan p = pstate;
750
733
 
751
734
  // specially parse nth-child pseudo selectors
752
735
  if (lex_css < sequence < binomial, word_boundary >>()) {
753
- std::string parsed(lexed); // always compacting binominals (as dart-sass)
736
+ sass::string parsed(lexed); // always compacting binominals (as dart-sass)
754
737
  parsed.erase(std::unique(parsed.begin(), parsed.end(), BothAreSpaces), parsed.end());
755
738
  String_Constant_Obj arg = SASS_MEMORY_NEW(String_Constant, pstate, parsed);
756
- Pseudo_Selector* pseudo = SASS_MEMORY_NEW(Pseudo_Selector, p, name, element);
739
+ PseudoSelector* pseudo = SASS_MEMORY_NEW(PseudoSelector, p, name, element);
757
740
  if (lex < sequence < css_whitespace, insensitive < of_kwd >>>(false)) {
758
741
  pseudo->selector(parseSelectorList(true));
759
742
  }
@@ -767,19 +750,19 @@ namespace Sass {
767
750
  css_error("Invalid CSS", " after ", ": expected An+B expression, was ");
768
751
  }
769
752
 
770
- std::string unvendored = Util::unvendor(name);
753
+ sass::string unvendored = Util::unvendor(name);
771
754
 
772
755
  if (unvendored == "not" || unvendored == "matches" || unvendored == "current" || unvendored == "any" || unvendored == "has" || unvendored == "host" || unvendored == "host-context" || unvendored == "slotted") {
773
756
  if (SelectorListObj wrapped = parseSelectorList(true)) {
774
757
  if (wrapped && lex_css< exactly<')'> >()) {
775
- Pseudo_Selector* pseudo = SASS_MEMORY_NEW(Pseudo_Selector, p, name, element);
758
+ PseudoSelector* pseudo = SASS_MEMORY_NEW(PseudoSelector, p, name, element);
776
759
  pseudo->selector(wrapped);
777
760
  return pseudo;
778
761
  }
779
762
  }
780
763
  } else {
781
764
  String_Schema_Obj arg = parse_css_variable_value();
782
- Pseudo_Selector* pseudo = SASS_MEMORY_NEW(Pseudo_Selector, p, name, element);
765
+ PseudoSelector* pseudo = SASS_MEMORY_NEW(PseudoSelector, p, name, element);
783
766
  pseudo->argument(arg);
784
767
 
785
768
  if (lex_css< exactly<')'> >()) {
@@ -792,7 +775,7 @@ namespace Sass {
792
775
  // EO if pseudo selector
793
776
 
794
777
  else if (lex < sequence< optional < pseudo_prefix >, identifier > >()) {
795
- return SASS_MEMORY_NEW(Pseudo_Selector, pstate, lexed, element);
778
+ return SASS_MEMORY_NEW(PseudoSelector, pstate, lexed, element);
796
779
  }
797
780
  else if (lex < pseudo_prefix >()) {
798
781
  css_error("Invalid CSS", " after ", ": expected pseudoclass or pseudoelement, was ");
@@ -821,23 +804,23 @@ namespace Sass {
821
804
  return sequence < insensitive<'i'>, re_attr_sensitive_close >(src);
822
805
  }
823
806
 
824
- Attribute_Selector_Obj Parser::parse_attribute_selector()
807
+ AttributeSelectorObj Parser::parse_attribute_selector()
825
808
  {
826
- ParserState p = pstate;
809
+ SourceSpan p = pstate;
827
810
  if (!lex_css< attribute_name >()) error("invalid attribute name in attribute selector");
828
- std::string name(lexed);
811
+ sass::string name(lexed);
829
812
  if (lex_css< re_attr_sensitive_close >()) {
830
- return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", {}, {});
813
+ return SASS_MEMORY_NEW(AttributeSelector, p, name, "", String_Obj{});
831
814
  }
832
815
  else if (lex_css< re_attr_insensitive_close >()) {
833
816
  char modifier = lexed.begin[0];
834
- return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", {}, modifier);
817
+ return SASS_MEMORY_NEW(AttributeSelector, p, name, "", String_Obj{}, modifier);
835
818
  }
836
819
  if (!lex_css< alternatives< exact_match, class_match, dash_match,
837
820
  prefix_match, suffix_match, substring_match > >()) {
838
821
  error("invalid operator in attribute selector for " + name);
839
822
  }
840
- std::string matcher(lexed);
823
+ sass::string matcher(lexed);
841
824
 
842
825
  String_Obj value;
843
826
  if (lex_css< identifier >()) {
@@ -851,11 +834,11 @@ namespace Sass {
851
834
  }
852
835
 
853
836
  if (lex_css< re_attr_sensitive_close >()) {
854
- return SASS_MEMORY_NEW(Attribute_Selector, p, name, matcher, value, 0);
837
+ return SASS_MEMORY_NEW(AttributeSelector, p, name, matcher, value, 0);
855
838
  }
856
839
  else if (lex_css< re_attr_insensitive_close >()) {
857
840
  char modifier = lexed.begin[0];
858
- return SASS_MEMORY_NEW(Attribute_Selector, p, name, matcher, value, modifier);
841
+ return SASS_MEMORY_NEW(AttributeSelector, p, name, matcher, value, modifier);
859
842
  }
860
843
  error("unterminated attribute selector for " + name);
861
844
  return {}; // to satisfy compilers (error must not return)
@@ -878,12 +861,12 @@ namespace Sass {
878
861
  String_Obj prop;
879
862
  bool is_custom_property = false;
880
863
  if (lex< sequence< optional< exactly<'*'> >, identifier_schema > >()) {
881
- const std::string property(lexed);
864
+ const sass::string property(lexed);
882
865
  is_custom_property = property.compare(0, 2, "--") == 0;
883
866
  prop = parse_identifier_schema();
884
867
  }
885
868
  else if (lex< sequence< optional< exactly<'*'> >, identifier, zero_plus< block_comment > > >()) {
886
- const std::string property(lexed);
869
+ const sass::string property(lexed);
887
870
  is_custom_property = property.compare(0, 2, "--") == 0;
888
871
  prop = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
889
872
  }
@@ -891,7 +874,7 @@ namespace Sass {
891
874
  css_error("Invalid CSS", " after ", ": expected \"}\", was ");
892
875
  }
893
876
  bool is_indented = true;
894
- const std::string property(lexed);
877
+ const sass::string property(lexed);
895
878
  if (!lex_css< one_plus< exactly<':'> > >()) error("property \"" + escape_string(property) + "\" must be followed by a ':'");
896
879
  if (!is_custom_property && match< sequence< optional_css_comments, exactly<';'> > >()) error("style declaration must contain a value");
897
880
  if (match< sequence< optional_css_comments, exactly<'{'> > >()) is_indented = false; // don't indent if value is empty
@@ -903,7 +886,7 @@ namespace Sass {
903
886
  return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, parse_static_value()/*, lex<kwd_important>()*/);
904
887
  }
905
888
  else {
906
- Expression_Obj value;
889
+ ExpressionObj value;
907
890
  Lookahead lookahead = lookahead_for_value(position);
908
891
  if (lookahead.found) {
909
892
  if (lookahead.has_interpolants) {
@@ -928,10 +911,10 @@ namespace Sass {
928
911
  }
929
912
  }
930
913
 
931
- Expression_Obj Parser::parse_map()
914
+ ExpressionObj Parser::parse_map()
932
915
  {
933
916
  NESTING_GUARD(nestings);
934
- Expression_Obj key = parse_list();
917
+ ExpressionObj key = parse_list();
935
918
  List_Obj map = SASS_MEMORY_NEW(List, pstate, 0, SASS_HASH);
936
919
 
937
920
  // it's not a map so return the lexed value as a list value
@@ -943,7 +926,7 @@ namespace Sass {
943
926
  css_error("Invalid CSS", " after ", ": expected \")\", was ");
944
927
  }
945
928
 
946
- Expression_Obj value = parse_space_list();
929
+ ExpressionObj value = parse_space_list();
947
930
 
948
931
  map->append(key);
949
932
  map->append(value);
@@ -965,14 +948,14 @@ namespace Sass {
965
948
  map->append(value);
966
949
  }
967
950
 
968
- ParserState ps = map->pstate();
969
- ps.offset = pstate - ps + pstate.offset;
951
+ SourceSpan ps = map->pstate();
952
+ ps.offset = pstate.position - ps.position + pstate.offset;
970
953
  map->pstate(ps);
971
954
 
972
955
  return map;
973
956
  }
974
957
 
975
- Expression_Obj Parser::parse_bracket_list()
958
+ ExpressionObj Parser::parse_bracket_list()
976
959
  {
977
960
  NESTING_GUARD(nestings);
978
961
  // check if we have an empty list
@@ -986,7 +969,7 @@ namespace Sass {
986
969
  bool has_paren = peek_css< exactly<'('> >() != NULL;
987
970
 
988
971
  // now try to parse a space list
989
- Expression_Obj list = parse_space_list();
972
+ ExpressionObj list = parse_space_list();
990
973
  // if it's a singleton, return it (don't wrap it)
991
974
  if (!peek_css< exactly<','> >(position)) {
992
975
  List_Obj l = Cast<List>(list);
@@ -1019,14 +1002,14 @@ namespace Sass {
1019
1002
  // parse list returns either a space separated list,
1020
1003
  // a comma separated list or any bare expression found.
1021
1004
  // so to speak: we unwrap items from lists if possible here!
1022
- Expression_Obj Parser::parse_list(bool delayed)
1005
+ ExpressionObj Parser::parse_list(bool delayed)
1023
1006
  {
1024
1007
  NESTING_GUARD(nestings);
1025
1008
  return parse_comma_list(delayed);
1026
1009
  }
1027
1010
 
1028
1011
  // will return singletons unwrapped
1029
- Expression_Obj Parser::parse_comma_list(bool delayed)
1012
+ ExpressionObj Parser::parse_comma_list(bool delayed)
1030
1013
  {
1031
1014
  NESTING_GUARD(nestings);
1032
1015
  // check if we have an empty list
@@ -1038,7 +1021,7 @@ namespace Sass {
1038
1021
  }
1039
1022
 
1040
1023
  // now try to parse a space list
1041
- Expression_Obj list = parse_space_list();
1024
+ ExpressionObj list = parse_space_list();
1042
1025
  // if it's a singleton, return it (don't wrap it)
1043
1026
  if (!peek_css< exactly<','> >(position)) {
1044
1027
  // set_delay doesn't apply to list children
@@ -1066,10 +1049,10 @@ namespace Sass {
1066
1049
  // EO parse_comma_list
1067
1050
 
1068
1051
  // will return singletons unwrapped
1069
- Expression_Obj Parser::parse_space_list()
1052
+ ExpressionObj Parser::parse_space_list()
1070
1053
  {
1071
1054
  NESTING_GUARD(nestings);
1072
- Expression_Obj disj1 = parse_disjunction();
1055
+ ExpressionObj disj1 = parse_disjunction();
1073
1056
  // if it's a singleton, return it (don't wrap it)
1074
1057
  if (peek_css< space_list_terminator >(position)
1075
1058
  ) {
@@ -1091,60 +1074,60 @@ namespace Sass {
1091
1074
  // EO parse_space_list
1092
1075
 
1093
1076
  // parse logical OR operation
1094
- Expression_Obj Parser::parse_disjunction()
1077
+ ExpressionObj Parser::parse_disjunction()
1095
1078
  {
1096
1079
  NESTING_GUARD(nestings);
1097
1080
  advanceToNextToken();
1098
- ParserState state(pstate);
1081
+ SourceSpan state(pstate);
1099
1082
  // parse the left hand side conjunction
1100
- Expression_Obj conj = parse_conjunction();
1083
+ ExpressionObj conj = parse_conjunction();
1101
1084
  // parse multiple right hand sides
1102
- std::vector<Expression_Obj> operands;
1085
+ sass::vector<ExpressionObj> operands;
1103
1086
  while (lex_css< kwd_or >())
1104
1087
  operands.push_back(parse_conjunction());
1105
1088
  // if it's a singleton, return it directly
1106
1089
  if (operands.size() == 0) return conj;
1107
1090
  // fold all operands into one binary expression
1108
- Expression_Obj ex = fold_operands(conj, operands, { Sass_OP::OR });
1109
- state.offset = pstate - state + pstate.offset;
1091
+ ExpressionObj ex = fold_operands(conj, operands, { Sass_OP::OR });
1092
+ state.offset = pstate.position - state.position + pstate.offset;
1110
1093
  ex->pstate(state);
1111
1094
  return ex;
1112
1095
  }
1113
1096
  // EO parse_disjunction
1114
1097
 
1115
1098
  // parse logical AND operation
1116
- Expression_Obj Parser::parse_conjunction()
1099
+ ExpressionObj Parser::parse_conjunction()
1117
1100
  {
1118
1101
  NESTING_GUARD(nestings);
1119
1102
  advanceToNextToken();
1120
- ParserState state(pstate);
1103
+ SourceSpan state(pstate);
1121
1104
  // parse the left hand side relation
1122
- Expression_Obj rel = parse_relation();
1105
+ ExpressionObj rel = parse_relation();
1123
1106
  // parse multiple right hand sides
1124
- std::vector<Expression_Obj> operands;
1107
+ sass::vector<ExpressionObj> operands;
1125
1108
  while (lex_css< kwd_and >()) {
1126
1109
  operands.push_back(parse_relation());
1127
1110
  }
1128
1111
  // if it's a singleton, return it directly
1129
1112
  if (operands.size() == 0) return rel;
1130
1113
  // fold all operands into one binary expression
1131
- Expression_Obj ex = fold_operands(rel, operands, { Sass_OP::AND });
1132
- state.offset = pstate - state + pstate.offset;
1114
+ ExpressionObj ex = fold_operands(rel, operands, { Sass_OP::AND });
1115
+ state.offset = pstate.position - state.position + pstate.offset;
1133
1116
  ex->pstate(state);
1134
1117
  return ex;
1135
1118
  }
1136
1119
  // EO parse_conjunction
1137
1120
 
1138
1121
  // parse comparison operations
1139
- Expression_Obj Parser::parse_relation()
1122
+ ExpressionObj Parser::parse_relation()
1140
1123
  {
1141
1124
  NESTING_GUARD(nestings);
1142
1125
  advanceToNextToken();
1143
- ParserState state(pstate);
1126
+ SourceSpan state(pstate);
1144
1127
  // parse the left hand side expression
1145
- Expression_Obj lhs = parse_expression();
1146
- std::vector<Expression_Obj> operands;
1147
- std::vector<Operand> operators;
1128
+ ExpressionObj lhs = parse_expression();
1129
+ sass::vector<ExpressionObj> operands;
1130
+ sass::vector<Operand> operators;
1148
1131
  // if it's a singleton, return it (don't wrap it)
1149
1132
  while (peek< alternatives <
1150
1133
  kwd_eq,
@@ -1177,8 +1160,8 @@ namespace Sass {
1177
1160
  // correctly set to zero. After folding we also unwrap
1178
1161
  // single nested items. So we cannot set delay on the
1179
1162
  // returned result here, as we have lost nestings ...
1180
- Expression_Obj ex = fold_operands(lhs, operands, operators);
1181
- state.offset = pstate - state + pstate.offset;
1163
+ ExpressionObj ex = fold_operands(lhs, operands, operators);
1164
+ state.offset = pstate.position - state.position + pstate.offset;
1182
1165
  ex->pstate(state);
1183
1166
  return ex;
1184
1167
  }
@@ -1189,15 +1172,15 @@ namespace Sass {
1189
1172
  // called from parse_for_directive
1190
1173
  // called from parse_media_expression
1191
1174
  // parse addition and subtraction operations
1192
- Expression_Obj Parser::parse_expression()
1175
+ ExpressionObj Parser::parse_expression()
1193
1176
  {
1194
1177
  NESTING_GUARD(nestings);
1195
1178
  advanceToNextToken();
1196
- ParserState state(pstate);
1179
+ SourceSpan state(pstate);
1197
1180
  // parses multiple add and subtract operations
1198
1181
  // NOTE: make sure that identifiers starting with
1199
1182
  // NOTE: dashes do NOT count as subtract operation
1200
- Expression_Obj lhs = parse_operators();
1183
+ ExpressionObj lhs = parse_operators();
1201
1184
  // if it's a singleton, return it (don't wrap it)
1202
1185
  if (!(peek_css< exactly<'+'> >(position) ||
1203
1186
  // condition is a bit mysterious, but some combinations should not be counted as operations
@@ -1206,8 +1189,8 @@ namespace Sass {
1206
1189
  peek< sequence < zero_plus < exactly <'-' > >, identifier > >(position))
1207
1190
  { return lhs; }
1208
1191
 
1209
- std::vector<Expression_Obj> operands;
1210
- std::vector<Operand> operators;
1192
+ sass::vector<ExpressionObj> operands;
1193
+ sass::vector<Operand> operators;
1211
1194
  bool left_ws = peek < css_comments >() != NULL;
1212
1195
  while (
1213
1196
  lex_css< exactly<'+'> >() ||
@@ -1226,22 +1209,22 @@ namespace Sass {
1226
1209
  }
1227
1210
 
1228
1211
  if (operands.size() == 0) return lhs;
1229
- Expression_Obj ex = fold_operands(lhs, operands, operators);
1230
- state.offset = pstate - state + pstate.offset;
1212
+ ExpressionObj ex = fold_operands(lhs, operands, operators);
1213
+ state.offset = pstate.position - state.position + pstate.offset;
1231
1214
  ex->pstate(state);
1232
1215
  return ex;
1233
1216
  }
1234
1217
 
1235
1218
  // parse addition and subtraction operations
1236
- Expression_Obj Parser::parse_operators()
1219
+ ExpressionObj Parser::parse_operators()
1237
1220
  {
1238
1221
  NESTING_GUARD(nestings);
1239
1222
  advanceToNextToken();
1240
- ParserState state(pstate);
1241
- Expression_Obj factor = parse_factor();
1223
+ SourceSpan state(pstate);
1224
+ ExpressionObj factor = parse_factor();
1242
1225
  // if it's a singleton, return it (don't wrap it)
1243
- std::vector<Expression_Obj> operands; // factors
1244
- std::vector<Operand> operators; // ops
1226
+ sass::vector<ExpressionObj> operands; // factors
1227
+ sass::vector<Operand> operators; // ops
1245
1228
  // lex operations to apply to lhs
1246
1229
  const char* left_ws = peek < css_comments >();
1247
1230
  while (lex_css< class_char< static_ops > >()) {
@@ -1256,8 +1239,8 @@ namespace Sass {
1256
1239
  left_ws = peek < css_comments >();
1257
1240
  }
1258
1241
  // operands and operators to binary expression
1259
- Expression_Obj ex = fold_operands(factor, operands, operators);
1260
- state.offset = pstate - state + pstate.offset;
1242
+ ExpressionObj ex = fold_operands(factor, operands, operators);
1243
+ state.offset = pstate.position - state.position + pstate.offset;
1261
1244
  ex->pstate(state);
1262
1245
  return ex;
1263
1246
  }
@@ -1266,13 +1249,13 @@ namespace Sass {
1266
1249
 
1267
1250
  // called from parse_operators
1268
1251
  // called from parse_value_schema
1269
- Expression_Obj Parser::parse_factor()
1252
+ ExpressionObj Parser::parse_factor()
1270
1253
  {
1271
1254
  NESTING_GUARD(nestings);
1272
1255
  lex < css_comments >(false);
1273
1256
  if (lex_css< exactly<'('> >()) {
1274
1257
  // parse_map may return a list
1275
- Expression_Obj value = parse_map();
1258
+ ExpressionObj value = parse_map();
1276
1259
  // lex the expected closing parenthesis
1277
1260
  if (!lex_css< exactly<')'> >()) error("unclosed parenthesis");
1278
1261
  // expression can be evaluated
@@ -1280,7 +1263,7 @@ namespace Sass {
1280
1263
  }
1281
1264
  else if (lex_css< exactly<'['> >()) {
1282
1265
  // explicit bracketed
1283
- Expression_Obj value = parse_bracket_list();
1266
+ ExpressionObj value = parse_bracket_list();
1284
1267
  // lex the expected closing square bracket
1285
1268
  if (!lex_css< exactly<']'> >()) error("unclosed squared bracket");
1286
1269
  return value;
@@ -1342,7 +1325,7 @@ namespace Sass {
1342
1325
  }
1343
1326
  }
1344
1327
 
1345
- bool number_has_zero(const std::string& parsed)
1328
+ bool number_has_zero(const sass::string& parsed)
1346
1329
  {
1347
1330
  size_t L = parsed.length();
1348
1331
  return !( (L > 0 && parsed.substr(0, 1) == ".") ||
@@ -1351,7 +1334,7 @@ namespace Sass {
1351
1334
  (L > 2 && parsed.substr(0, 3) == "-0.") );
1352
1335
  }
1353
1336
 
1354
- Number* Parser::lexed_number(const ParserState& pstate, const std::string& parsed)
1337
+ Number* Parser::lexed_number(const SourceSpan& pstate, const sass::string& parsed)
1355
1338
  {
1356
1339
  Number* nr = SASS_MEMORY_NEW(Number,
1357
1340
  pstate,
@@ -1363,7 +1346,7 @@ namespace Sass {
1363
1346
  return nr;
1364
1347
  }
1365
1348
 
1366
- Number* Parser::lexed_percentage(const ParserState& pstate, const std::string& parsed)
1349
+ Number* Parser::lexed_percentage(const SourceSpan& pstate, const sass::string& parsed)
1367
1350
  {
1368
1351
  Number* nr = SASS_MEMORY_NEW(Number,
1369
1352
  pstate,
@@ -1375,17 +1358,17 @@ namespace Sass {
1375
1358
  return nr;
1376
1359
  }
1377
1360
 
1378
- Number* Parser::lexed_dimension(const ParserState& pstate, const std::string& parsed)
1361
+ Number* Parser::lexed_dimension(const SourceSpan& pstate, const sass::string& parsed)
1379
1362
  {
1380
1363
  size_t L = parsed.length();
1381
1364
  size_t num_pos = parsed.find_first_not_of(" \n\r\t");
1382
- if (num_pos == std::string::npos) num_pos = L;
1365
+ if (num_pos == sass::string::npos) num_pos = L;
1383
1366
  size_t unit_pos = parsed.find_first_not_of("-+0123456789.", num_pos);
1384
1367
  if (parsed[unit_pos] == 'e' && is_number(parsed[unit_pos+1]) ) {
1385
1368
  unit_pos = parsed.find_first_not_of("-+0123456789.", ++ unit_pos);
1386
1369
  }
1387
- if (unit_pos == std::string::npos) unit_pos = L;
1388
- const std::string& num = parsed.substr(num_pos, unit_pos - num_pos);
1370
+ if (unit_pos == sass::string::npos) unit_pos = L;
1371
+ const sass::string& num = parsed.substr(num_pos, unit_pos - num_pos);
1389
1372
  Number* nr = SASS_MEMORY_NEW(Number,
1390
1373
  pstate,
1391
1374
  sass_strtod(num.c_str()),
@@ -1396,18 +1379,18 @@ namespace Sass {
1396
1379
  return nr;
1397
1380
  }
1398
1381
 
1399
- Value* Parser::lexed_hex_color(const ParserState& pstate, const std::string& parsed)
1382
+ Value* Parser::lexed_hex_color(const SourceSpan& pstate, const sass::string& parsed)
1400
1383
  {
1401
1384
  Color_RGBA* color = NULL;
1402
1385
  if (parsed[0] != '#') {
1403
1386
  return SASS_MEMORY_NEW(String_Quoted, pstate, parsed);
1404
1387
  }
1405
1388
  // chop off the '#'
1406
- std::string hext(parsed.substr(1));
1389
+ sass::string hext(parsed.substr(1));
1407
1390
  if (parsed.length() == 4) {
1408
- std::string r(2, parsed[1]);
1409
- std::string g(2, parsed[2]);
1410
- std::string b(2, parsed[3]);
1391
+ sass::string r(2, parsed[1]);
1392
+ sass::string g(2, parsed[2]);
1393
+ sass::string b(2, parsed[3]);
1411
1394
  color = SASS_MEMORY_NEW(Color_RGBA,
1412
1395
  pstate,
1413
1396
  static_cast<double>(strtol(r.c_str(), NULL, 16)),
@@ -1417,10 +1400,10 @@ namespace Sass {
1417
1400
  parsed);
1418
1401
  }
1419
1402
  else if (parsed.length() == 5) {
1420
- std::string r(2, parsed[1]);
1421
- std::string g(2, parsed[2]);
1422
- std::string b(2, parsed[3]);
1423
- std::string a(2, parsed[4]);
1403
+ sass::string r(2, parsed[1]);
1404
+ sass::string g(2, parsed[2]);
1405
+ sass::string b(2, parsed[3]);
1406
+ sass::string a(2, parsed[4]);
1424
1407
  color = SASS_MEMORY_NEW(Color_RGBA,
1425
1408
  pstate,
1426
1409
  static_cast<double>(strtol(r.c_str(), NULL, 16)),
@@ -1430,9 +1413,9 @@ namespace Sass {
1430
1413
  parsed);
1431
1414
  }
1432
1415
  else if (parsed.length() == 7) {
1433
- std::string r(parsed.substr(1,2));
1434
- std::string g(parsed.substr(3,2));
1435
- std::string b(parsed.substr(5,2));
1416
+ sass::string r(parsed.substr(1,2));
1417
+ sass::string g(parsed.substr(3,2));
1418
+ sass::string b(parsed.substr(5,2));
1436
1419
  color = SASS_MEMORY_NEW(Color_RGBA,
1437
1420
  pstate,
1438
1421
  static_cast<double>(strtol(r.c_str(), NULL, 16)),
@@ -1442,10 +1425,10 @@ namespace Sass {
1442
1425
  parsed);
1443
1426
  }
1444
1427
  else if (parsed.length() == 9) {
1445
- std::string r(parsed.substr(1,2));
1446
- std::string g(parsed.substr(3,2));
1447
- std::string b(parsed.substr(5,2));
1448
- std::string a(parsed.substr(7,2));
1428
+ sass::string r(parsed.substr(1,2));
1429
+ sass::string g(parsed.substr(3,2));
1430
+ sass::string b(parsed.substr(5,2));
1431
+ sass::string a(parsed.substr(7,2));
1449
1432
  color = SASS_MEMORY_NEW(Color_RGBA,
1450
1433
  pstate,
1451
1434
  static_cast<double>(strtol(r.c_str(), NULL, 16)),
@@ -1459,7 +1442,7 @@ namespace Sass {
1459
1442
  return color;
1460
1443
  }
1461
1444
 
1462
- Value* Parser::color_or_string(const std::string& lexed) const
1445
+ Value* Parser::color_or_string(const sass::string& lexed) const
1463
1446
  {
1464
1447
  if (auto color = name_to_color(lexed)) {
1465
1448
  auto c = SASS_MEMORY_NEW(Color_RGBA, color);
@@ -1473,7 +1456,7 @@ namespace Sass {
1473
1456
  }
1474
1457
 
1475
1458
  // parse one value for a list
1476
- Expression_Obj Parser::parse_value()
1459
+ ExpressionObj Parser::parse_value()
1477
1460
  {
1478
1461
  lex< css_comments >(false);
1479
1462
  if (lex< ampersand >())
@@ -1560,7 +1543,7 @@ namespace Sass {
1560
1543
  find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);
1561
1544
 
1562
1545
  if (!p) {
1563
- String_Quoted* str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end), 0, false, false, true, css);
1546
+ String_Quoted* str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, sass::string(i, chunk.end), 0, false, false, true, css);
1564
1547
  if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*');
1565
1548
  return str_quoted;
1566
1549
  }
@@ -1573,7 +1556,7 @@ namespace Sass {
1573
1556
  if (p) {
1574
1557
  if (i < p) {
1575
1558
  // accumulate the preceding segment if it's nonempty
1576
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p), css));
1559
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(i, p), css));
1577
1560
  }
1578
1561
  // we need to skip anything inside strings
1579
1562
  // create a new target in parser/prelexer
@@ -1583,7 +1566,9 @@ namespace Sass {
1583
1566
  const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p + 2, chunk.end); // find the closing brace
1584
1567
  if (j) { --j;
1585
1568
  // parse the interpolant and accumulate it
1586
- Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, traces, pstate, source).parse_list();
1569
+ LocalOption<const char*> partEnd(end, j);
1570
+ LocalOption<const char*> partBeg(position, p + 2);
1571
+ ExpressionObj interp_node = parse_list();
1587
1572
  interp_node->is_interpolant(true);
1588
1573
  schema->append(interp_node);
1589
1574
  i = j;
@@ -1595,7 +1580,7 @@ namespace Sass {
1595
1580
  }
1596
1581
  else { // no interpolants left; add the last segment if nonempty
1597
1582
  // check if we need quotes here (was not sure after merge)
1598
- if (i < chunk.end) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, chunk.end), css));
1583
+ if (i < chunk.end) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(i, chunk.end), css));
1599
1584
  break;
1600
1585
  }
1601
1586
  ++ i;
@@ -1607,7 +1592,7 @@ namespace Sass {
1607
1592
  String_Schema_Obj Parser::parse_css_variable_value()
1608
1593
  {
1609
1594
  String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
1610
- std::vector<char> brackets;
1595
+ sass::vector<char> brackets;
1611
1596
  while (true) {
1612
1597
  if (
1613
1598
  (brackets.empty() && lex< css_variable_top_level_value >(false)) ||
@@ -1615,7 +1600,7 @@ namespace Sass {
1615
1600
  ) {
1616
1601
  Token str(lexed);
1617
1602
  schema->append(SASS_MEMORY_NEW(String_Constant, pstate, str));
1618
- } else if (Expression_Obj tok = lex_interpolation()) {
1603
+ } else if (ExpressionObj tok = lex_interpolation()) {
1619
1604
  if (String_Schema* s = Cast<String_Schema>(tok)) {
1620
1605
  if (s->empty()) break;
1621
1606
  schema->concat(s);
@@ -1623,7 +1608,7 @@ namespace Sass {
1623
1608
  schema->append(tok);
1624
1609
  }
1625
1610
  } else if (lex< quoted_string >()) {
1626
- Expression_Obj tok = parse_string();
1611
+ ExpressionObj tok = parse_string();
1627
1612
  if (tok.isNull()) break;
1628
1613
  if (String_Schema* s = Cast<String_Schema>(tok)) {
1629
1614
  if (s->empty()) break;
@@ -1634,18 +1619,18 @@ namespace Sass {
1634
1619
  } else if (lex< alternatives< exactly<'('>, exactly<'['>, exactly<'{'> > >()) {
1635
1620
  const char opening_bracket = *(position - 1);
1636
1621
  brackets.push_back(opening_bracket);
1637
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(1, opening_bracket)));
1622
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(1, opening_bracket)));
1638
1623
  } else if (const char *match = peek< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >()) {
1639
1624
  if (brackets.empty()) break;
1640
1625
  const char closing_bracket = *(match - 1);
1641
1626
  if (brackets.back() != Util::opening_bracket_for(closing_bracket)) {
1642
- std::string message = ": expected \"";
1627
+ sass::string message = ": expected \"";
1643
1628
  message += Util::closing_bracket_for(brackets.back());
1644
1629
  message += "\", was ";
1645
1630
  css_error("Invalid CSS", " after ", message);
1646
1631
  }
1647
1632
  lex< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >();
1648
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(1, closing_bracket)));
1633
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(1, closing_bracket)));
1649
1634
  brackets.pop_back();
1650
1635
  } else {
1651
1636
  break;
@@ -1653,7 +1638,7 @@ namespace Sass {
1653
1638
  }
1654
1639
 
1655
1640
  if (!brackets.empty()) {
1656
- std::string message = ": expected \"";
1641
+ sass::string message = ": expected \"";
1657
1642
  message += Util::closing_bracket_for(brackets.back());
1658
1643
  message += "\", was ";
1659
1644
  css_error("Invalid CSS", " after ", message);
@@ -1663,7 +1648,7 @@ namespace Sass {
1663
1648
  return schema.detach();
1664
1649
  }
1665
1650
 
1666
- Value_Obj Parser::parse_static_value()
1651
+ ValueObj Parser::parse_static_value()
1667
1652
  {
1668
1653
  lex< static_value >();
1669
1654
  Token str(lexed);
@@ -1690,7 +1675,7 @@ namespace Sass {
1690
1675
  // see if there any interpolants
1691
1676
  const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(str.begin, str.end);
1692
1677
  if (!p) {
1693
- return SASS_MEMORY_NEW(String_Quoted, pstate, std::string(str.begin, str.end));
1678
+ return SASS_MEMORY_NEW(String_Quoted, pstate, sass::string(str.begin, str.end));
1694
1679
  }
1695
1680
 
1696
1681
  String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
@@ -1698,7 +1683,7 @@ namespace Sass {
1698
1683
  p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, str.end);
1699
1684
  if (p) {
1700
1685
  if (i < p) {
1701
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p))); // accumulate the preceding segment if it's nonempty
1686
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(i, p))); // accumulate the preceding segment if it's nonempty
1702
1687
  }
1703
1688
  if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p+2;
1704
1689
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
@@ -1706,7 +1691,9 @@ namespace Sass {
1706
1691
  const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p+2, str.end); // find the closing brace
1707
1692
  if (j) {
1708
1693
  // parse the interpolant and accumulate it
1709
- Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, traces, pstate, source).parse_list();
1694
+ LocalOption<const char*> partEnd(end, j);
1695
+ LocalOption<const char*> partBeg(position, p + 2);
1696
+ ExpressionObj interp_node = parse_list();
1710
1697
  interp_node->is_interpolant(true);
1711
1698
  schema->append(interp_node);
1712
1699
  i = j;
@@ -1718,7 +1705,7 @@ namespace Sass {
1718
1705
  }
1719
1706
  else { // no interpolants left; add the last segment if nonempty
1720
1707
  if (i < str.end) {
1721
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, str.end)));
1708
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(i, str.end)));
1722
1709
  }
1723
1710
  break;
1724
1711
  }
@@ -1739,7 +1726,7 @@ namespace Sass {
1739
1726
  kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1740
1727
  if (peek< variable >()) kwd_arg->append(parse_list());
1741
1728
  else if (lex< number >()) {
1742
- std::string parsed(lexed);
1729
+ sass::string parsed(lexed);
1743
1730
  Util::normalize_decimals(parsed);
1744
1731
  kwd_arg->append(lexed_number(parsed));
1745
1732
  }
@@ -1779,7 +1766,7 @@ namespace Sass {
1779
1766
  if (peek< exactly< rbrace > >()) {
1780
1767
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1781
1768
  }
1782
- Expression_Obj ex;
1769
+ ExpressionObj ex;
1783
1770
  if (lex< re_static_expression >()) {
1784
1771
  ex = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1785
1772
  } else {
@@ -1815,7 +1802,7 @@ namespace Sass {
1815
1802
  }
1816
1803
  // lex (normalized) variable
1817
1804
  else if (lex< variable >()) {
1818
- std::string name(Util::normalize_underscores(lexed));
1805
+ sass::string name(Util::normalize_underscores(lexed));
1819
1806
  schema->append(SASS_MEMORY_NEW(Variable, pstate, name));
1820
1807
  }
1821
1808
  // lex percentage value
@@ -1847,7 +1834,7 @@ namespace Sass {
1847
1834
  ++num_items;
1848
1835
  }
1849
1836
  if (position != stop) {
1850
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(position, stop)));
1837
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(position, stop)));
1851
1838
  position = stop;
1852
1839
  }
1853
1840
  end = ee;
@@ -1863,7 +1850,7 @@ namespace Sass {
1863
1850
  // see if there any interpolants
1864
1851
  const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(id.begin, id.end);
1865
1852
  if (!p) {
1866
- return SASS_MEMORY_NEW(String_Constant, pstate, std::string(id.begin, id.end));
1853
+ return SASS_MEMORY_NEW(String_Constant, pstate, sass::string(id.begin, id.end));
1867
1854
  }
1868
1855
 
1869
1856
  String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
@@ -1884,7 +1871,9 @@ namespace Sass {
1884
1871
  const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p+2, id.end); // find the closing brace
1885
1872
  if (j) {
1886
1873
  // parse the interpolant and accumulate it
1887
- Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, traces, pstate, source).parse_list(DELAYED);
1874
+ LocalOption<const char*> partEnd(end, j);
1875
+ LocalOption<const char*> partBeg(position, p + 2);
1876
+ ExpressionObj interp_node = parse_list(DELAYED);
1888
1877
  interp_node->is_interpolant(true);
1889
1878
  schema->append(interp_node);
1890
1879
  // schema->has_interpolants(true);
@@ -1911,10 +1900,10 @@ namespace Sass {
1911
1900
  Function_Call_Obj Parser::parse_calc_function()
1912
1901
  {
1913
1902
  lex< identifier >();
1914
- std::string name(lexed);
1915
- ParserState call_pos = pstate;
1903
+ sass::string name(lexed);
1904
+ SourceSpan call_pos = pstate;
1916
1905
  lex< exactly<'('> >();
1917
- ParserState arg_pos = pstate;
1906
+ SourceSpan arg_pos = pstate;
1918
1907
  const char* arg_beg = position;
1919
1908
  parse_list();
1920
1909
  const char* arg_end = position;
@@ -1931,20 +1920,20 @@ namespace Sass {
1931
1920
 
1932
1921
  String_Obj Parser::parse_url_function_string()
1933
1922
  {
1934
- std::string prefix("");
1923
+ sass::string prefix("");
1935
1924
  if (lex< uri_prefix >()) {
1936
- prefix = std::string(lexed);
1925
+ prefix = sass::string(lexed);
1937
1926
  }
1938
1927
 
1939
1928
  lex < optional_spaces >();
1940
1929
  String_Obj url_string = parse_url_function_argument();
1941
1930
 
1942
- std::string suffix("");
1931
+ sass::string suffix("");
1943
1932
  if (lex< real_uri_suffix >()) {
1944
- suffix = std::string(lexed);
1933
+ suffix = sass::string(lexed);
1945
1934
  }
1946
1935
 
1947
- std::string uri("");
1936
+ sass::string uri("");
1948
1937
  if (url_string) {
1949
1938
  uri = url_string->to_string({ NESTED, 5 });
1950
1939
  }
@@ -1956,7 +1945,7 @@ namespace Sass {
1956
1945
  res->append(SASS_MEMORY_NEW(String_Constant, pstate, suffix));
1957
1946
  return res;
1958
1947
  } else {
1959
- std::string res = prefix + uri + suffix;
1948
+ sass::string res = prefix + uri + suffix;
1960
1949
  return SASS_MEMORY_NEW(String_Constant, pstate, res);
1961
1950
  }
1962
1951
  }
@@ -1965,7 +1954,7 @@ namespace Sass {
1965
1954
  {
1966
1955
  const char* p = position;
1967
1956
 
1968
- std::string uri("");
1957
+ sass::string uri("");
1969
1958
  if (lex< real_uri_value >(false)) {
1970
1959
  uri = lexed.to_string();
1971
1960
  }
@@ -1981,7 +1970,7 @@ namespace Sass {
1981
1970
  return parse_interpolated_chunk(Token(p, position));
1982
1971
  }
1983
1972
  else if (uri != "") {
1984
- std::string res = Util::rtrim(uri);
1973
+ sass::string res = Util::rtrim(uri);
1985
1974
  return SASS_MEMORY_NEW(String_Constant, pstate, res);
1986
1975
  }
1987
1976
 
@@ -1991,12 +1980,12 @@ namespace Sass {
1991
1980
  Function_Call_Obj Parser::parse_function_call()
1992
1981
  {
1993
1982
  lex< identifier >();
1994
- std::string name(lexed);
1983
+ sass::string name(lexed);
1995
1984
 
1996
1985
  if (Util::normalize_underscores(name) == "content-exists" && stack.back() != Scope::Mixin)
1997
1986
  { error("Cannot call content-exists() except within a mixin."); }
1998
1987
 
1999
- ParserState call_pos = pstate;
1988
+ SourceSpan call_pos = pstate;
2000
1989
  Arguments_Obj args = parse_arguments();
2001
1990
  return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);
2002
1991
  }
@@ -2004,7 +1993,7 @@ namespace Sass {
2004
1993
  Function_Call_Obj Parser::parse_function_call_schema()
2005
1994
  {
2006
1995
  String_Obj name = parse_identifier_schema();
2007
- ParserState source_position_of_call = pstate;
1996
+ SourceSpan source_position_of_call = pstate;
2008
1997
  Arguments_Obj args = parse_arguments();
2009
1998
 
2010
1999
  return SASS_MEMORY_NEW(Function_Call, source_position_of_call, name, args);
@@ -2012,7 +2001,7 @@ namespace Sass {
2012
2001
 
2013
2002
  Content_Obj Parser::parse_content_directive()
2014
2003
  {
2015
- ParserState call_pos = pstate;
2004
+ SourceSpan call_pos = pstate;
2016
2005
  Arguments_Obj args = parse_arguments();
2017
2006
 
2018
2007
  return SASS_MEMORY_NEW(Content, call_pos, args);
@@ -2021,9 +2010,9 @@ namespace Sass {
2021
2010
  If_Obj Parser::parse_if_directive(bool else_if)
2022
2011
  {
2023
2012
  stack.push_back(Scope::Control);
2024
- ParserState if_source_position = pstate;
2013
+ SourceSpan if_source_position = pstate;
2025
2014
  bool root = block_stack.back()->is_root();
2026
- Expression_Obj predicate = parse_list();
2015
+ ExpressionObj predicate = parse_list();
2027
2016
  Block_Obj block = parse_block(root);
2028
2017
  Block_Obj alternative;
2029
2018
 
@@ -2040,23 +2029,23 @@ namespace Sass {
2040
2029
  return SASS_MEMORY_NEW(If, if_source_position, predicate, block, alternative);
2041
2030
  }
2042
2031
 
2043
- For_Obj Parser::parse_for_directive()
2032
+ ForRuleObj Parser::parse_for_directive()
2044
2033
  {
2045
2034
  stack.push_back(Scope::Control);
2046
- ParserState for_source_position = pstate;
2035
+ SourceSpan for_source_position = pstate;
2047
2036
  bool root = block_stack.back()->is_root();
2048
2037
  lex_variable();
2049
- std::string var(Util::normalize_underscores(lexed));
2038
+ sass::string var(Util::normalize_underscores(lexed));
2050
2039
  if (!lex< kwd_from >()) error("expected 'from' keyword in @for directive");
2051
- Expression_Obj lower_bound = parse_expression();
2040
+ ExpressionObj lower_bound = parse_expression();
2052
2041
  bool inclusive = false;
2053
2042
  if (lex< kwd_through >()) inclusive = true;
2054
2043
  else if (lex< kwd_to >()) inclusive = false;
2055
2044
  else error("expected 'through' or 'to' keyword in @for directive");
2056
- Expression_Obj upper_bound = parse_expression();
2045
+ ExpressionObj upper_bound = parse_expression();
2057
2046
  Block_Obj body = parse_block(root);
2058
2047
  stack.pop_back();
2059
- return SASS_MEMORY_NEW(For, for_source_position, var, lower_bound, upper_bound, body, inclusive);
2048
+ return SASS_MEMORY_NEW(ForRule, for_source_position, var, lower_bound, upper_bound, body, inclusive);
2060
2049
  }
2061
2050
 
2062
2051
  // helper to parse a var token
@@ -2072,7 +2061,7 @@ namespace Sass {
2072
2061
  css_error("Invalid CSS", " after ", ": expected identifier, was ");
2073
2062
  }
2074
2063
  // return object
2075
- return token;
2064
+ return lexed;
2076
2065
  }
2077
2066
  // helper to parse identifier
2078
2067
  Token Parser::lex_identifier()
@@ -2082,15 +2071,15 @@ namespace Sass {
2082
2071
  css_error("Invalid CSS", " after ", ": expected identifier, was ");
2083
2072
  }
2084
2073
  // return object
2085
- return token;
2074
+ return lexed;
2086
2075
  }
2087
2076
 
2088
- Each_Obj Parser::parse_each_directive()
2077
+ EachRuleObj Parser::parse_each_directive()
2089
2078
  {
2090
2079
  stack.push_back(Scope::Control);
2091
- ParserState each_source_position = pstate;
2080
+ SourceSpan each_source_position = pstate;
2092
2081
  bool root = block_stack.back()->is_root();
2093
- std::vector<std::string> vars;
2082
+ sass::vector<sass::string> vars;
2094
2083
  lex_variable();
2095
2084
  vars.push_back(Util::normalize_underscores(lexed));
2096
2085
  while (lex< exactly<','> >()) {
@@ -2098,21 +2087,21 @@ namespace Sass {
2098
2087
  vars.push_back(Util::normalize_underscores(lexed));
2099
2088
  }
2100
2089
  if (!lex< kwd_in >()) error("expected 'in' keyword in @each directive");
2101
- Expression_Obj list = parse_list();
2090
+ ExpressionObj list = parse_list();
2102
2091
  Block_Obj body = parse_block(root);
2103
2092
  stack.pop_back();
2104
- return SASS_MEMORY_NEW(Each, each_source_position, vars, list, body);
2093
+ return SASS_MEMORY_NEW(EachRule, each_source_position, vars, list, body);
2105
2094
  }
2106
2095
 
2107
2096
  // called after parsing `kwd_while_directive`
2108
- While_Obj Parser::parse_while_directive()
2097
+ WhileRuleObj Parser::parse_while_directive()
2109
2098
  {
2110
2099
  stack.push_back(Scope::Control);
2111
2100
  bool root = block_stack.back()->is_root();
2112
2101
  // create the initial while call object
2113
- While_Obj call = SASS_MEMORY_NEW(While, pstate, {}, {});
2102
+ WhileRuleObj call = SASS_MEMORY_NEW(WhileRule, pstate, ExpressionObj{}, Block_Obj{});
2114
2103
  // parse mandatory predicate
2115
- Expression_Obj predicate = parse_list();
2104
+ ExpressionObj predicate = parse_list();
2116
2105
  List_Obj l = Cast<List>(predicate);
2117
2106
  if (!predicate || (l && !l->length())) {
2118
2107
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ", false);
@@ -2127,9 +2116,9 @@ namespace Sass {
2127
2116
  }
2128
2117
 
2129
2118
 
2130
- std::vector<CssMediaQuery_Obj> Parser::parseCssMediaQueries()
2119
+ sass::vector<CssMediaQuery_Obj> Parser::parseCssMediaQueries()
2131
2120
  {
2132
- std::vector<CssMediaQuery_Obj> result;
2121
+ sass::vector<CssMediaQuery_Obj> result;
2133
2122
  do {
2134
2123
  if (auto query = parseCssMediaQuery()) {
2135
2124
  result.push_back(query);
@@ -2138,12 +2127,12 @@ namespace Sass {
2138
2127
  return result;
2139
2128
  }
2140
2129
 
2141
- std::string Parser::parseIdentifier()
2130
+ sass::string Parser::parseIdentifier()
2142
2131
  {
2143
2132
  if (lex < identifier >(false)) {
2144
- return std::string(lexed);
2133
+ return sass::string(lexed);
2145
2134
  }
2146
- return std::string();
2135
+ return sass::string();
2147
2136
  }
2148
2137
 
2149
2138
  CssMediaQuery_Obj Parser::parseCssMediaQuery()
@@ -2154,14 +2143,14 @@ namespace Sass {
2154
2143
  // Check if any tokens are to parse
2155
2144
  if (!peek_css<exactly<'('>>()) {
2156
2145
 
2157
- std::string token1(parseIdentifier());
2146
+ sass::string token1(parseIdentifier());
2158
2147
  lex<css_comments>(false);
2159
2148
 
2160
2149
  if (token1.empty()) {
2161
2150
  return {};
2162
2151
  }
2163
2152
 
2164
- std::string token2(parseIdentifier());
2153
+ sass::string token2(parseIdentifier());
2165
2154
  lex<css_comments>(false);
2166
2155
 
2167
2156
  if (Util::equalsLiteral("and", token2)) {
@@ -2187,7 +2176,7 @@ namespace Sass {
2187
2176
 
2188
2177
  }
2189
2178
 
2190
- std::vector<std::string> queries;
2179
+ sass::vector<sass::string> queries;
2191
2180
 
2192
2181
  do {
2193
2182
  lex<css_comments>(false);
@@ -2195,7 +2184,7 @@ namespace Sass {
2195
2184
  if (lex<exactly<'('>>()) {
2196
2185
  // In dart sass parser returns a pure string
2197
2186
  if (lex < skip_over_scopes < exactly < '(' >, exactly < ')' > > >()) {
2198
- std::string decl("(" + std::string(lexed));
2187
+ sass::string decl("(" + sass::string(lexed));
2199
2188
  queries.push_back(decl);
2200
2189
  }
2201
2190
  // Should be: parseDeclarationValue;
@@ -2247,15 +2236,17 @@ namespace Sass {
2247
2236
  if (lex < kwd_not >()) { media_query->is_negated(true); lex < css_comments >(false); }
2248
2237
  else if (lex < kwd_only >()) { media_query->is_restricted(true); lex < css_comments >(false); }
2249
2238
 
2250
- if (lex < identifier_schema >()) media_query->media_type(parse_identifier_schema());
2251
- else if (lex < identifier >()) media_query->media_type(parse_interpolated_chunk(lexed));
2239
+ if (lex < identifier_schema >()) media_query->media_type(parse_identifier_schema());
2240
+ else if (lex < identifier >()) media_query->media_type(parse_interpolated_chunk(lexed));
2252
2241
  else media_query->append(parse_media_expression());
2253
2242
 
2254
2243
  while (lex_css < kwd_and >()) media_query->append(parse_media_expression());
2255
2244
  if (lex < identifier_schema >()) {
2256
- String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
2257
- schema->append(media_query->media_type());
2258
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
2245
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
2246
+ if (media_query->media_type()) {
2247
+ schema->append(media_query->media_type());
2248
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
2249
+ }
2259
2250
  schema->append(parse_identifier_schema());
2260
2251
  media_query->media_type(schema);
2261
2252
  }
@@ -2266,21 +2257,21 @@ namespace Sass {
2266
2257
  return media_query;
2267
2258
  }
2268
2259
 
2269
- Media_Query_Expression_Obj Parser::parse_media_expression()
2260
+ Media_Query_ExpressionObj Parser::parse_media_expression()
2270
2261
  {
2271
2262
  if (lex < identifier_schema >()) {
2272
2263
  String_Obj ss = parse_identifier_schema();
2273
- return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss, {}, true);
2264
+ return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss, ExpressionObj{}, true);
2274
2265
  }
2275
2266
  if (!lex_css< exactly<'('> >()) {
2276
2267
  error("media query expression must begin with '('");
2277
2268
  }
2278
- Expression_Obj feature;
2269
+ ExpressionObj feature;
2279
2270
  if (peek_css< exactly<')'> >()) {
2280
2271
  error("media feature required in media query expression");
2281
2272
  }
2282
2273
  feature = parse_expression();
2283
- Expression_Obj expression;
2274
+ ExpressionObj expression;
2284
2275
  if (lex_css< exactly<':'> >()) {
2285
2276
  expression = parse_list(DELAYED);
2286
2277
  }
@@ -2292,11 +2283,11 @@ namespace Sass {
2292
2283
 
2293
2284
  // lexed after `kwd_supports_directive`
2294
2285
  // these are very similar to media blocks
2295
- Supports_Block_Obj Parser::parse_supports_directive()
2286
+ SupportsRuleObj Parser::parse_supports_directive()
2296
2287
  {
2297
- Supports_Condition_Obj cond = parse_supports_condition(/*top_level=*/true);
2288
+ SupportsConditionObj cond = parse_supports_condition(/*top_level=*/true);
2298
2289
  // create the ast node object for the support queries
2299
- Supports_Block_Obj query = SASS_MEMORY_NEW(Supports_Block, pstate, cond);
2290
+ SupportsRuleObj query = SASS_MEMORY_NEW(SupportsRule, pstate, cond);
2300
2291
  // additional block is mandatory
2301
2292
  // parse inner block
2302
2293
  query->block(parse_block());
@@ -2306,43 +2297,43 @@ namespace Sass {
2306
2297
 
2307
2298
  // parse one query operation
2308
2299
  // may encounter nested queries
2309
- Supports_Condition_Obj Parser::parse_supports_condition(bool top_level)
2300
+ SupportsConditionObj Parser::parse_supports_condition(bool top_level)
2310
2301
  {
2311
2302
  lex < css_whitespace >();
2312
- Supports_Condition_Obj cond;
2303
+ SupportsConditionObj cond;
2313
2304
  if ((cond = parse_supports_negation())) return cond;
2314
2305
  if ((cond = parse_supports_operator(top_level))) return cond;
2315
2306
  if ((cond = parse_supports_interpolation())) return cond;
2316
2307
  return cond;
2317
2308
  }
2318
2309
 
2319
- Supports_Condition_Obj Parser::parse_supports_negation()
2310
+ SupportsConditionObj Parser::parse_supports_negation()
2320
2311
  {
2321
2312
  if (!lex < kwd_not >()) return {};
2322
- Supports_Condition_Obj cond = parse_supports_condition_in_parens(/*parens_required=*/true);
2323
- return SASS_MEMORY_NEW(Supports_Negation, pstate, cond);
2313
+ SupportsConditionObj cond = parse_supports_condition_in_parens(/*parens_required=*/true);
2314
+ return SASS_MEMORY_NEW(SupportsNegation, pstate, cond);
2324
2315
  }
2325
2316
 
2326
- Supports_Condition_Obj Parser::parse_supports_operator(bool top_level)
2317
+ SupportsConditionObj Parser::parse_supports_operator(bool top_level)
2327
2318
  {
2328
- Supports_Condition_Obj cond = parse_supports_condition_in_parens(/*parens_required=*/top_level);
2319
+ SupportsConditionObj cond = parse_supports_condition_in_parens(/*parens_required=*/top_level);
2329
2320
  if (cond.isNull()) return {};
2330
2321
 
2331
2322
  while (true) {
2332
- Supports_Operator::Operand op = Supports_Operator::OR;
2333
- if (lex < kwd_and >()) { op = Supports_Operator::AND; }
2323
+ SupportsOperation::Operand op = SupportsOperation::OR;
2324
+ if (lex < kwd_and >()) { op = SupportsOperation::AND; }
2334
2325
  else if(!lex < kwd_or >()) { break; }
2335
2326
 
2336
2327
  lex < css_whitespace >();
2337
- Supports_Condition_Obj right = parse_supports_condition_in_parens(/*parens_required=*/true);
2328
+ SupportsConditionObj right = parse_supports_condition_in_parens(/*parens_required=*/true);
2338
2329
 
2339
- // Supports_Condition* cc = SASS_MEMORY_NEW(Supports_Condition, *static_cast<Supports_Condition*>(cond));
2340
- cond = SASS_MEMORY_NEW(Supports_Operator, pstate, cond, right, op);
2330
+ // SupportsCondition* cc = SASS_MEMORY_NEW(SupportsCondition, *static_cast<SupportsCondition*>(cond));
2331
+ cond = SASS_MEMORY_NEW(SupportsOperation, pstate, cond, right, op);
2341
2332
  }
2342
2333
  return cond;
2343
2334
  }
2344
2335
 
2345
- Supports_Condition_Obj Parser::parse_supports_interpolation()
2336
+ SupportsConditionObj Parser::parse_supports_interpolation()
2346
2337
  {
2347
2338
  if (!lex < interpolant >()) return {};
2348
2339
 
@@ -2354,17 +2345,17 @@ namespace Sass {
2354
2345
 
2355
2346
  // TODO: This needs some major work. Although feature conditions
2356
2347
  // look like declarations their semantics differ significantly
2357
- Supports_Condition_Obj Parser::parse_supports_declaration()
2348
+ SupportsConditionObj Parser::parse_supports_declaration()
2358
2349
  {
2359
- Supports_Condition* cond;
2350
+ SupportsCondition* cond;
2360
2351
  // parse something declaration like
2361
- Expression_Obj feature = parse_expression();
2362
- Expression_Obj expression;
2352
+ ExpressionObj feature = parse_expression();
2353
+ ExpressionObj expression;
2363
2354
  if (lex_css< exactly<':'> >()) {
2364
2355
  expression = parse_list(DELAYED);
2365
2356
  }
2366
2357
  if (!feature || !expression) error("@supports condition expected declaration");
2367
- cond = SASS_MEMORY_NEW(Supports_Declaration,
2358
+ cond = SASS_MEMORY_NEW(SupportsDeclaration,
2368
2359
  feature->pstate(),
2369
2360
  feature,
2370
2361
  expression);
@@ -2372,9 +2363,9 @@ namespace Sass {
2372
2363
  return cond;
2373
2364
  }
2374
2365
 
2375
- Supports_Condition_Obj Parser::parse_supports_condition_in_parens(bool parens_required)
2366
+ SupportsConditionObj Parser::parse_supports_condition_in_parens(bool parens_required)
2376
2367
  {
2377
- Supports_Condition_Obj interp = parse_supports_interpolation();
2368
+ SupportsConditionObj interp = parse_supports_interpolation();
2378
2369
  if (interp != nullptr) return interp;
2379
2370
 
2380
2371
  if (!lex < exactly <'('> >()) {
@@ -2386,7 +2377,7 @@ namespace Sass {
2386
2377
  }
2387
2378
  lex < css_whitespace >();
2388
2379
 
2389
- Supports_Condition_Obj cond = parse_supports_condition(/*top_level=*/false);
2380
+ SupportsConditionObj cond = parse_supports_condition(/*top_level=*/false);
2390
2381
  if (cond.isNull()) cond = parse_supports_declaration();
2391
2382
  if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration");
2392
2383
 
@@ -2394,10 +2385,10 @@ namespace Sass {
2394
2385
  return cond;
2395
2386
  }
2396
2387
 
2397
- At_Root_Block_Obj Parser::parse_at_root_block()
2388
+ AtRootRuleObj Parser::parse_at_root_block()
2398
2389
  {
2399
2390
  stack.push_back(Scope::AtRoot);
2400
- ParserState at_source_position = pstate;
2391
+ SourceSpan at_source_position = pstate;
2401
2392
  Block_Obj body;
2402
2393
  At_Root_Query_Obj expr;
2403
2394
  Lookahead lookahead_result;
@@ -2409,11 +2400,11 @@ namespace Sass {
2409
2400
  body = parse_block(true);
2410
2401
  }
2411
2402
  else if ((lookahead_result = lookahead_for_selector(position)).found) {
2412
- Ruleset_Obj r = parse_ruleset(lookahead_result);
2403
+ StyleRuleObj r = parse_ruleset(lookahead_result);
2413
2404
  body = SASS_MEMORY_NEW(Block, r->pstate(), 1, true);
2414
2405
  body->append(r);
2415
2406
  }
2416
- At_Root_Block_Obj at_root = SASS_MEMORY_NEW(At_Root_Block, at_source_position, body);
2407
+ AtRootRuleObj at_root = SASS_MEMORY_NEW(AtRootRule, at_source_position, body);
2417
2408
  if (!expr.isNull()) at_root->expression(expr);
2418
2409
  stack.pop_back();
2419
2410
  return at_root;
@@ -2427,9 +2418,9 @@ namespace Sass {
2427
2418
  css_error("Invalid CSS", " after ", ": expected \"with\" or \"without\", was ");
2428
2419
  }
2429
2420
 
2430
- Expression_Obj feature = parse_list();
2421
+ ExpressionObj feature = parse_list();
2431
2422
  if (!lex_css< exactly<':'> >()) error("style declaration must contain a value");
2432
- Expression_Obj expression = parse_list();
2423
+ ExpressionObj expression = parse_list();
2433
2424
  List_Obj value = SASS_MEMORY_NEW(List, feature->pstate(), 1);
2434
2425
 
2435
2426
  if (expression->concrete_type() == Expression::LIST) {
@@ -2445,9 +2436,9 @@ namespace Sass {
2445
2436
  return cond;
2446
2437
  }
2447
2438
 
2448
- Directive_Obj Parser::parse_directive()
2439
+ AtRuleObj Parser::parse_directive()
2449
2440
  {
2450
- Directive_Obj directive = SASS_MEMORY_NEW(Directive, pstate, lexed);
2441
+ AtRuleObj directive = SASS_MEMORY_NEW(AtRule, pstate, lexed);
2451
2442
  String_Schema_Obj val = parse_almost_any_value();
2452
2443
  // strip left and right if they are of type string
2453
2444
  directive->value(val);
@@ -2457,7 +2448,7 @@ namespace Sass {
2457
2448
  return directive;
2458
2449
  }
2459
2450
 
2460
- Expression_Obj Parser::lex_interpolation()
2451
+ ExpressionObj Parser::lex_interpolation()
2461
2452
  {
2462
2453
  if (lex < interpolant >(true) != NULL) {
2463
2454
  return parse_interpolated_chunk(lexed, true);
@@ -2465,21 +2456,21 @@ namespace Sass {
2465
2456
  return {};
2466
2457
  }
2467
2458
 
2468
- Expression_Obj Parser::lex_interp_uri()
2459
+ ExpressionObj Parser::lex_interp_uri()
2469
2460
  {
2470
2461
  // create a string schema by lexing optional interpolations
2471
2462
  return lex_interp< re_string_uri_open, re_string_uri_close >();
2472
2463
  }
2473
2464
 
2474
- Expression_Obj Parser::lex_interp_string()
2465
+ ExpressionObj Parser::lex_interp_string()
2475
2466
  {
2476
- Expression_Obj rv;
2467
+ ExpressionObj rv;
2477
2468
  if ((rv = lex_interp< re_string_double_open, re_string_double_close >())) return rv;
2478
2469
  if ((rv = lex_interp< re_string_single_open, re_string_single_close >())) return rv;
2479
2470
  return rv;
2480
2471
  }
2481
2472
 
2482
- Expression_Obj Parser::lex_almost_any_value_chars()
2473
+ ExpressionObj Parser::lex_almost_any_value_chars()
2483
2474
  {
2484
2475
  const char* match =
2485
2476
  lex <
@@ -2532,9 +2523,9 @@ namespace Sass {
2532
2523
  return {};
2533
2524
  }
2534
2525
 
2535
- Expression_Obj Parser::lex_almost_any_value_token()
2526
+ ExpressionObj Parser::lex_almost_any_value_token()
2536
2527
  {
2537
- Expression_Obj rv;
2528
+ ExpressionObj rv;
2538
2529
  if (*position == 0) return {};
2539
2530
  if ((rv = lex_almost_any_value_chars())) return rv;
2540
2531
  // if ((rv = lex_block_comment())) return rv;
@@ -2553,7 +2544,7 @@ namespace Sass {
2553
2544
  String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
2554
2545
  if (*position == 0) return {};
2555
2546
  lex < spaces >(false);
2556
- Expression_Obj token = lex_almost_any_value_token();
2547
+ ExpressionObj token = lex_almost_any_value_token();
2557
2548
  if (!token) return {};
2558
2549
  schema->append(token);
2559
2550
  if (*position == 0) {
@@ -2572,7 +2563,7 @@ namespace Sass {
2572
2563
  return schema.detach();
2573
2564
  }
2574
2565
 
2575
- Warning_Obj Parser::parse_warning()
2566
+ WarningRuleObj Parser::parse_warning()
2576
2567
  {
2577
2568
  if (stack.back() != Scope::Root &&
2578
2569
  stack.back() != Scope::Function &&
@@ -2581,10 +2572,10 @@ namespace Sass {
2581
2572
  stack.back() != Scope::Rules) {
2582
2573
  error("Illegal nesting: Only properties may be nested beneath properties.");
2583
2574
  }
2584
- return SASS_MEMORY_NEW(Warning, pstate, parse_list(DELAYED));
2575
+ return SASS_MEMORY_NEW(WarningRule, pstate, parse_list(DELAYED));
2585
2576
  }
2586
2577
 
2587
- Error_Obj Parser::parse_error()
2578
+ ErrorRuleObj Parser::parse_error()
2588
2579
  {
2589
2580
  if (stack.back() != Scope::Root &&
2590
2581
  stack.back() != Scope::Function &&
@@ -2593,10 +2584,10 @@ namespace Sass {
2593
2584
  stack.back() != Scope::Rules) {
2594
2585
  error("Illegal nesting: Only properties may be nested beneath properties.");
2595
2586
  }
2596
- return SASS_MEMORY_NEW(Error, pstate, parse_list(DELAYED));
2587
+ return SASS_MEMORY_NEW(ErrorRule, pstate, parse_list(DELAYED));
2597
2588
  }
2598
2589
 
2599
- Debug_Obj Parser::parse_debug()
2590
+ DebugRuleObj Parser::parse_debug()
2600
2591
  {
2601
2592
  if (stack.back() != Scope::Root &&
2602
2593
  stack.back() != Scope::Function &&
@@ -2605,7 +2596,7 @@ namespace Sass {
2605
2596
  stack.back() != Scope::Rules) {
2606
2597
  error("Illegal nesting: Only properties may be nested beneath properties.");
2607
2598
  }
2608
- return SASS_MEMORY_NEW(Debug, pstate, parse_list(DELAYED));
2599
+ return SASS_MEMORY_NEW(DebugRule, pstate, parse_list(DELAYED));
2609
2600
  }
2610
2601
 
2611
2602
  Return_Obj Parser::parse_return_directive()
@@ -2760,53 +2751,53 @@ namespace Sass {
2760
2751
  void Parser::read_bom()
2761
2752
  {
2762
2753
  size_t skip = 0;
2763
- std::string encoding;
2754
+ sass::string encoding;
2764
2755
  bool utf_8 = false;
2765
- switch ((unsigned char) source[0]) {
2756
+ switch ((unsigned char)position[0]) {
2766
2757
  case 0xEF:
2767
- skip = check_bom_chars(source, end, utf_8_bom, 3);
2758
+ skip = check_bom_chars(position, end, utf_8_bom, 3);
2768
2759
  encoding = "UTF-8";
2769
2760
  utf_8 = true;
2770
2761
  break;
2771
2762
  case 0xFE:
2772
- skip = check_bom_chars(source, end, utf_16_bom_be, 2);
2763
+ skip = check_bom_chars(position, end, utf_16_bom_be, 2);
2773
2764
  encoding = "UTF-16 (big endian)";
2774
2765
  break;
2775
2766
  case 0xFF:
2776
- skip = check_bom_chars(source, end, utf_16_bom_le, 2);
2777
- skip += (skip ? check_bom_chars(source, end, utf_32_bom_le, 4) : 0);
2767
+ skip = check_bom_chars(position, end, utf_16_bom_le, 2);
2768
+ skip += (skip ? check_bom_chars(position, end, utf_32_bom_le, 4) : 0);
2778
2769
  encoding = (skip == 2 ? "UTF-16 (little endian)" : "UTF-32 (little endian)");
2779
2770
  break;
2780
2771
  case 0x00:
2781
- skip = check_bom_chars(source, end, utf_32_bom_be, 4);
2772
+ skip = check_bom_chars(position, end, utf_32_bom_be, 4);
2782
2773
  encoding = "UTF-32 (big endian)";
2783
2774
  break;
2784
2775
  case 0x2B:
2785
- skip = check_bom_chars(source, end, utf_7_bom_1, 4)
2786
- | check_bom_chars(source, end, utf_7_bom_2, 4)
2787
- | check_bom_chars(source, end, utf_7_bom_3, 4)
2788
- | check_bom_chars(source, end, utf_7_bom_4, 4)
2789
- | check_bom_chars(source, end, utf_7_bom_5, 5);
2776
+ skip = check_bom_chars(position, end, utf_7_bom_1, 4)
2777
+ | check_bom_chars(position, end, utf_7_bom_2, 4)
2778
+ | check_bom_chars(position, end, utf_7_bom_3, 4)
2779
+ | check_bom_chars(position, end, utf_7_bom_4, 4)
2780
+ | check_bom_chars(position, end, utf_7_bom_5, 5);
2790
2781
  encoding = "UTF-7";
2791
2782
  break;
2792
2783
  case 0xF7:
2793
- skip = check_bom_chars(source, end, utf_1_bom, 3);
2784
+ skip = check_bom_chars(position, end, utf_1_bom, 3);
2794
2785
  encoding = "UTF-1";
2795
2786
  break;
2796
2787
  case 0xDD:
2797
- skip = check_bom_chars(source, end, utf_ebcdic_bom, 4);
2788
+ skip = check_bom_chars(position, end, utf_ebcdic_bom, 4);
2798
2789
  encoding = "UTF-EBCDIC";
2799
2790
  break;
2800
2791
  case 0x0E:
2801
- skip = check_bom_chars(source, end, scsu_bom, 3);
2792
+ skip = check_bom_chars(position, end, scsu_bom, 3);
2802
2793
  encoding = "SCSU";
2803
2794
  break;
2804
2795
  case 0xFB:
2805
- skip = check_bom_chars(source, end, bocu_1_bom, 3);
2796
+ skip = check_bom_chars(position, end, bocu_1_bom, 3);
2806
2797
  encoding = "BOCU-1";
2807
2798
  break;
2808
2799
  case 0x84:
2809
- skip = check_bom_chars(source, end, gb_18030_bom, 4);
2800
+ skip = check_bom_chars(position, end, gb_18030_bom, 4);
2810
2801
  encoding = "GB-18030";
2811
2802
  break;
2812
2803
  default: break;
@@ -2826,7 +2817,7 @@ namespace Sass {
2826
2817
  }
2827
2818
 
2828
2819
 
2829
- Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, Operand op)
2820
+ ExpressionObj Parser::fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, Operand op)
2830
2821
  {
2831
2822
  for (size_t i = 0, S = operands.size(); i < S; ++i) {
2832
2823
  base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), op, base, operands[i]);
@@ -2834,7 +2825,7 @@ namespace Sass {
2834
2825
  return base;
2835
2826
  }
2836
2827
 
2837
- Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, std::vector<Operand>& ops, size_t i)
2828
+ ExpressionObj Parser::fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, sass::vector<Operand>& ops, size_t i)
2838
2829
  {
2839
2830
  if (String_Schema* schema = Cast<String_Schema>(base)) {
2840
2831
  // return schema;
@@ -2850,7 +2841,7 @@ namespace Sass {
2850
2841
  || (ops[0].operand == Sass_OP::LTE)
2851
2842
  || (ops[0].operand == Sass_OP::GTE)
2852
2843
  )) {
2853
- Expression_Obj rhs = fold_operands(operands[i], operands, ops, i + 1);
2844
+ ExpressionObj rhs = fold_operands(operands[i], operands, ops, i + 1);
2854
2845
  rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[0], schema, rhs);
2855
2846
  return rhs;
2856
2847
  }
@@ -2858,12 +2849,19 @@ namespace Sass {
2858
2849
  }
2859
2850
  }
2860
2851
 
2852
+ if (operands.size() > Constants::MaxCallStack) {
2853
+ // XXX: this is never hit via spec tests
2854
+ sass::ostream stm;
2855
+ stm << "Stack depth exceeded max of " << Constants::MaxCallStack;
2856
+ error(stm.str());
2857
+ }
2858
+
2861
2859
  for (size_t S = operands.size(); i < S; ++i) {
2862
2860
  if (String_Schema* schema = Cast<String_Schema>(operands[i])) {
2863
2861
  if (schema->has_interpolants()) {
2864
2862
  if (i + 1 < S) {
2865
2863
  // this whole branch is never hit via spec tests
2866
- Expression_Obj rhs = fold_operands(operands[i+1], operands, ops, i + 2);
2864
+ ExpressionObj rhs = fold_operands(operands[i+1], operands, ops, i + 2);
2867
2865
  rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], schema, rhs);
2868
2866
  base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, rhs);
2869
2867
  return base;
@@ -2889,28 +2887,14 @@ namespace Sass {
2889
2887
  return base;
2890
2888
  }
2891
2889
 
2892
- void Parser::error(std::string msg, Position pos)
2890
+ void Parser::error(sass::string msg)
2893
2891
  {
2894
- Position p(pos.line ? pos : before_token);
2895
- ParserState pstate(path, source, p, Offset(0, 0));
2896
- // `pstate.src` may not outlive stack unwind so we must copy it.
2897
- // This is needed since we often parse dynamically generated code,
2898
- // e.g. for interpolations, and we normally don't want to keep this
2899
- // memory around after we parsed the AST tree successfully. Only on
2900
- // errors we want to preserve them for better error reporting.
2901
- char *src_copy = sass_copy_c_string(pstate.src);
2902
- pstate.src = src_copy;
2903
2892
  traces.push_back(Backtrace(pstate));
2904
- throw Exception::InvalidSass(pstate, traces, msg, src_copy);
2905
- }
2906
-
2907
- void Parser::error(std::string msg)
2908
- {
2909
- error(msg, pstate);
2893
+ throw Exception::InvalidSass(pstate, traces, msg);
2910
2894
  }
2911
2895
 
2912
2896
  // print a css parsing error with actual context information from parsed source
2913
- void Parser::css_error(const std::string& msg, const std::string& prefix, const std::string& middle, const bool trim)
2897
+ void Parser::css_error(const sass::string& msg, const sass::string& prefix, const sass::string& middle, const bool trim)
2914
2898
  {
2915
2899
  int max_len = 18;
2916
2900
  const char* end = this->end;
@@ -2919,13 +2903,13 @@ namespace Sass {
2919
2903
  if (!pos) pos = position;
2920
2904
 
2921
2905
  const char* last_pos(pos);
2922
- if (last_pos > source) {
2923
- utf8::prior(last_pos, source);
2906
+ if (last_pos > begin) {
2907
+ utf8::prior(last_pos, begin);
2924
2908
  }
2925
2909
  // backup position to last significant char
2926
- while (trim && last_pos > source && last_pos < end) {
2910
+ while (trim && last_pos > begin&& last_pos < end) {
2927
2911
  if (!Util::ascii_isspace(static_cast<unsigned char>(*last_pos))) break;
2928
- utf8::prior(last_pos, source);
2912
+ utf8::prior(last_pos, begin);
2929
2913
  }
2930
2914
 
2931
2915
  bool ellipsis_left = false;
@@ -2934,9 +2918,9 @@ namespace Sass {
2934
2918
 
2935
2919
  if (*pos_left) utf8::next(pos_left, end);
2936
2920
  if (*end_left) utf8::next(end_left, end);
2937
- while (pos_left > source) {
2921
+ while (pos_left > begin) {
2938
2922
  if (utf8::distance(pos_left, end_left) >= max_len) {
2939
- utf8::prior(pos_left, source);
2923
+ utf8::prior(pos_left, begin);
2940
2924
  ellipsis_left = *(pos_left) != '\n' &&
2941
2925
  *(pos_left) != '\r';
2942
2926
  utf8::next(pos_left, end);
@@ -2944,13 +2928,13 @@ namespace Sass {
2944
2928
  }
2945
2929
 
2946
2930
  const char* prev = pos_left;
2947
- utf8::prior(prev, source);
2931
+ utf8::prior(prev, begin);
2948
2932
  if (*prev == '\r') break;
2949
2933
  if (*prev == '\n') break;
2950
2934
  pos_left = prev;
2951
2935
  }
2952
- if (pos_left < source) {
2953
- pos_left = source;
2936
+ if (pos_left < begin) {
2937
+ pos_left = begin;
2954
2938
  }
2955
2939
 
2956
2940
  bool ellipsis_right = false;
@@ -2968,14 +2952,12 @@ namespace Sass {
2968
2952
  }
2969
2953
  // if (*end_right == 0) end_right ++;
2970
2954
 
2971
- std::string left(pos_left, end_left);
2972
- std::string right(pos_right, end_right);
2955
+ sass::string left(pos_left, end_left);
2956
+ sass::string right(pos_right, end_right);
2973
2957
  size_t left_subpos = left.size() > 15 ? left.size() - 15 : 0;
2974
2958
  size_t right_subpos = right.size() > 15 ? right.size() - 15 : 0;
2975
2959
  if (left_subpos && ellipsis_left) left = ellipsis + left.substr(left_subpos);
2976
2960
  if (right_subpos && ellipsis_right) right = right.substr(right_subpos) + ellipsis;
2977
- // Hotfix when source is null, probably due to interpolation parsing!?
2978
- if (source == NULL || *source == 0) source = pstate.src;
2979
2961
  // now pass new message to the more generic error function
2980
2962
  error(msg + prefix + quote(left) + middle + quote(right));
2981
2963
  }