sassc 1.11.1 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/README.md +3 -2
  4. data/ext/libsass/Makefile.conf +2 -1
  5. data/ext/libsass/appveyor.yml +10 -5
  6. data/ext/libsass/docs/dev-ast-memory.md +223 -0
  7. data/ext/libsass/include/sass/base.h +2 -0
  8. data/ext/libsass/script/bootstrap +7 -4
  9. data/ext/libsass/script/ci-build-libsass +3 -3
  10. data/ext/libsass/script/ci-install-compiler +2 -0
  11. data/ext/libsass/script/ci-report-coverage +2 -1
  12. data/ext/libsass/script/test-leaks.pl +103 -0
  13. data/ext/libsass/src/ast.cpp +621 -495
  14. data/ext/libsass/src/ast.hpp +801 -367
  15. data/ext/libsass/src/ast_def_macros.hpp +5 -5
  16. data/ext/libsass/src/ast_fwd_decl.hpp +312 -14
  17. data/ext/libsass/src/bind.cpp +54 -51
  18. data/ext/libsass/src/bind.hpp +3 -7
  19. data/ext/libsass/src/check_nesting.cpp +117 -120
  20. data/ext/libsass/src/check_nesting.hpp +38 -34
  21. data/ext/libsass/src/color_maps.cpp +3 -3
  22. data/ext/libsass/src/color_maps.hpp +3 -3
  23. data/ext/libsass/src/context.cpp +33 -34
  24. data/ext/libsass/src/context.hpp +12 -14
  25. data/ext/libsass/src/cssize.cpp +200 -228
  26. data/ext/libsass/src/cssize.hpp +49 -49
  27. data/ext/libsass/src/debugger.hpp +260 -241
  28. data/ext/libsass/src/emitter.cpp +6 -6
  29. data/ext/libsass/src/emitter.hpp +7 -7
  30. data/ext/libsass/src/environment.cpp +2 -2
  31. data/ext/libsass/src/environment.hpp +0 -2
  32. data/ext/libsass/src/error_handling.cpp +5 -5
  33. data/ext/libsass/src/error_handling.hpp +12 -12
  34. data/ext/libsass/src/eval.cpp +412 -401
  35. data/ext/libsass/src/eval.hpp +61 -62
  36. data/ext/libsass/src/expand.cpp +223 -204
  37. data/ext/libsass/src/expand.hpp +42 -42
  38. data/ext/libsass/src/extend.cpp +198 -201
  39. data/ext/libsass/src/extend.hpp +12 -14
  40. data/ext/libsass/src/file.hpp +4 -5
  41. data/ext/libsass/src/functions.cpp +413 -418
  42. data/ext/libsass/src/functions.hpp +7 -10
  43. data/ext/libsass/src/inspect.cpp +115 -109
  44. data/ext/libsass/src/inspect.hpp +69 -69
  45. data/ext/libsass/src/listize.cpp +31 -33
  46. data/ext/libsass/src/listize.hpp +8 -10
  47. data/ext/libsass/src/memory/SharedPtr.cpp +116 -0
  48. data/ext/libsass/src/memory/SharedPtr.hpp +202 -0
  49. data/ext/libsass/src/node.cpp +45 -43
  50. data/ext/libsass/src/node.hpp +15 -15
  51. data/ext/libsass/src/operation.hpp +136 -136
  52. data/ext/libsass/src/output.cpp +48 -49
  53. data/ext/libsass/src/output.hpp +14 -14
  54. data/ext/libsass/src/parser.cpp +530 -554
  55. data/ext/libsass/src/parser.hpp +91 -96
  56. data/ext/libsass/src/prelexer.cpp +13 -10
  57. data/ext/libsass/src/remove_placeholders.cpp +25 -21
  58. data/ext/libsass/src/remove_placeholders.hpp +7 -7
  59. data/ext/libsass/src/sass2scss.cpp +2 -1
  60. data/ext/libsass/src/sass_context.cpp +125 -107
  61. data/ext/libsass/src/sass_context.hpp +1 -1
  62. data/ext/libsass/src/sass_util.hpp +5 -5
  63. data/ext/libsass/src/sass_values.cpp +27 -27
  64. data/ext/libsass/src/source_map.cpp +2 -2
  65. data/ext/libsass/src/source_map.hpp +2 -2
  66. data/ext/libsass/src/subset_map.cpp +57 -0
  67. data/ext/libsass/src/subset_map.hpp +8 -76
  68. data/ext/libsass/src/to_c.cpp +13 -13
  69. data/ext/libsass/src/to_c.hpp +14 -14
  70. data/ext/libsass/src/to_value.cpp +20 -20
  71. data/ext/libsass/src/to_value.hpp +20 -21
  72. data/ext/libsass/src/util.cpp +55 -88
  73. data/ext/libsass/src/util.hpp +9 -13
  74. data/ext/libsass/src/values.cpp +27 -26
  75. data/ext/libsass/src/values.hpp +2 -2
  76. data/ext/libsass/test/test_subset_map.cpp +69 -69
  77. data/ext/libsass/win/libsass.targets +3 -2
  78. data/ext/libsass/win/libsass.vcxproj.filters +9 -6
  79. data/lib/sassc/version.rb +1 -1
  80. data/sassc.gemspec +0 -1
  81. data/test/native_test.rb +1 -1
  82. metadata +7 -5
  83. data/ext/libsass/src/ast_factory.hpp +0 -92
  84. data/ext/libsass/src/memory_manager.cpp +0 -77
  85. data/ext/libsass/src/memory_manager.hpp +0 -48
@@ -5,6 +5,7 @@
5
5
  #include "extend.hpp"
6
6
  #include "emitter.hpp"
7
7
  #include "color_maps.hpp"
8
+ #include "ast_fwd_decl.hpp"
8
9
  #include <set>
9
10
  #include <iomanip>
10
11
  #include <iostream>
@@ -15,17 +16,35 @@
15
16
 
16
17
  namespace Sass {
17
18
 
18
- static Null sass_null(Sass::Null(ParserState("null")));
19
+ static Null sass_null(ParserState("null"));
19
20
 
20
- bool Supports_Operator::needs_parens(Supports_Condition* cond) const {
21
- return dynamic_cast<Supports_Negation*>(cond) ||
22
- (dynamic_cast<Supports_Operator*>(cond) &&
23
- dynamic_cast<Supports_Operator*>(cond)->operand() != operand());
21
+ bool Supports_Operator::needs_parens(Supports_Condition_Obj cond) const {
22
+ if (Supports_Operator_Obj op = SASS_MEMORY_CAST(Supports_Operator, cond)) {
23
+ return op->operand() != operand();
24
+ }
25
+ return SASS_MEMORY_CAST(Supports_Negation, cond) != NULL;
26
+ }
27
+
28
+ bool Supports_Negation::needs_parens(Supports_Condition_Obj cond) const {
29
+ return SASS_MEMORY_CAST(Supports_Negation, cond) ||
30
+ SASS_MEMORY_CAST(Supports_Operator, cond);
31
+ }
32
+
33
+ size_t HashExpression::operator() (Expression_Obj ex) const {
34
+ return ex ? ex->hash() : 0;
35
+ }
36
+
37
+ size_t HashSimpleSelector::operator() (Simple_Selector_Obj ex) const {
38
+ return ex ? ex->hash() : 0;
24
39
  }
25
40
 
26
- bool Supports_Negation::needs_parens(Supports_Condition* cond) const {
27
- return dynamic_cast<Supports_Negation*>(cond) ||
28
- dynamic_cast<Supports_Operator*>(cond);
41
+
42
+ bool CompareExpression::operator()(const Expression_Obj& lhs, const Expression_Obj& rhs) const {
43
+ return lhs && rhs && lhs->eq(*rhs);
44
+ }
45
+
46
+ bool CompareSimpleSelector::operator()(Simple_Selector_Obj lhs, Simple_Selector_Obj rhs) const {
47
+ return &lhs && &rhs && *lhs == *rhs;
29
48
  }
30
49
 
31
50
  std::string & str_ltrim(std::string & str)
@@ -59,13 +78,13 @@ namespace Sass {
59
78
  void String_Schema::rtrim()
60
79
  {
61
80
  if (!empty()) {
62
- if (String* str = dynamic_cast<String*>(last())) str->rtrim();
81
+ if (String_Ptr str = SASS_MEMORY_CAST(String, last())) str->rtrim();
63
82
  }
64
83
  }
65
84
  void String_Schema::ltrim()
66
85
  {
67
86
  if (!empty()) {
68
- if (String* str = dynamic_cast<String*>(first())) str->ltrim();
87
+ if (String_Ptr str = SASS_MEMORY_CAST(String, first())) str->ltrim();
69
88
  }
70
89
  }
71
90
  void String_Schema::trim()
@@ -82,7 +101,7 @@ namespace Sass {
82
101
 
83
102
  void Arguments::set_delayed(bool delayed)
84
103
  {
85
- for (Argument* arg : elements()) {
104
+ for (Argument_Obj arg : elements()) {
86
105
  if (arg) arg->set_delayed(delayed);
87
106
  }
88
107
  is_delayed(delayed);
@@ -92,7 +111,7 @@ namespace Sass {
92
111
  bool At_Root_Query::exclude(std::string str)
93
112
  {
94
113
  bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
95
- List* l = static_cast<List*>(value());
114
+ List_Ptr l = static_cast<List_Ptr>(&value());
96
115
  std::string v;
97
116
 
98
117
  if (with)
@@ -137,13 +156,13 @@ namespace Sass {
137
156
 
138
157
 
139
158
 
140
- bool SimpleSequence_Selector::operator< (const SimpleSequence_Selector& rhs) const
159
+ bool Compound_Selector::operator< (const Compound_Selector& rhs) const
141
160
  {
142
161
  size_t L = std::min(length(), rhs.length());
143
162
  for (size_t i = 0; i < L; ++i)
144
163
  {
145
- Simple_Selector* l = (*this)[i];
146
- Simple_Selector* r = rhs[i];
164
+ Simple_Selector_Obj l = (*this)[i];
165
+ Simple_Selector_Obj r = rhs[i];
147
166
  if (!l && !r) return false;
148
167
  else if (!r) return false;
149
168
  else if (!l) return true;
@@ -154,56 +173,56 @@ namespace Sass {
154
173
  return length() < rhs.length();
155
174
  }
156
175
 
157
- bool SimpleSequence_Selector::has_parent_ref()
176
+ bool Compound_Selector::has_parent_ref()
158
177
  {
159
- for (Simple_Selector* s : *this) {
178
+ for (Simple_Selector_Obj s : *this) {
160
179
  if (s && s->has_parent_ref()) return true;
161
180
  }
162
181
  return false;
163
182
  }
164
183
 
165
- bool SimpleSequence_Selector::has_real_parent_ref()
184
+ bool Compound_Selector::has_real_parent_ref()
166
185
  {
167
- for (Simple_Selector* s : *this) {
186
+ for (Simple_Selector_Obj s : *this) {
168
187
  if (s && s->has_real_parent_ref()) return true;
169
188
  }
170
189
  return false;
171
190
  }
172
191
 
173
- bool Sequence_Selector::has_parent_ref()
192
+ bool Complex_Selector::has_parent_ref()
174
193
  {
175
194
  return (head() && head()->has_parent_ref()) ||
176
195
  (tail() && tail()->has_parent_ref());
177
196
  }
178
197
 
179
- bool Sequence_Selector::has_real_parent_ref()
198
+ bool Complex_Selector::has_real_parent_ref()
180
199
  {
181
200
  return (head() && head()->has_real_parent_ref()) ||
182
201
  (tail() && tail()->has_real_parent_ref());
183
202
  }
184
203
 
185
- bool Sequence_Selector::operator< (const Sequence_Selector& rhs) const
204
+ bool Complex_Selector::operator< (const Complex_Selector& rhs) const
186
205
  {
187
206
  // const iterators for tails
188
- const Sequence_Selector* l = this;
189
- const Sequence_Selector* r = &rhs;
190
- SimpleSequence_Selector* l_h = l ? l->head() : 0;
191
- SimpleSequence_Selector* r_h = r ? r->head() : 0;
207
+ Complex_Selector_Ptr_Const l = this;
208
+ Complex_Selector_Ptr_Const r = &rhs;
209
+ Compound_Selector_Ptr l_h = l ? &l->head() : 0;
210
+ Compound_Selector_Ptr r_h = r ? &r->head() : 0;
192
211
  // process all tails
193
212
  while (true)
194
213
  {
195
214
  // skip empty ancestor first
196
215
  if (l && l->is_empty_ancestor())
197
216
  {
198
- l = l->tail();
199
- l_h = l ? l->head() : 0;
217
+ l = &l->tail();
218
+ l_h = l ? &l->head() : 0;
200
219
  continue;
201
220
  }
202
221
  // skip empty ancestor first
203
222
  if (r && r->is_empty_ancestor())
204
223
  {
205
- r = r->tail();
206
- r_h = r ? r->head() : 0;
224
+ r = &r->tail();
225
+ r_h = r ? &r->head() : 0;
207
226
  continue;
208
227
  }
209
228
  // check for valid selectors
@@ -216,11 +235,11 @@ namespace Sass {
216
235
  if (l->combinator() != r->combinator())
217
236
  { return l->combinator() < r->combinator(); }
218
237
  // advance to next tails
219
- l = l->tail();
220
- r = r->tail();
238
+ l = &l->tail();
239
+ r = &r->tail();
221
240
  // fetch the next headers
222
- l_h = l ? l->head() : 0;
223
- r_h = r ? r->head() : 0;
241
+ l_h = l ? &l->head() : 0;
242
+ r_h = r ? &r->head() : 0;
224
243
  }
225
244
  // one side is null
226
245
  else if (!r_h) return true;
@@ -232,11 +251,11 @@ namespace Sass {
232
251
  if (l->combinator() != r->combinator())
233
252
  { return l->combinator() < r->combinator(); }
234
253
  // advance to next tails
235
- l = l->tail();
236
- r = r->tail();
254
+ l = &l->tail();
255
+ r = &r->tail();
237
256
  // fetch the next headers
238
- l_h = l ? l->head() : 0;
239
- r_h = r ? r->head() : 0;
257
+ l_h = l ? &l->head() : 0;
258
+ r_h = r ? &r->head() : 0;
240
259
  }
241
260
  // heads are not equal
242
261
  else return *l_h < *r_h;
@@ -244,28 +263,28 @@ namespace Sass {
244
263
  return true;
245
264
  }
246
265
 
247
- bool Sequence_Selector::operator== (const Sequence_Selector& rhs) const
266
+ bool Complex_Selector::operator== (const Complex_Selector& rhs) const
248
267
  {
249
268
  // const iterators for tails
250
- const Sequence_Selector* l = this;
251
- const Sequence_Selector* r = &rhs;
252
- SimpleSequence_Selector* l_h = l ? l->head() : 0;
253
- SimpleSequence_Selector* r_h = r ? r->head() : 0;
269
+ Complex_Selector_Ptr_Const l = this;
270
+ Complex_Selector_Ptr_Const r = &rhs;
271
+ Compound_Selector_Ptr l_h = l ? &l->head() : 0;
272
+ Compound_Selector_Ptr r_h = r ? &r->head() : 0;
254
273
  // process all tails
255
274
  while (true)
256
275
  {
257
276
  // skip empty ancestor first
258
277
  if (l && l->is_empty_ancestor())
259
278
  {
260
- l = l->tail();
261
- l_h = l ? l->head() : 0;
279
+ l = &l->tail();
280
+ l_h = l ? &l->head() : 0;
262
281
  continue;
263
282
  }
264
283
  // skip empty ancestor first
265
284
  if (r && r->is_empty_ancestor())
266
285
  {
267
- r = r->tail();
268
- r_h = r ? r->head() : 0;
286
+ r = &r->tail();
287
+ r_h = r ? &r->head() : 0;
269
288
  continue;
270
289
  }
271
290
  // check the pointers
@@ -278,27 +297,27 @@ namespace Sass {
278
297
  if (l->combinator() != r->combinator())
279
298
  { return l->combinator() < r->combinator(); }
280
299
  // advance to next tails
281
- l = l->tail();
282
- r = r->tail();
300
+ l = &l->tail();
301
+ r = &r->tail();
283
302
  // fetch the next heads
284
- l_h = l ? l->head() : 0;
285
- r_h = r ? r->head() : 0;
303
+ l_h = l ? &l->head() : 0;
304
+ r_h = r ? &r->head() : 0;
286
305
  }
287
- // fail if only one is null
288
- else if (!r_h) return !l_h;
289
- else if (!l_h) return !r_h;
290
- // heads ok and equal
291
- else if (*l_h == *r_h)
306
+ // equals if other head is empty
307
+ else if ((!l_h && !r_h) ||
308
+ (!l_h && r_h->empty()) ||
309
+ (!r_h && l_h->empty()) ||
310
+ (*l_h == *r_h))
292
311
  {
293
312
  // check combinator after heads
294
313
  if (l->combinator() != r->combinator())
295
314
  { return l->combinator() == r->combinator(); }
296
315
  // advance to next tails
297
- l = l->tail();
298
- r = r->tail();
316
+ l = &l->tail();
317
+ r = &r->tail();
299
318
  // fetch the next heads
300
- l_h = l ? l->head() : 0;
301
- r_h = r ? r->head() : 0;
319
+ l_h = l ? &l->head() : 0;
320
+ r_h = r ? &r->head() : 0;
302
321
  }
303
322
  // abort
304
323
  else break;
@@ -307,66 +326,111 @@ namespace Sass {
307
326
  return false;
308
327
  }
309
328
 
310
- SimpleSequence_Selector* SimpleSequence_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
329
+ Compound_Selector_Ptr Compound_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
311
330
  {
312
- SimpleSequence_Selector* unified = rhs;
331
+ if (empty()) return rhs;
332
+ Compound_Selector_Obj unified = SASS_MEMORY_COPY(rhs);
313
333
  for (size_t i = 0, L = length(); i < L; ++i)
314
334
  {
315
- if (!unified) break;
316
- unified = (*this)[i]->unify_with(unified, ctx);
335
+ if (unified.isNull()) break;
336
+ unified = at(i)->unify_with(&unified, ctx);
317
337
  }
318
- return unified;
338
+ return unified.detach();
339
+ }
340
+
341
+ bool Selector::operator== (const Selector& rhs) const
342
+ {
343
+ if (Selector_List_Ptr_Const sl = dynamic_cast<Selector_List_Ptr_Const>(this)) return *sl == rhs;
344
+ if (Simple_Selector_Ptr_Const sp = dynamic_cast<Simple_Selector_Ptr_Const>(this)) return *sp == rhs;
345
+ throw std::runtime_error("invalid selector base classes to compare");
346
+ return false;
347
+ }
348
+
349
+ bool Selector::operator< (const Selector& rhs) const
350
+ {
351
+ if (Selector_List_Ptr_Const sl = dynamic_cast<Selector_List_Ptr_Const>(this)) return *sl < rhs;
352
+ if (Simple_Selector_Ptr_Const sp = dynamic_cast<Simple_Selector_Ptr_Const>(this)) return *sp < rhs;
353
+ throw std::runtime_error("invalid selector base classes to compare");
354
+ return false;
355
+ }
356
+
357
+ bool Simple_Selector::operator== (const Selector& rhs) const
358
+ {
359
+ if (Simple_Selector_Ptr_Const sp = dynamic_cast<Simple_Selector_Ptr_Const>(&rhs)) return *this == *sp;
360
+ return false;
361
+ }
362
+
363
+ bool Simple_Selector::operator< (const Selector& rhs) const
364
+ {
365
+ if (Simple_Selector_Ptr_Const sp = dynamic_cast<Simple_Selector_Ptr_Const>(&rhs)) return *this < *sp;
366
+ return false;
319
367
  }
320
368
 
321
369
  bool Simple_Selector::operator== (const Simple_Selector& rhs) const
322
370
  {
323
- if (const Pseudo_Selector* lp = dynamic_cast<const Pseudo_Selector*>(this)) return *lp == rhs;
324
- if (const Wrapped_Selector* lw = dynamic_cast<const Wrapped_Selector*>(this)) return *lw == rhs;
325
- if (const Attribute_Selector* la = dynamic_cast<const Attribute_Selector*>(this)) return *la == rhs;
326
- if (is_ns_eq(ns(), rhs.ns()))
327
- { return name() == rhs.name(); }
328
- return ns() == rhs.ns();
371
+ Simple_Type type = simple_type();
372
+ // dynamic cast is a bottleneck - use concrete type as types are final
373
+ if (type == PSEUDO_SEL /* Pseudo_Selector_Ptr_Const lp = dynamic_cast<Pseudo_Selector_Ptr_Const>(this) */) {
374
+ return *static_cast<Pseudo_Selector_Ptr_Const>(this) == rhs;
375
+ }
376
+ else if (type == WRAPPED_SEL /* Wrapped_Selector_Ptr_Const lw = dynamic_cast<Wrapped_Selector_Ptr_Const>(this) */) {
377
+ return *static_cast<Wrapped_Selector_Ptr_Const>(this) == rhs;
378
+ }
379
+ else if (type == ATTR_SEL /* Attribute_Selector_Ptr_Const la = dynamic_cast<Attribute_Selector_Ptr_Const>(this) */) {
380
+ return *static_cast<Attribute_Selector_Ptr_Const>(this) == rhs;
381
+ }
382
+ else if (name_ == rhs.name_)
383
+ { return is_ns_eq(ns_, rhs.ns_); }
384
+ else return false;
329
385
  }
330
386
 
331
387
  bool Simple_Selector::operator< (const Simple_Selector& rhs) const
332
388
  {
333
- if (const Pseudo_Selector* lp = dynamic_cast<const Pseudo_Selector*>(this)) return *lp == rhs;
334
- if (const Wrapped_Selector* lw = dynamic_cast<const Wrapped_Selector*>(this)) return *lw < rhs;
335
- if (const Attribute_Selector* la = dynamic_cast<const Attribute_Selector*>(this)) return *la < rhs;
336
- if (is_ns_eq(ns(), rhs.ns()))
337
- { return name() < rhs.name(); }
338
- return ns() < rhs.ns();
389
+ Simple_Type type = simple_type();
390
+ // dynamic cast is a bottleneck - use concrete type as types are final
391
+ if (type == PSEUDO_SEL /* Pseudo_Selector_Ptr_Const lp = dynamic_cast<Pseudo_Selector_Ptr_Const>(this) */) {
392
+ return *static_cast<Pseudo_Selector_Ptr_Const>(this) < rhs;
393
+ }
394
+ else if (type == WRAPPED_SEL /* Wrapped_Selector_Ptr_Const lw = dynamic_cast<Wrapped_Selector_Ptr_Const>(this) */) {
395
+ return *static_cast<Wrapped_Selector_Ptr_Const>(this) < rhs;
396
+ }
397
+ else if (type == ATTR_SEL /* Attribute_Selector_Ptr_Const la = dynamic_cast<Attribute_Selector_Ptr_Const>(this) */) {
398
+ return *static_cast<Attribute_Selector_Ptr_Const>(this) < rhs;
399
+ }
400
+ if (is_ns_eq(ns_, rhs.ns_))
401
+ { return name_ < rhs.name_; }
402
+ return ns_ < rhs.ns_;
339
403
  }
340
404
 
341
- bool CommaSequence_Selector::operator== (const Selector& rhs) const
405
+ bool Selector_List::operator== (const Selector& rhs) const
342
406
  {
343
407
  // solve the double dispatch problem by using RTTI information via dynamic cast
344
- if (const CommaSequence_Selector* ls = dynamic_cast<const CommaSequence_Selector*>(&rhs)) { return *this == *ls; }
345
- else if (const Sequence_Selector* ls = dynamic_cast<const Sequence_Selector*>(&rhs)) { return *this == *ls; }
346
- else if (const SimpleSequence_Selector* ls = dynamic_cast<const SimpleSequence_Selector*>(&rhs)) { return *this == *ls; }
408
+ if (Selector_List_Ptr_Const ls = dynamic_cast<Selector_List_Ptr_Const>(&rhs)) { return *this == *ls; }
409
+ else if (Complex_Selector_Ptr_Const ls = dynamic_cast<Complex_Selector_Ptr_Const>(&rhs)) { return *this == *ls; }
410
+ else if (Compound_Selector_Ptr_Const ls = dynamic_cast<Compound_Selector_Ptr_Const>(&rhs)) { return *this == *ls; }
347
411
  // no compare method
348
412
  return this == &rhs;
349
413
  }
350
414
 
351
415
  // Selector lists can be compared to comma lists
352
- bool CommaSequence_Selector::operator==(const Expression& rhs) const
416
+ bool Selector_List::operator==(const Expression& rhs) const
353
417
  {
354
418
  // solve the double dispatch problem by using RTTI information via dynamic cast
355
- if (const List* ls = dynamic_cast<const List*>(&rhs)) { return *this == *ls; }
356
- if (const Selector* ls = dynamic_cast<const Selector*>(&rhs)) { return *this == *ls; }
419
+ if (List_Ptr_Const ls = dynamic_cast<List_Ptr_Const>(&rhs)) { return *this == *ls; }
420
+ if (Selector_Ptr_Const ls = dynamic_cast<Selector_Ptr_Const>(&rhs)) { return *this == *ls; }
357
421
  // compare invalid (maybe we should error?)
358
422
  return false;
359
423
  }
360
424
 
361
- bool CommaSequence_Selector::operator== (const CommaSequence_Selector& rhs) const
425
+ bool Selector_List::operator== (const Selector_List& rhs) const
362
426
  {
363
427
  // for array access
364
428
  size_t i = 0, n = 0;
365
429
  size_t iL = length();
366
430
  size_t nL = rhs.length();
367
431
  // create temporary vectors and sort them
368
- std::vector<Sequence_Selector*> l_lst = this->elements();
369
- std::vector<Sequence_Selector*> r_lst = rhs.elements();
432
+ std::vector<Complex_Selector_Obj> l_lst = this->elements();
433
+ std::vector<Complex_Selector_Obj> r_lst = rhs.elements();
370
434
  std::sort(l_lst.begin(), l_lst.end(), cmp_complex_selector());
371
435
  std::sort(r_lst.begin(), r_lst.end(), cmp_complex_selector());
372
436
  // process loop
@@ -376,8 +440,8 @@ namespace Sass {
376
440
  if (i == iL) return iL == nL;
377
441
  else if (n == nL) return iL == nL;
378
442
  // the access the vector items
379
- Sequence_Selector* l = l_lst[i];
380
- Sequence_Selector* r = r_lst[n];
443
+ Complex_Selector_Obj l = l_lst[i];
444
+ Complex_Selector_Obj r = r_lst[n];
381
445
  // skip nulls
382
446
  if (!l) ++i;
383
447
  else if (!r) ++n;
@@ -391,10 +455,25 @@ namespace Sass {
391
455
  return true;
392
456
  }
393
457
 
394
- SimpleSequence_Selector* Simple_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
458
+ bool Selector_List::operator< (const Selector& rhs) const
459
+ {
460
+ if (Selector_List_Ptr_Const sp = dynamic_cast<Selector_List_Ptr_Const>(&rhs)) return *this < *sp;
461
+ return false;
462
+ }
463
+
464
+ bool Selector_List::operator< (const Selector_List& rhs) const
465
+ {
466
+ if (this->length() != rhs.length()) return false;
467
+ for (size_t i = 0; i < rhs.length(); i ++) {
468
+ if (!(*at(i) < *rhs.at(i))) return false;
469
+ }
470
+ return true;
471
+ }
472
+
473
+ Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
395
474
  {
396
475
  for (size_t i = 0, L = rhs->length(); i < L; ++i)
397
- { if (to_string(ctx.c_options) == (*rhs)[i]->to_string(ctx.c_options)) return rhs; }
476
+ { if (to_string(ctx.c_options) == rhs->at(i)->to_string(ctx.c_options)) return rhs; }
398
477
 
399
478
  // check for pseudo elements because they are always last
400
479
  size_t i, L;
@@ -403,7 +482,7 @@ namespace Sass {
403
482
  {
404
483
  for (i = 0, L = rhs->length(); i < L; ++i)
405
484
  {
406
- if ((dynamic_cast<Pseudo_Selector*>((*rhs)[i]) || dynamic_cast<Wrapped_Selector*>((*rhs)[i])) && (*rhs)[L-1]->is_pseudo_element())
485
+ if ((SASS_MEMORY_CAST(Pseudo_Selector, (*rhs)[i]) || SASS_MEMORY_CAST(Wrapped_Selector, (*rhs)[i])) && (*rhs)[L-1]->is_pseudo_element())
407
486
  { found = true; break; }
408
487
  }
409
488
  }
@@ -411,26 +490,20 @@ namespace Sass {
411
490
  {
412
491
  for (i = 0, L = rhs->length(); i < L; ++i)
413
492
  {
414
- if (dynamic_cast<Pseudo_Selector*>((*rhs)[i]) || dynamic_cast<Wrapped_Selector*>((*rhs)[i]))
493
+ if (SASS_MEMORY_CAST(Pseudo_Selector, (*rhs)[i]) || SASS_MEMORY_CAST(Wrapped_Selector, (*rhs)[i]))
415
494
  { found = true; break; }
416
495
  }
417
496
  }
418
497
  if (!found)
419
498
  {
420
- SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, *rhs);
421
- (*cpy) << this;
422
- return cpy;
423
- }
424
- SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
425
- for (size_t j = 0; j < i; ++j)
426
- { (*cpy) << (*rhs)[j]; }
427
- (*cpy) << this;
428
- for (size_t j = i; j < L; ++j)
429
- { (*cpy) << (*rhs)[j]; }
430
- return cpy;
499
+ rhs->append(this);
500
+ return rhs;
501
+ }
502
+ rhs->elements().insert(rhs->elements().begin() + i, this);
503
+ return rhs;
431
504
  }
432
505
 
433
- Simple_Selector* Element_Selector::unify_with(Simple_Selector* rhs, Context& ctx)
506
+ Simple_Selector_Ptr Element_Selector::unify_with(Simple_Selector_Ptr rhs, Context& ctx)
434
507
  {
435
508
  // check if ns can be extended
436
509
  // true for no ns or universal
@@ -440,63 +513,54 @@ namespace Sass {
440
513
  // true for valid ns and universal
441
514
  if (!rhs->is_universal_ns())
442
515
  {
443
- // creaty the copy inside (avoid unnecessary copies)
444
- Element_Selector* ts = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *this);
445
516
  // overwrite the name if star is given as name
446
- if (ts->name() == "*") { ts->name(rhs->name()); }
517
+ if (this->name() == "*") { this->name(rhs->name()); }
447
518
  // now overwrite the namespace name and flag
448
- ts->ns(rhs->ns()); ts->has_ns(rhs->has_ns());
519
+ this->ns(rhs->ns()); this->has_ns(rhs->has_ns());
449
520
  // return copy
450
- return ts;
521
+ return this;
451
522
  }
452
523
  }
453
524
  // namespace may changed, check the name now
454
525
  // overwrite star (but not with another star)
455
526
  if (name() == "*" && rhs->name() != "*")
456
527
  {
457
- // creaty the copy inside (avoid unnecessary copies)
458
- Element_Selector* ts = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *this);
459
528
  // simply set the new name
460
- ts->name(rhs->name());
529
+ this->name(rhs->name());
461
530
  // return copy
462
- return ts;
531
+ return this;
463
532
  }
464
533
  // return original
465
534
  return this;
466
535
  }
467
536
 
468
- SimpleSequence_Selector* Element_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
537
+ Compound_Selector_Ptr Element_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
469
538
  {
470
539
  // TODO: handle namespaces
471
540
 
472
541
  // if the rhs is empty, just return a copy of this
473
542
  if (rhs->length() == 0) {
474
- SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
475
- (*cpy) << this;
476
- return cpy;
543
+ rhs->append(this);
544
+ return rhs;
477
545
  }
478
546
 
479
- Simple_Selector* rhs_0 = (*rhs)[0];
547
+ Simple_Selector_Ptr rhs_0 = &rhs->at(0);
480
548
  // otherwise, this is a tag name
481
549
  if (name() == "*")
482
550
  {
483
551
  if (typeid(*rhs_0) == typeid(Element_Selector))
484
552
  {
485
553
  // if rhs is universal, just return this tagname + rhs's qualifiers
486
- SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, *rhs);
487
- Element_Selector* ts = static_cast<Element_Selector*>(rhs_0);
488
- (*cpy)[0] = this->unify_with(ts, ctx);
489
- return cpy;
554
+ Element_Selector_Ptr ts = SASS_MEMORY_CAST_PTR(Element_Selector, rhs_0);
555
+ rhs->at(0) = this->unify_with(ts, ctx);
556
+ return rhs;
490
557
  }
491
- else if (dynamic_cast<Class_Selector*>(rhs_0) || dynamic_cast<Id_Selector*>(rhs_0)) {
558
+ else if (SASS_MEMORY_CAST_PTR(Class_Selector, rhs_0) || SASS_MEMORY_CAST_PTR(Id_Selector, rhs_0)) {
492
559
  // qualifier is `.class`, so we can prefix with `ns|*.class`
493
- SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
494
560
  if (has_ns() && !rhs_0->has_ns()) {
495
- if (ns() != "*") (*cpy) << this;
561
+ if (ns() != "*") rhs->elements().insert(rhs->begin(), this);
496
562
  }
497
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
498
- { (*cpy) << (*rhs)[i]; }
499
- return cpy;
563
+ return rhs;
500
564
  }
501
565
 
502
566
 
@@ -508,48 +572,42 @@ namespace Sass {
508
572
  // if rhs is universal, just return this tagname + rhs's qualifiers
509
573
  if (rhs_0->name() != "*" && rhs_0->ns() != "*" && rhs_0->name() != name()) return 0;
510
574
  // otherwise create new compound and unify first simple selector
511
- SimpleSequence_Selector* copy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, *rhs);
512
- (*copy)[0] = this->unify_with(rhs_0, ctx);
513
- return copy;
575
+ rhs->at(0) = this->unify_with(rhs_0, ctx);
576
+ return rhs;
514
577
 
515
578
  }
516
579
  // else it's a tag name and a bunch of qualifiers -- just append them
517
- SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
518
- if (name() != "*") (*cpy) << this;
519
- (*cpy) += rhs;
520
- return cpy;
580
+ if (name() != "*") rhs->elements().insert(rhs->begin(), this);
581
+ return rhs;
521
582
  }
522
583
 
523
- SimpleSequence_Selector* Class_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
584
+ Compound_Selector_Ptr Class_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
524
585
  {
525
586
  rhs->has_line_break(has_line_break());
526
587
  return Simple_Selector::unify_with(rhs, ctx);
527
588
  }
528
589
 
529
- SimpleSequence_Selector* Id_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
590
+ Compound_Selector_Ptr Id_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
530
591
  {
531
592
  for (size_t i = 0, L = rhs->length(); i < L; ++i)
532
593
  {
533
- Simple_Selector* rhs_i = (*rhs)[i];
534
- if (typeid(*rhs_i) == typeid(Id_Selector) && static_cast<Id_Selector*>(rhs_i)->name() != name()) {
535
- return 0;
594
+ if (Id_Selector_Ptr sel = SASS_MEMORY_CAST(Id_Selector, rhs->at(i))) {
595
+ if (sel->name() != name()) return 0;
536
596
  }
537
597
  }
538
598
  rhs->has_line_break(has_line_break());
539
599
  return Simple_Selector::unify_with(rhs, ctx);
540
600
  }
541
601
 
542
- SimpleSequence_Selector* Pseudo_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
602
+ Compound_Selector_Ptr Pseudo_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
543
603
  {
544
604
  if (is_pseudo_element())
545
605
  {
546
606
  for (size_t i = 0, L = rhs->length(); i < L; ++i)
547
607
  {
548
- Simple_Selector* rhs_i = (*rhs)[i];
549
- if (typeid(*rhs_i) == typeid(Pseudo_Selector) &&
550
- static_cast<Pseudo_Selector*>(rhs_i)->is_pseudo_element() &&
551
- static_cast<Pseudo_Selector*>(rhs_i)->name() != name())
552
- { return 0; }
608
+ if (Pseudo_Selector_Ptr sel = SASS_MEMORY_CAST(Pseudo_Selector, rhs->at(i))) {
609
+ if (sel->is_pseudo_element() && sel->name() != name()) return 0;
610
+ }
553
611
  }
554
612
  }
555
613
  return Simple_Selector::unify_with(rhs, ctx);
@@ -560,16 +618,23 @@ namespace Sass {
560
618
  if (is_ns_eq(ns(), rhs.ns())) {
561
619
  if (name() == rhs.name()) {
562
620
  if (matcher() == rhs.matcher()) {
563
- return value() < rhs.value();
621
+ bool no_lhs_val = value().isNull();
622
+ bool no_rhs_val = rhs.value().isNull();
623
+ if (no_lhs_val && no_rhs_val) {
624
+ return true;
625
+ }
626
+ if (!no_lhs_val && !no_rhs_val) {
627
+ return *value() < *rhs.value();
628
+ }
564
629
  } else { return matcher() < rhs.matcher(); }
565
630
  } else { return name() < rhs.name(); }
566
631
  }
567
- else return false;
632
+ return false;
568
633
  }
569
634
 
570
635
  bool Attribute_Selector::operator< (const Simple_Selector& rhs) const
571
636
  {
572
- if (const Attribute_Selector* w = dynamic_cast<const Attribute_Selector*>(&rhs))
637
+ if (Attribute_Selector_Ptr_Const w = dynamic_cast<Attribute_Selector_Ptr_Const>(&rhs))
573
638
  {
574
639
  return *this < *w;
575
640
  }
@@ -580,14 +645,30 @@ namespace Sass {
580
645
 
581
646
  bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const
582
647
  {
583
- if (is_ns_eq(ns(), rhs.ns()) && name() == rhs.name())
584
- { return matcher() == rhs.matcher() && value() == rhs.value(); }
585
- else return false;
648
+ // get optional value state
649
+ bool no_lhs_val = value().isNull();
650
+ bool no_rhs_val = rhs.value().isNull();
651
+ // both are null, therefore equal
652
+ if (no_lhs_val && no_rhs_val) {
653
+ return (name() == rhs.name())
654
+ && (matcher() == rhs.matcher())
655
+ && (is_ns_eq(ns(), rhs.ns()));
656
+ }
657
+ // both are defined, evaluate
658
+ if (no_lhs_val == no_rhs_val) {
659
+ return (name() == rhs.name())
660
+ && (matcher() == rhs.matcher())
661
+ && (is_ns_eq(ns(), rhs.ns()))
662
+ && (*value() == *rhs.value());
663
+ }
664
+ // not equal
665
+ return false;
666
+
586
667
  }
587
668
 
588
669
  bool Attribute_Selector::operator== (const Simple_Selector& rhs) const
589
670
  {
590
- if (const Attribute_Selector* w = dynamic_cast<const Attribute_Selector*>(&rhs))
671
+ if (Attribute_Selector_Ptr_Const w = dynamic_cast<Attribute_Selector_Ptr_Const>(&rhs))
591
672
  {
592
673
  return *this == *w;
593
674
  }
@@ -600,8 +681,8 @@ namespace Sass {
600
681
  {
601
682
  if (is_ns_eq(ns(), rhs.ns()) && name() == rhs.name())
602
683
  {
603
- Expression* lhs_ex = expression();
604
- Expression* rhs_ex = rhs.expression();
684
+ String_Obj lhs_ex = expression();
685
+ String_Obj rhs_ex = rhs.expression();
605
686
  if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex;
606
687
  else return lhs_ex == rhs_ex;
607
688
  }
@@ -610,7 +691,7 @@ namespace Sass {
610
691
 
611
692
  bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const
612
693
  {
613
- if (const Pseudo_Selector* w = dynamic_cast<const Pseudo_Selector*>(&rhs))
694
+ if (Pseudo_Selector_Ptr_Const w = dynamic_cast<Pseudo_Selector_Ptr_Const>(&rhs))
614
695
  {
615
696
  return *this == *w;
616
697
  }
@@ -622,7 +703,12 @@ namespace Sass {
622
703
  bool Pseudo_Selector::operator< (const Pseudo_Selector& rhs) const
623
704
  {
624
705
  if (is_ns_eq(ns(), rhs.ns()) && name() == rhs.name())
625
- { return *(expression()) < *(rhs.expression()); }
706
+ {
707
+ String_Obj lhs_ex = expression();
708
+ String_Obj rhs_ex = rhs.expression();
709
+ if (rhs_ex && lhs_ex) return *lhs_ex < *rhs_ex;
710
+ else return lhs_ex < rhs_ex;
711
+ }
626
712
  if (is_ns_eq(ns(), rhs.ns()))
627
713
  { return name() < rhs.name(); }
628
714
  return ns() < rhs.ns();
@@ -630,7 +716,7 @@ namespace Sass {
630
716
 
631
717
  bool Pseudo_Selector::operator< (const Simple_Selector& rhs) const
632
718
  {
633
- if (const Pseudo_Selector* w = dynamic_cast<const Pseudo_Selector*>(&rhs))
719
+ if (Pseudo_Selector_Ptr_Const w = dynamic_cast<Pseudo_Selector_Ptr_Const>(&rhs))
634
720
  {
635
721
  return *this < *w;
636
722
  }
@@ -648,7 +734,7 @@ namespace Sass {
648
734
 
649
735
  bool Wrapped_Selector::operator== (const Simple_Selector& rhs) const
650
736
  {
651
- if (const Wrapped_Selector* w = dynamic_cast<const Wrapped_Selector*>(&rhs))
737
+ if (Wrapped_Selector_Ptr_Const w = dynamic_cast<Wrapped_Selector_Ptr_Const>(&rhs))
652
738
  {
653
739
  return *this == *w;
654
740
  }
@@ -668,7 +754,7 @@ namespace Sass {
668
754
 
669
755
  bool Wrapped_Selector::operator< (const Simple_Selector& rhs) const
670
756
  {
671
- if (const Wrapped_Selector* w = dynamic_cast<const Wrapped_Selector*>(&rhs))
757
+ if (Wrapped_Selector_Ptr_Const w = dynamic_cast<Wrapped_Selector_Ptr_Const>(&rhs))
672
758
  {
673
759
  return *this < *w;
674
760
  }
@@ -677,40 +763,40 @@ namespace Sass {
677
763
  return ns() < rhs.ns();
678
764
  }
679
765
 
680
- bool Wrapped_Selector::is_superselector_of(Wrapped_Selector* sub)
766
+ bool Wrapped_Selector::is_superselector_of(Wrapped_Selector_Obj sub)
681
767
  {
682
768
  if (this->name() != sub->name()) return false;
683
769
  if (this->name() == ":current") return false;
684
- if (CommaSequence_Selector* rhs_list = dynamic_cast<CommaSequence_Selector*>(sub->selector())) {
685
- if (CommaSequence_Selector* lhs_list = dynamic_cast<CommaSequence_Selector*>(selector())) {
770
+ if (Selector_List_Obj rhs_list = SASS_MEMORY_CAST(Selector_List, sub->selector())) {
771
+ if (Selector_List_Obj lhs_list = SASS_MEMORY_CAST(Selector_List, selector())) {
686
772
  return lhs_list->is_superselector_of(rhs_list);
687
773
  }
688
- error("is_superselector expected a CommaSequence_Selector", sub->pstate());
774
+ error("is_superselector expected a Selector_List", sub->pstate());
689
775
  } else {
690
- error("is_superselector expected a CommaSequence_Selector", sub->pstate());
776
+ error("is_superselector expected a Selector_List", sub->pstate());
691
777
  }
692
778
  return false;
693
779
  }
694
780
 
695
- bool SimpleSequence_Selector::is_superselector_of(CommaSequence_Selector* rhs, std::string wrapped)
781
+ bool Compound_Selector::is_superselector_of(Selector_List_Obj rhs, std::string wrapped)
696
782
  {
697
- for (Sequence_Selector* item : rhs->elements()) {
698
- if (is_superselector_of(item, wrapped)) return true;
783
+ for (Complex_Selector_Obj item : rhs->elements()) {
784
+ if (is_superselector_of(&item, wrapped)) return true;
699
785
  }
700
786
  return false;
701
787
  }
702
788
 
703
- bool SimpleSequence_Selector::is_superselector_of(Sequence_Selector* rhs, std::string wrapped)
789
+ bool Compound_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapped)
704
790
  {
705
- if (rhs->head()) return is_superselector_of(rhs->head(), wrapped);
791
+ if (rhs->head()) return is_superselector_of(&rhs->head(), wrapped);
706
792
  return false;
707
793
  }
708
794
 
709
- bool SimpleSequence_Selector::is_superselector_of(SimpleSequence_Selector* rhs, std::string wrapping)
795
+ bool Compound_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping)
710
796
  {
711
- SimpleSequence_Selector* lhs = this;
712
- Simple_Selector* lbase = lhs->base();
713
- Simple_Selector* rbase = rhs->base();
797
+ Compound_Selector_Ptr lhs = this;
798
+ Simple_Selector_Ptr lbase = lhs->base();
799
+ Simple_Selector_Ptr rbase = rhs->base();
714
800
 
715
801
  // Check if pseudo-elements are the same between the selectors
716
802
 
@@ -751,11 +837,11 @@ namespace Sass {
751
837
 
752
838
  for (size_t i = 0, iL = length(); i < iL; ++i)
753
839
  {
754
- Selector* lhs = (*this)[i];
840
+ Selector_Obj lhs = &(*this)[i];
755
841
  // very special case for wrapped matches selector
756
- if (Wrapped_Selector* wrapped = dynamic_cast<Wrapped_Selector*>(lhs)) {
842
+ if (Wrapped_Selector_Obj wrapped = SASS_MEMORY_CAST(Wrapped_Selector, lhs)) {
757
843
  if (wrapped->name() == ":not") {
758
- if (CommaSequence_Selector* not_list = dynamic_cast<CommaSequence_Selector*>(wrapped->selector())) {
844
+ if (Selector_List_Obj not_list = SASS_MEMORY_CAST(Selector_List, wrapped->selector())) {
759
845
  if (not_list->is_superselector_of(rhs, wrapped->name())) return false;
760
846
  } else {
761
847
  throw std::runtime_error("wrapped not selector is not a list");
@@ -763,8 +849,8 @@ namespace Sass {
763
849
  }
764
850
  if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
765
851
  lhs = wrapped->selector();
766
- if (CommaSequence_Selector* list = dynamic_cast<CommaSequence_Selector*>(wrapped->selector())) {
767
- if (SimpleSequence_Selector* comp = dynamic_cast<SimpleSequence_Selector*>(rhs)) {
852
+ if (Selector_List_Obj list = SASS_MEMORY_CAST(Selector_List, wrapped->selector())) {
853
+ if (Compound_Selector_Obj comp = SASS_MEMORY_CAST(Compound_Selector, rhs)) {
768
854
  if (!wrapping.empty() && wrapping != wrapped->name()) return false;
769
855
  if (wrapping.empty() || wrapping != wrapped->name()) {;
770
856
  if (list->is_superselector_of(comp, wrapped->name())) return true;
@@ -772,8 +858,8 @@ namespace Sass {
772
858
  }
773
859
  }
774
860
  }
775
- Simple_Selector* rhs_sel = rhs->elements().size() > i ? (*rhs)[i] : 0;
776
- if (Wrapped_Selector* wrapped_r = dynamic_cast<Wrapped_Selector*>(rhs_sel)) {
861
+ Simple_Selector_Ptr rhs_sel = rhs->elements().size() > i ? &(*rhs)[i] : 0;
862
+ if (Wrapped_Selector_Ptr wrapped_r = dynamic_cast<Wrapped_Selector_Ptr>(rhs_sel)) {
777
863
  if (wrapped->name() == wrapped_r->name()) {
778
864
  if (wrapped->is_superselector_of(wrapped_r)) {
779
865
  continue;
@@ -788,10 +874,10 @@ namespace Sass {
788
874
 
789
875
  for (size_t n = 0, nL = rhs->length(); n < nL; ++n)
790
876
  {
791
- auto r = (*rhs)[n];
792
- if (Wrapped_Selector* wrapped = dynamic_cast<Wrapped_Selector*>(r)) {
877
+ Selector_Obj r = &(*rhs)[n];
878
+ if (Wrapped_Selector_Obj wrapped = SASS_MEMORY_CAST(Wrapped_Selector, r)) {
793
879
  if (wrapped->name() == ":not") {
794
- if (CommaSequence_Selector* ls = dynamic_cast<CommaSequence_Selector*>(wrapped->selector())) {
880
+ if (Selector_List_Obj ls = SASS_MEMORY_CAST(Selector_List, wrapped->selector())) {
795
881
  ls->remove_parent_selectors();
796
882
  if (is_superselector_of(ls, wrapped->name())) return false;
797
883
  }
@@ -800,7 +886,7 @@ namespace Sass {
800
886
  if (!wrapping.empty()) {
801
887
  if (wrapping != wrapped->name()) return false;
802
888
  }
803
- if (CommaSequence_Selector* ls = dynamic_cast<CommaSequence_Selector*>(wrapped->selector())) {
889
+ if (Selector_List_Obj ls = SASS_MEMORY_CAST(Selector_List, wrapped->selector())) {
804
890
  ls->remove_parent_selectors();
805
891
  return (is_superselector_of(ls, wrapped->name()));
806
892
  }
@@ -819,22 +905,22 @@ namespace Sass {
819
905
  }
820
906
 
821
907
  // create complex selector (ancestor of) from compound selector
822
- Sequence_Selector* SimpleSequence_Selector::to_complex(Memory_Manager& mem)
908
+ Complex_Selector_Obj Compound_Selector::to_complex()
823
909
  {
824
910
  // create an intermediate complex selector
825
- return SASS_MEMORY_NEW(mem, Sequence_Selector,
911
+ return SASS_MEMORY_NEW(Complex_Selector,
826
912
  pstate(),
827
- Sequence_Selector::ANCESTOR_OF,
913
+ Complex_Selector::ANCESTOR_OF,
828
914
  this,
829
915
  0);
830
916
  }
831
917
 
832
- CommaSequence_Selector* Sequence_Selector::unify_with(Sequence_Selector* other, Context& ctx)
918
+ Selector_List_Ptr Complex_Selector::unify_with(Complex_Selector_Ptr other, Context& ctx)
833
919
  {
834
920
 
835
921
  // get last tails (on the right side)
836
- Sequence_Selector* l_last = this->last();
837
- Sequence_Selector* r_last = other->last();
922
+ Complex_Selector_Obj l_last = this->last();
923
+ Complex_Selector_Obj r_last = other->last();
838
924
 
839
925
  // check valid pointers (assertion)
840
926
  SASS_ASSERT(l_last, "lhs is null");
@@ -847,15 +933,15 @@ namespace Sass {
847
933
  if (r_last->combinator() != Combinator::ANCESTOR_OF ) return 0;
848
934
 
849
935
  // get the headers for the last tails
850
- SimpleSequence_Selector* l_last_head = l_last->head();
851
- SimpleSequence_Selector* r_last_head = r_last->head();
936
+ Compound_Selector_Obj l_last_head = l_last->head();
937
+ Compound_Selector_Obj r_last_head = r_last->head();
852
938
 
853
939
  // check valid head pointers (assertion)
854
940
  SASS_ASSERT(l_last_head, "lhs head is null");
855
941
  SASS_ASSERT(r_last_head, "rhs head is null");
856
942
 
857
943
  // get the unification of the last compound selectors
858
- SimpleSequence_Selector* unified = r_last_head->unify_with(l_last_head, ctx);
944
+ Compound_Selector_Obj unified = r_last_head->unify_with(&l_last_head, ctx);
859
945
 
860
946
  // abort if we could not unify heads
861
947
  if (unified == 0) return 0;
@@ -879,33 +965,33 @@ namespace Sass {
879
965
  if (!is_universal)
880
966
  {
881
967
  // create some temporaries to convert to node
882
- Sequence_Selector* fake = unified->to_complex(ctx.mem);
883
- Node unified_node = complexSelectorToNode(fake, ctx);
968
+ Complex_Selector_Obj fake = unified->to_complex();
969
+ Node unified_node = complexSelectorToNode(&fake, ctx);
884
970
  // add to permutate the list?
885
971
  rhsNode.plus(unified_node);
886
972
  }
887
973
 
888
974
  // do some magic we inherit from node and extend
889
975
  Node node = Extend::subweave(lhsNode, rhsNode, ctx);
890
- CommaSequence_Selector* result = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
976
+ Selector_List_Ptr result = SASS_MEMORY_NEW(Selector_List, pstate());
891
977
  NodeDequePtr col = node.collection(); // move from collection to list
892
978
  for (NodeDeque::iterator it = col->begin(), end = col->end(); it != end; it++)
893
- { (*result) << nodeToComplexSelector(Node::naiveTrim(*it, ctx), ctx); }
979
+ { result->append(nodeToComplexSelector(Node::naiveTrim(*it, ctx), ctx)); }
894
980
 
895
981
  // only return if list has some entries
896
982
  return result->length() ? result : 0;
897
983
 
898
984
  }
899
985
 
900
- bool SimpleSequence_Selector::operator== (const SimpleSequence_Selector& rhs) const
986
+ bool Compound_Selector::operator== (const Compound_Selector& rhs) const
901
987
  {
902
988
  // for array access
903
989
  size_t i = 0, n = 0;
904
990
  size_t iL = length();
905
991
  size_t nL = rhs.length();
906
992
  // create temporary vectors and sort them
907
- std::vector<Simple_Selector*> l_lst = this->elements();
908
- std::vector<Simple_Selector*> r_lst = rhs.elements();
993
+ std::vector<Simple_Selector_Obj> l_lst = this->elements();
994
+ std::vector<Simple_Selector_Obj> r_lst = rhs.elements();
909
995
  std::sort(l_lst.begin(), l_lst.end(), cmp_simple_selector());
910
996
  std::sort(r_lst.begin(), r_lst.end(), cmp_simple_selector());
911
997
  // process loop
@@ -915,8 +1001,8 @@ namespace Sass {
915
1001
  if (i == iL) return iL == nL;
916
1002
  else if (n == nL) return iL == nL;
917
1003
  // the access the vector items
918
- Simple_Selector* l = l_lst[i];
919
- Simple_Selector* r = r_lst[n];
1004
+ Simple_Selector_Obj l = l_lst[i];
1005
+ Simple_Selector_Obj r = r_lst[n];
920
1006
  // skip nulls
921
1007
  if (!l) ++i;
922
1008
  if (!r) ++n;
@@ -930,26 +1016,26 @@ namespace Sass {
930
1016
  return true;
931
1017
  }
932
1018
 
933
- bool Sequence_Selector_Pointer_Compare::operator() (const Sequence_Selector* const pLeft, const Sequence_Selector* const pRight) const {
1019
+ bool Complex_Selector_Pointer_Compare::operator() (const Complex_Selector_Obj& pLeft, const Complex_Selector_Obj& pRight) const {
934
1020
  return *pLeft < *pRight;
935
1021
  }
936
1022
 
937
- bool Sequence_Selector::is_superselector_of(SimpleSequence_Selector* rhs, std::string wrapping)
1023
+ bool Complex_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping)
938
1024
  {
939
1025
  return last()->head() && last()->head()->is_superselector_of(rhs, wrapping);
940
1026
  }
941
1027
 
942
- bool Sequence_Selector::is_superselector_of(Sequence_Selector* rhs, std::string wrapping)
1028
+ bool Complex_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapping)
943
1029
  {
944
- Sequence_Selector* lhs = this;
1030
+ Complex_Selector_Ptr lhs = this;
945
1031
  // check for selectors with leading or trailing combinators
946
1032
  if (!lhs->head() || !rhs->head())
947
1033
  { return false; }
948
- const Sequence_Selector* l_innermost = lhs->innermost();
949
- if (l_innermost->combinator() != Sequence_Selector::ANCESTOR_OF)
1034
+ Complex_Selector_Obj l_innermost = lhs->innermost();
1035
+ if (l_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
950
1036
  { return false; }
951
- const Sequence_Selector* r_innermost = rhs->innermost();
952
- if (r_innermost->combinator() != Sequence_Selector::ANCESTOR_OF)
1037
+ Complex_Selector_Obj r_innermost = rhs->innermost();
1038
+ if (r_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
953
1039
  { return false; }
954
1040
  // more complex (i.e., longer) selectors are always more specific
955
1041
  size_t l_len = lhs->length(), r_len = rhs->length();
@@ -957,27 +1043,27 @@ namespace Sass {
957
1043
  { return false; }
958
1044
 
959
1045
  if (l_len == 1)
960
- { return lhs->head()->is_superselector_of(rhs->last()->head(), wrapping); }
1046
+ { return lhs->head()->is_superselector_of(&rhs->last()->head(), wrapping); }
961
1047
 
962
1048
  // we have to look one tail deeper, since we cary the
963
1049
  // combinator around for it (which is important here)
964
- if (rhs->tail() && lhs->tail() && combinator() != Sequence_Selector::ANCESTOR_OF) {
965
- Sequence_Selector* lhs_tail = lhs->tail();
966
- Sequence_Selector* rhs_tail = rhs->tail();
1050
+ if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) {
1051
+ Complex_Selector_Obj lhs_tail = lhs->tail();
1052
+ Complex_Selector_Obj rhs_tail = rhs->tail();
967
1053
  if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
968
1054
  if (lhs_tail->head() && !rhs_tail->head()) return false;
969
1055
  if (!lhs_tail->head() && rhs_tail->head()) return false;
970
1056
  if (lhs_tail->head() && rhs_tail->head()) {
971
- if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false;
1057
+ if (!lhs_tail->head()->is_superselector_of(&rhs_tail->head())) return false;
972
1058
  }
973
1059
  }
974
1060
 
975
1061
  bool found = false;
976
- Sequence_Selector* marker = rhs;
1062
+ Complex_Selector_Obj marker = rhs;
977
1063
  for (size_t i = 0, L = rhs->length(); i < L; ++i) {
978
1064
  if (i == L-1)
979
1065
  { return false; }
980
- if (lhs->head() && marker->head() && lhs->head()->is_superselector_of(marker->head(), wrapping))
1066
+ if (lhs->head() && marker->head() && lhs->head()->is_superselector_of(&marker->head(), wrapping))
981
1067
  { found = true; break; }
982
1068
  marker = marker->tail();
983
1069
  }
@@ -997,40 +1083,40 @@ namespace Sass {
997
1083
  else
998
1084
  return lhs.tail.is_superselector_of(marker.tail)
999
1085
  */
1000
- if (lhs->combinator() != Sequence_Selector::ANCESTOR_OF)
1086
+ if (lhs->combinator() != Complex_Selector::ANCESTOR_OF)
1001
1087
  {
1002
- if (marker->combinator() == Sequence_Selector::ANCESTOR_OF)
1088
+ if (marker->combinator() == Complex_Selector::ANCESTOR_OF)
1003
1089
  { return false; }
1004
- if (!(lhs->combinator() == Sequence_Selector::PRECEDES ? marker->combinator() != Sequence_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
1090
+ if (!(lhs->combinator() == Complex_Selector::PRECEDES ? marker->combinator() != Complex_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
1005
1091
  { return false; }
1006
- return lhs->tail()->is_superselector_of(marker->tail());
1092
+ return lhs->tail()->is_superselector_of(&marker->tail());
1007
1093
  }
1008
- else if (marker->combinator() != Sequence_Selector::ANCESTOR_OF)
1094
+ else if (marker->combinator() != Complex_Selector::ANCESTOR_OF)
1009
1095
  {
1010
- if (marker->combinator() != Sequence_Selector::PARENT_OF)
1096
+ if (marker->combinator() != Complex_Selector::PARENT_OF)
1011
1097
  { return false; }
1012
- return lhs->tail()->is_superselector_of(marker->tail());
1098
+ return lhs->tail()->is_superselector_of(&marker->tail());
1013
1099
  }
1014
1100
  else
1015
1101
  {
1016
- return lhs->tail()->is_superselector_of(marker->tail());
1102
+ return lhs->tail()->is_superselector_of(&marker->tail());
1017
1103
  }
1018
1104
  // catch-all
1019
1105
  return false;
1020
1106
  }
1021
1107
 
1022
- size_t Sequence_Selector::length() const
1108
+ size_t Complex_Selector::length() const
1023
1109
  {
1024
1110
  // TODO: make this iterative
1025
1111
  if (!tail()) return 1;
1026
1112
  return 1 + tail()->length();
1027
1113
  }
1028
1114
 
1029
- Sequence_Selector* Sequence_Selector::context(Context& ctx)
1115
+ Complex_Selector_Obj Complex_Selector::context(Context& ctx)
1030
1116
  {
1031
1117
  if (!tail()) return 0;
1032
1118
  if (!head()) return tail()->context(ctx);
1033
- Sequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, pstate(), combinator(), head(), tail()->context(ctx));
1119
+ Complex_Selector_Obj cpy = SASS_MEMORY_NEW(Complex_Selector, pstate(), combinator(), head(), tail()->context(ctx));
1034
1120
  cpy->media_block(media_block());
1035
1121
  return cpy;
1036
1122
  }
@@ -1039,13 +1125,13 @@ namespace Sass {
1039
1125
  // check if we need to append some headers
1040
1126
  // then we need to check for the combinator
1041
1127
  // only then we can safely set the new tail
1042
- void Sequence_Selector::append(Context& ctx, Sequence_Selector* ss)
1128
+ void Complex_Selector::append(Context& ctx, Complex_Selector_Obj ss)
1043
1129
  {
1044
1130
 
1045
- Sequence_Selector* t = ss->tail();
1131
+ Complex_Selector_Obj t = ss->tail();
1046
1132
  Combinator c = ss->combinator();
1047
- String* r = ss->reference();
1048
- SimpleSequence_Selector* h = ss->head();
1133
+ String_Obj r = ss->reference();
1134
+ Compound_Selector_Obj h = ss->head();
1049
1135
 
1050
1136
  if (ss->has_line_feed()) has_line_feed(true);
1051
1137
  if (ss->has_line_break()) has_line_break(true);
@@ -1055,45 +1141,45 @@ namespace Sass {
1055
1141
  if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
1056
1142
  error("Invalid parent selector", pstate_);
1057
1143
  } else if (last()->head_ && last()->head_->length()) {
1058
- SimpleSequence_Selector* rh = last()->head();
1144
+ Compound_Selector_Obj rh = last()->head();
1059
1145
  size_t i = 0, L = h->length();
1060
- if (dynamic_cast<Element_Selector*>(h->first())) {
1061
- if (Class_Selector* sq = dynamic_cast<Class_Selector*>(rh->last())) {
1062
- Class_Selector* sqs = SASS_MEMORY_NEW(ctx.mem, Class_Selector, *sq);
1146
+ if (SASS_MEMORY_CAST(Element_Selector, h->first())) {
1147
+ if (Class_Selector_Ptr sq = SASS_MEMORY_CAST(Class_Selector, rh->last())) {
1148
+ Class_Selector_Ptr sqs = SASS_MEMORY_COPY(sq);
1063
1149
  sqs->name(sqs->name() + (*h)[0]->name());
1064
1150
  sqs->pstate((*h)[0]->pstate());
1065
1151
  (*rh)[rh->length()-1] = sqs;
1066
1152
  rh->pstate(h->pstate());
1067
- for (i = 1; i < L; ++i) *rh << (*h)[i];
1068
- } else if (Id_Selector* sq = dynamic_cast<Id_Selector*>(rh->last())) {
1069
- Id_Selector* sqs = SASS_MEMORY_NEW(ctx.mem, Id_Selector, *sq);
1153
+ for (i = 1; i < L; ++i) rh->append(&(*h)[i]);
1154
+ } else if (Id_Selector_Ptr sq = SASS_MEMORY_CAST(Id_Selector, rh->last())) {
1155
+ Id_Selector_Ptr sqs = SASS_MEMORY_COPY(sq);
1070
1156
  sqs->name(sqs->name() + (*h)[0]->name());
1071
1157
  sqs->pstate((*h)[0]->pstate());
1072
1158
  (*rh)[rh->length()-1] = sqs;
1073
1159
  rh->pstate(h->pstate());
1074
- for (i = 1; i < L; ++i) *rh << (*h)[i];
1075
- } else if (Element_Selector* ts = dynamic_cast<Element_Selector*>(rh->last())) {
1076
- Element_Selector* tss = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *ts);
1160
+ for (i = 1; i < L; ++i) rh->append(&(*h)[i]);
1161
+ } else if (Element_Selector_Ptr ts = SASS_MEMORY_CAST(Element_Selector, rh->last())) {
1162
+ Element_Selector_Ptr tss = SASS_MEMORY_COPY(ts);
1077
1163
  tss->name(tss->name() + (*h)[0]->name());
1078
1164
  tss->pstate((*h)[0]->pstate());
1079
1165
  (*rh)[rh->length()-1] = tss;
1080
1166
  rh->pstate(h->pstate());
1081
- for (i = 1; i < L; ++i) *rh << (*h)[i];
1082
- } else if (Placeholder_Selector* ps = dynamic_cast<Placeholder_Selector*>(rh->last())) {
1083
- Placeholder_Selector* pss = SASS_MEMORY_NEW(ctx.mem, Placeholder_Selector, *ps);
1167
+ for (i = 1; i < L; ++i) rh->append(&(*h)[i]);
1168
+ } else if (Placeholder_Selector_Ptr ps = SASS_MEMORY_CAST(Placeholder_Selector, rh->last())) {
1169
+ Placeholder_Selector_Ptr pss = SASS_MEMORY_COPY(ps);
1084
1170
  pss->name(pss->name() + (*h)[0]->name());
1085
1171
  pss->pstate((*h)[0]->pstate());
1086
1172
  (*rh)[rh->length()-1] = pss;
1087
1173
  rh->pstate(h->pstate());
1088
- for (i = 1; i < L; ++i) *rh << (*h)[i];
1174
+ for (i = 1; i < L; ++i) rh->append(&(*h)[i]);
1089
1175
  } else {
1090
- *last()->head_ += h;
1176
+ last()->head_->concat(&h);
1091
1177
  }
1092
1178
  } else {
1093
- *last()->head_ += h;
1179
+ last()->head_->concat(&h);
1094
1180
  }
1095
1181
  } else {
1096
- *last()->head_ += h;
1182
+ last()->head_->concat(&h);
1097
1183
  }
1098
1184
  } else {
1099
1185
  // std::cerr << "has no or empty head\n";
@@ -1101,7 +1187,7 @@ namespace Sass {
1101
1187
 
1102
1188
  if (last()) {
1103
1189
  if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
1104
- Sequence_Selector* inter = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, pstate());
1190
+ Complex_Selector_Ptr inter = SASS_MEMORY_NEW(Complex_Selector, pstate());
1105
1191
  inter->reference(r);
1106
1192
  inter->combinator(c);
1107
1193
  inter->tail(t);
@@ -1118,57 +1204,68 @@ namespace Sass {
1118
1204
 
1119
1205
  }
1120
1206
 
1121
- CommaSequence_Selector* CommaSequence_Selector::resolve_parent_refs(Context& ctx, CommaSequence_Selector* ps, bool implicit_parent)
1207
+ Selector_List_Ptr Selector_List::resolve_parent_refs(Context& ctx, std::vector<Selector_List_Obj>& pstack, bool implicit_parent)
1122
1208
  {
1123
- if (!this->has_parent_ref()/* && !implicit_parent*/) return this;
1124
- CommaSequence_Selector* ss = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
1209
+ if (!this->has_parent_ref()) return this;
1210
+ Selector_List_Ptr ss = SASS_MEMORY_NEW(Selector_List, pstate());
1211
+ Selector_List_Ptr ps = &pstack.back();
1125
1212
  for (size_t pi = 0, pL = ps->length(); pi < pL; ++pi) {
1126
- CommaSequence_Selector* list = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
1127
- *list << (*ps)[pi];
1128
1213
  for (size_t si = 0, sL = this->length(); si < sL; ++si) {
1129
- *ss += (*this)[si]->resolve_parent_refs(ctx, list, implicit_parent);
1214
+ Selector_List_Obj rv = at(si)->resolve_parent_refs(ctx, pstack, implicit_parent);
1215
+ ss->concat(&rv);
1130
1216
  }
1131
1217
  }
1132
1218
  return ss;
1133
1219
  }
1134
1220
 
1135
- CommaSequence_Selector* Sequence_Selector::resolve_parent_refs(Context& ctx, CommaSequence_Selector* parents, bool implicit_parent)
1221
+ Selector_List_Ptr Complex_Selector::resolve_parent_refs(Context& ctx, std::vector<Selector_List_Obj>& pstack, bool implicit_parent)
1136
1222
  {
1137
- Sequence_Selector* tail = this->tail();
1138
- SimpleSequence_Selector* head = this->head();
1223
+ Complex_Selector_Obj tail = this->tail();
1224
+ Compound_Selector_Obj head = this->head();
1225
+ Selector_List_Ptr parents = &pstack.back();
1139
1226
 
1140
1227
  if (!this->has_real_parent_ref() && !implicit_parent) {
1141
- CommaSequence_Selector* retval = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
1142
- *retval << this;
1228
+ Selector_List_Ptr retval = SASS_MEMORY_NEW(Selector_List, pstate());
1229
+ retval->append(this);
1143
1230
  return retval;
1144
1231
  }
1145
1232
 
1146
1233
  // first resolve_parent_refs the tail (which may return an expanded list)
1147
- CommaSequence_Selector* tails = tail ? tail->resolve_parent_refs(ctx, parents, implicit_parent) : 0;
1234
+ Selector_List_Obj tails = tail ? tail->resolve_parent_refs(ctx, pstack, implicit_parent) : 0;
1148
1235
 
1149
1236
  if (head && head->length() > 0) {
1150
1237
 
1151
- CommaSequence_Selector* retval = 0;
1238
+ Selector_List_Obj retval;
1152
1239
  // we have a parent selector in a simple compound list
1153
1240
  // mix parent complex selector into the compound list
1154
- if (dynamic_cast<Parent_Selector*>((*head)[0])) {
1155
- retval = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
1241
+ if (SASS_MEMORY_CAST(Parent_Selector, (*head)[0])) {
1242
+ retval = SASS_MEMORY_NEW(Selector_List, pstate());
1243
+
1244
+ // it turns out that real parent references reach
1245
+ // across @at-root rules, which comes unexpected
1246
+ if (parents == NULL && head->has_real_parent_ref()) {
1247
+ int i = pstack.size() - 1;
1248
+ while (!parents && i > -1) {
1249
+ parents = &pstack.at(i--);
1250
+ }
1251
+ }
1252
+
1156
1253
  if (parents && parents->length()) {
1157
1254
  if (tails && tails->length() > 0) {
1158
1255
  for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
1159
1256
  for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
1160
- Sequence_Selector* t = (*tails)[n];
1161
- Sequence_Selector* parent = (*parents)[i];
1162
- Sequence_Selector* s = parent->cloneFully(ctx);
1163
- Sequence_Selector* ss = this->clone(ctx);
1164
- ss->tail(t ? t->clone(ctx) : 0);
1165
- SimpleSequence_Selector* h = head_->clone(ctx);
1257
+ Complex_Selector_Obj t = (*tails)[n];
1258
+ Complex_Selector_Obj parent = (*parents)[i];
1259
+ Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
1260
+ Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
1261
+ ss->tail(t ? SASS_MEMORY_CLONE(t) : 0);
1262
+ Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
1166
1263
  // remove parent selector from sequence
1167
1264
  if (h->length()) h->erase(h->begin());
1168
- ss->head(h->length() ? h : 0);
1265
+ ss->head(h->length() ? &h : 0);
1169
1266
  // adjust for parent selector (1 char)
1170
1267
  if (h->length()) {
1171
- ParserState state((*h)[0]->pstate());
1268
+ ParserState state(h->at(0)->pstate());
1172
1269
  state.offset.column += 1;
1173
1270
  state.column -= 1;
1174
1271
  (*h)[0]->pstate(state);
@@ -1177,7 +1274,7 @@ namespace Sass {
1177
1274
  s->pstate(pstate());
1178
1275
  // append new tail
1179
1276
  s->append(ctx, ss);
1180
- *retval << s;
1277
+ retval->append(s);
1181
1278
  }
1182
1279
  }
1183
1280
  }
@@ -1185,24 +1282,24 @@ namespace Sass {
1185
1282
  // loop above is inside out
1186
1283
  else {
1187
1284
  for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
1188
- Sequence_Selector* parent = (*parents)[i];
1189
- Sequence_Selector* s = parent->cloneFully(ctx);
1190
- Sequence_Selector* ss = this->clone(ctx);
1285
+ Complex_Selector_Obj parent = (*parents)[i];
1286
+ Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
1287
+ Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
1191
1288
  // this is only if valid if the parent has no trailing op
1192
1289
  // otherwise we cannot append more simple selectors to head
1193
1290
  if (parent->last()->combinator() != ANCESTOR_OF) {
1194
- throw Exception::InvalidParent(parent, ss);
1291
+ throw Exception::InvalidParent(&parent, &ss);
1195
1292
  }
1196
- ss->tail(tail ? tail->clone(ctx) : 0);
1197
- SimpleSequence_Selector* h = head_->clone(ctx);
1293
+ ss->tail(tail ? SASS_MEMORY_CLONE(tail) : 0);
1294
+ Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
1198
1295
  // remove parent selector from sequence
1199
1296
  if (h->length()) h->erase(h->begin());
1200
- ss->head(h->length() ? h : 0);
1297
+ ss->head(h->length() ? &h : 0);
1201
1298
  // \/ IMO ruby sass bug \/
1202
1299
  ss->has_line_feed(false);
1203
1300
  // adjust for parent selector (1 char)
1204
1301
  if (h->length()) {
1205
- ParserState state((*h)[0]->pstate());
1302
+ ParserState state(h->at(0)->pstate());
1206
1303
  state.offset.column += 1;
1207
1304
  state.column -= 1;
1208
1305
  (*h)[0]->pstate(state);
@@ -1210,8 +1307,8 @@ namespace Sass {
1210
1307
  // keep old parser state
1211
1308
  s->pstate(pstate());
1212
1309
  // append new tail
1213
- s->append(ctx, ss);
1214
- *retval << s;
1310
+ s->append(ctx, &ss);
1311
+ retval->append(s);
1215
1312
  }
1216
1313
  }
1217
1314
  }
@@ -1219,129 +1316,97 @@ namespace Sass {
1219
1316
  else {
1220
1317
  if (tails && tails->length() > 0) {
1221
1318
  for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
1222
- Sequence_Selector* cpy = this->clone(ctx);
1223
- cpy->tail((*tails)[n]->cloneFully(ctx));
1224
- cpy->head(SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, head->pstate()));
1319
+ Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
1320
+ cpy->tail(SASS_MEMORY_CLONE(tails->at(n)));
1321
+ cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
1225
1322
  for (size_t i = 1, L = this->head()->length(); i < L; ++i)
1226
- *cpy->head() << (*this->head())[i];
1323
+ cpy->head()->append(&(*this->head())[i]);
1227
1324
  if (!cpy->head()->length()) cpy->head(0);
1228
- *retval << cpy->skip_empty_reference();
1325
+ retval->append(cpy->skip_empty_reference());
1229
1326
  }
1230
1327
  }
1231
1328
  // have no parent nor tails
1232
1329
  else {
1233
- Sequence_Selector* cpy = this->clone(ctx);
1234
- cpy->head(SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, head->pstate()));
1330
+ Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
1331
+ cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
1235
1332
  for (size_t i = 1, L = this->head()->length(); i < L; ++i)
1236
- *cpy->head() << (*this->head())[i];
1333
+ cpy->head()->append(&(*this->head())[i]);
1237
1334
  if (!cpy->head()->length()) cpy->head(0);
1238
- *retval << cpy->skip_empty_reference();
1335
+ retval->append(cpy->skip_empty_reference());
1239
1336
  }
1240
1337
  }
1241
1338
  }
1242
1339
  // no parent selector in head
1243
1340
  else {
1244
- retval = this->tails(ctx, tails);
1341
+ retval = this->tails(ctx, &tails);
1245
1342
  }
1246
1343
 
1247
- for (Simple_Selector* ss : *head) {
1248
- if (Wrapped_Selector* ws = dynamic_cast<Wrapped_Selector*>(ss)) {
1249
- if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(ws->selector())) {
1250
- if (parents) ws->selector(sl->resolve_parent_refs(ctx, parents, implicit_parent));
1344
+ for (Simple_Selector_Obj ss : head->elements()) {
1345
+ if (Wrapped_Selector_Ptr ws = SASS_MEMORY_CAST(Wrapped_Selector, ss)) {
1346
+ if (Selector_List_Ptr sl = SASS_MEMORY_CAST(Selector_List, ws->selector())) {
1347
+ if (parents) ws->selector(sl->resolve_parent_refs(ctx, pstack, implicit_parent));
1251
1348
  }
1252
1349
  }
1253
1350
  }
1254
1351
 
1255
- return retval;
1352
+ return retval.detach();
1256
1353
 
1257
1354
  }
1258
1355
  // has no head
1259
1356
  else {
1260
- return this->tails(ctx, tails);
1357
+ return this->tails(ctx, &tails);
1261
1358
  }
1262
1359
 
1263
1360
  // unreachable
1264
1361
  return 0;
1265
1362
  }
1266
1363
 
1267
- CommaSequence_Selector* Sequence_Selector::tails(Context& ctx, CommaSequence_Selector* tails)
1364
+ Selector_List_Ptr Complex_Selector::tails(Context& ctx, Selector_List_Ptr tails)
1268
1365
  {
1269
- CommaSequence_Selector* rv = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate_);
1366
+ Selector_List_Ptr rv = SASS_MEMORY_NEW(Selector_List, pstate_);
1270
1367
  if (tails && tails->length()) {
1271
1368
  for (size_t i = 0, iL = tails->length(); i < iL; ++i) {
1272
- Sequence_Selector* pr = this->clone(ctx);
1273
- pr->tail((*tails)[i]);
1274
- *rv << pr;
1369
+ Complex_Selector_Obj pr = SASS_MEMORY_CLONE(this);
1370
+ pr->tail(tails->at(i));
1371
+ rv->append(pr);
1275
1372
  }
1276
1373
  }
1277
1374
  else {
1278
- *rv << this;
1375
+ rv->append(this);
1279
1376
  }
1280
1377
  return rv;
1281
1378
  }
1282
1379
 
1283
1380
  // return the last tail that is defined
1284
- Sequence_Selector* Sequence_Selector::first()
1381
+ Complex_Selector_Obj Complex_Selector::first()
1285
1382
  {
1286
1383
  // declare variables used in loop
1287
- Sequence_Selector* cur = this;
1288
- const SimpleSequence_Selector* head;
1384
+ Complex_Selector_Obj cur = this;
1385
+ Compound_Selector_Obj head;
1289
1386
  // processing loop
1290
1387
  while (cur)
1291
1388
  {
1292
1389
  // get the head
1293
1390
  head = cur->head_;
1294
1391
  // abort (and return) if it is not a parent selector
1295
- if (!head || head->length() != 1 || !dynamic_cast<Parent_Selector*>((*head)[0])) {
1392
+ if (!head || head->length() != 1 || !SASS_MEMORY_CAST(Parent_Selector, (*head)[0])) {
1296
1393
  break;
1297
1394
  }
1298
1395
  // advance to next
1299
1396
  cur = cur->tail_;
1300
1397
  }
1301
1398
  // result
1302
- return cur;
1303
- }
1304
-
1305
- // return the last tail that is defined
1306
- const Sequence_Selector* Sequence_Selector::first() const
1307
- {
1308
- // declare variables used in loop
1309
- const Sequence_Selector* cur = this->tail_;
1310
- const SimpleSequence_Selector* head = head_;
1311
- // processing loop
1312
- while (cur)
1313
- {
1314
- // get the head
1315
- head = cur->head_;
1316
- // check for single parent ref
1317
- if (head && head->length() == 1)
1318
- {
1319
- // abort (and return) if it is not a parent selector
1320
- if (!dynamic_cast<Parent_Selector*>((*head)[0])) break;
1321
- }
1322
- // advance to next
1323
- cur = cur->tail_;
1324
- }
1325
- // result
1326
- return cur;
1399
+ return &cur;
1327
1400
  }
1328
1401
 
1329
1402
  // return the last tail that is defined
1330
- Sequence_Selector* Sequence_Selector::last()
1403
+ Complex_Selector_Obj Complex_Selector::last()
1331
1404
  {
1332
1405
  // ToDo: implement with a while loop
1333
1406
  return tail_? tail_->last() : this;
1334
1407
  }
1335
1408
 
1336
- // return the last tail that is defined
1337
- const Sequence_Selector* Sequence_Selector::last() const
1338
- {
1339
- // ToDo: implement with a while loop
1340
- return tail_? tail_->last() : this;
1341
- }
1342
-
1343
-
1344
- Sequence_Selector::Combinator Sequence_Selector::clear_innermost()
1409
+ Complex_Selector::Combinator Complex_Selector::clear_innermost()
1345
1410
  {
1346
1411
  Combinator c;
1347
1412
  if (!tail() || tail()->tail() == 0)
@@ -1351,7 +1416,7 @@ namespace Sass {
1351
1416
  return c;
1352
1417
  }
1353
1418
 
1354
- void Sequence_Selector::set_innermost(Sequence_Selector* val, Combinator c)
1419
+ void Complex_Selector::set_innermost(Complex_Selector_Obj val, Combinator c)
1355
1420
  {
1356
1421
  if (!tail())
1357
1422
  { tail(val); combinator(c); }
@@ -1359,76 +1424,42 @@ namespace Sass {
1359
1424
  { tail()->set_innermost(val, c); }
1360
1425
  }
1361
1426
 
1362
- Sequence_Selector* Sequence_Selector::clone(Context& ctx) const
1427
+ void Complex_Selector::cloneChildren()
1363
1428
  {
1364
- Sequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, *this);
1365
- cpy->is_optional(this->is_optional());
1366
- cpy->media_block(this->media_block());
1367
- if (tail()) cpy->tail(tail()->clone(ctx));
1368
- return cpy;
1429
+ if (head()) head(SASS_MEMORY_CLONE(head()));
1430
+ if (tail()) tail(SASS_MEMORY_CLONE(tail()));
1369
1431
  }
1370
1432
 
1371
- Sequence_Selector* Sequence_Selector::cloneFully(Context& ctx) const
1433
+ void Compound_Selector::cloneChildren()
1372
1434
  {
1373
- Sequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, *this);
1374
- cpy->is_optional(this->is_optional());
1375
- cpy->media_block(this->media_block());
1376
- if (head()) {
1377
- cpy->head(head()->clone(ctx));
1378
- }
1379
-
1380
- if (tail()) {
1381
- cpy->tail(tail()->cloneFully(ctx));
1435
+ for (size_t i = 0, l = length(); i < l; i++) {
1436
+ at(i) = SASS_MEMORY_CLONE(at(i));
1382
1437
  }
1383
-
1384
- return cpy;
1385
1438
  }
1386
1439
 
1387
- SimpleSequence_Selector* SimpleSequence_Selector::clone(Context& ctx) const
1440
+ void Selector_List::cloneChildren()
1388
1441
  {
1389
- SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, *this);
1390
- cpy->is_optional(this->is_optional());
1391
- cpy->media_block(this->media_block());
1392
- cpy->extended(this->extended());
1393
- return cpy;
1394
- }
1395
-
1396
- CommaSequence_Selector* CommaSequence_Selector::clone(Context& ctx) const
1397
- {
1398
- CommaSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, *this);
1399
- cpy->is_optional(this->is_optional());
1400
- cpy->media_block(this->media_block());
1401
- return cpy;
1402
- }
1403
-
1404
- CommaSequence_Selector* CommaSequence_Selector::cloneFully(Context& ctx) const
1405
- {
1406
- CommaSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
1407
- cpy->is_optional(this->is_optional());
1408
- cpy->media_block(this->media_block());
1409
- for (size_t i = 0, L = length(); i < L; ++i) {
1410
- *cpy << (*this)[i]->cloneFully(ctx);
1442
+ for (size_t i = 0, l = length(); i < l; i++) {
1443
+ at(i) = SASS_MEMORY_CLONE(at(i));
1411
1444
  }
1412
- return cpy;
1413
1445
  }
1414
1446
 
1415
- /* not used anymore - remove?
1416
- Placeholder_Selector* Selector::find_placeholder()
1447
+ void Wrapped_Selector::cloneChildren()
1417
1448
  {
1418
- return 0;
1419
- }*/
1449
+ selector(SASS_MEMORY_CLONE(selector()));
1450
+ }
1420
1451
 
1421
1452
  // remove parent selector references
1422
1453
  // basically unwraps parsed selectors
1423
- void CommaSequence_Selector::remove_parent_selectors()
1454
+ void Selector_List::remove_parent_selectors()
1424
1455
  {
1425
1456
  // Check every rhs selector against left hand list
1426
1457
  for(size_t i = 0, L = length(); i < L; ++i) {
1427
1458
  if (!(*this)[i]->head()) continue;
1428
1459
  if ((*this)[i]->head()->is_empty_reference()) {
1429
1460
  // simply move to the next tail if we have "no" combinator
1430
- if ((*this)[i]->combinator() == Sequence_Selector::ANCESTOR_OF) {
1431
- if ((*this)[i]->tail() != NULL) {
1461
+ if ((*this)[i]->combinator() == Complex_Selector::ANCESTOR_OF) {
1462
+ if ((*this)[i]->tail()) {
1432
1463
  if ((*this)[i]->has_line_feed()) {
1433
1464
  (*this)[i]->tail()->has_line_feed(true);
1434
1465
  }
@@ -1443,17 +1474,17 @@ namespace Sass {
1443
1474
  }
1444
1475
  }
1445
1476
 
1446
- bool CommaSequence_Selector::has_parent_ref()
1477
+ bool Selector_List::has_parent_ref()
1447
1478
  {
1448
- for (Sequence_Selector* s : *this) {
1479
+ for (Complex_Selector_Obj s : elements()) {
1449
1480
  if (s && s->has_parent_ref()) return true;
1450
1481
  }
1451
1482
  return false;
1452
1483
  }
1453
1484
 
1454
- bool CommaSequence_Selector::has_real_parent_ref()
1485
+ bool Selector_List::has_real_parent_ref()
1455
1486
  {
1456
- for (Sequence_Selector* s : *this) {
1487
+ for (Complex_Selector_Obj s : elements()) {
1457
1488
  if (s && s->has_real_parent_ref()) return true;
1458
1489
  }
1459
1490
  return false;
@@ -1461,51 +1492,51 @@ namespace Sass {
1461
1492
 
1462
1493
  bool Selector_Schema::has_parent_ref()
1463
1494
  {
1464
- if (String_Schema* schema = dynamic_cast<String_Schema*>(contents())) {
1465
- return schema->length() > 0 && dynamic_cast<Parent_Selector*>(schema->at(0)) != NULL;
1495
+ if (String_Schema_Obj schema = SASS_MEMORY_CAST(String_Schema, contents())) {
1496
+ return schema->length() > 0 && SASS_MEMORY_CAST(Parent_Selector, schema->at(0)) != NULL;
1466
1497
  }
1467
1498
  return false;
1468
1499
  }
1469
1500
 
1470
1501
  bool Selector_Schema::has_real_parent_ref()
1471
1502
  {
1472
- if (String_Schema* schema = dynamic_cast<String_Schema*>(contents())) {
1473
- Parent_Selector* p = dynamic_cast<Parent_Selector*>(schema->at(0));
1474
- return schema->length() > 0 && p != NULL && p->is_real_parent_ref();
1503
+ if (String_Schema_Obj schema = SASS_MEMORY_CAST(String_Schema, contents())) {
1504
+ Parent_Selector_Obj p = SASS_MEMORY_CAST(Parent_Selector, schema->at(0));
1505
+ return schema->length() > 0 && p && p->is_real_parent_ref();
1475
1506
  }
1476
1507
  return false;
1477
1508
  }
1478
1509
 
1479
- void CommaSequence_Selector::adjust_after_pushing(Sequence_Selector* c)
1510
+ void Selector_List::adjust_after_pushing(Complex_Selector_Obj c)
1480
1511
  {
1481
1512
  // if (c->has_reference()) has_reference(true);
1482
1513
  }
1483
1514
 
1484
1515
  // it's a superselector if every selector of the right side
1485
1516
  // list is a superselector of the given left side selector
1486
- bool Sequence_Selector::is_superselector_of(CommaSequence_Selector *sub, std::string wrapping)
1517
+ bool Complex_Selector::is_superselector_of(Selector_List_Obj sub, std::string wrapping)
1487
1518
  {
1488
1519
  // Check every rhs selector against left hand list
1489
1520
  for(size_t i = 0, L = sub->length(); i < L; ++i) {
1490
- if (!is_superselector_of((*sub)[i], wrapping)) return false;
1521
+ if (!is_superselector_of(&(*sub)[i], wrapping)) return false;
1491
1522
  }
1492
1523
  return true;
1493
1524
  }
1494
1525
 
1495
1526
  // it's a superselector if every selector of the right side
1496
1527
  // list is a superselector of the given left side selector
1497
- bool CommaSequence_Selector::is_superselector_of(CommaSequence_Selector *sub, std::string wrapping)
1528
+ bool Selector_List::is_superselector_of(Selector_List_Obj sub, std::string wrapping)
1498
1529
  {
1499
1530
  // Check every rhs selector against left hand list
1500
1531
  for(size_t i = 0, L = sub->length(); i < L; ++i) {
1501
- if (!is_superselector_of((*sub)[i], wrapping)) return false;
1532
+ if (!is_superselector_of(&(*sub)[i], wrapping)) return false;
1502
1533
  }
1503
1534
  return true;
1504
1535
  }
1505
1536
 
1506
1537
  // it's a superselector if every selector on the right side
1507
1538
  // is a superselector of any one of the left side selectors
1508
- bool CommaSequence_Selector::is_superselector_of(SimpleSequence_Selector *sub, std::string wrapping)
1539
+ bool Selector_List::is_superselector_of(Compound_Selector_Obj sub, std::string wrapping)
1509
1540
  {
1510
1541
  // Check every lhs selector against right hand
1511
1542
  for(size_t i = 0, L = length(); i < L; ++i) {
@@ -1516,7 +1547,7 @@ namespace Sass {
1516
1547
 
1517
1548
  // it's a superselector if every selector on the right side
1518
1549
  // is a superselector of any one of the left side selectors
1519
- bool CommaSequence_Selector::is_superselector_of(Sequence_Selector *sub, std::string wrapping)
1550
+ bool Selector_List::is_superselector_of(Complex_Selector_Obj sub, std::string wrapping)
1520
1551
  {
1521
1552
  // Check every lhs selector against right hand
1522
1553
  for(size_t i = 0, L = length(); i < L; ++i) {
@@ -1525,45 +1556,45 @@ namespace Sass {
1525
1556
  return false;
1526
1557
  }
1527
1558
 
1528
- CommaSequence_Selector* CommaSequence_Selector::unify_with(CommaSequence_Selector* rhs, Context& ctx) {
1529
- std::vector<Sequence_Selector*> unified_complex_selectors;
1559
+ Selector_List_Ptr Selector_List::unify_with(Selector_List_Ptr rhs, Context& ctx) {
1560
+ std::vector<Complex_Selector_Obj> unified_complex_selectors;
1530
1561
  // Unify all of children with RHS's children, storing the results in `unified_complex_selectors`
1531
1562
  for (size_t lhs_i = 0, lhs_L = length(); lhs_i < lhs_L; ++lhs_i) {
1532
- Sequence_Selector* seq1 = (*this)[lhs_i];
1563
+ Complex_Selector_Obj seq1 = (*this)[lhs_i];
1533
1564
  for(size_t rhs_i = 0, rhs_L = rhs->length(); rhs_i < rhs_L; ++rhs_i) {
1534
- Sequence_Selector* seq2 = (*rhs)[rhs_i];
1565
+ Complex_Selector_Ptr seq2 = &rhs->at(rhs_i);
1535
1566
 
1536
- CommaSequence_Selector* result = seq1->unify_with(seq2, ctx);
1567
+ Selector_List_Obj result = seq1->unify_with(seq2, ctx);
1537
1568
  if( result ) {
1538
1569
  for(size_t i = 0, L = result->length(); i < L; ++i) {
1539
- unified_complex_selectors.push_back( (*result)[i] );
1570
+ unified_complex_selectors.push_back( &(*result)[i] );
1540
1571
  }
1541
1572
  }
1542
1573
  }
1543
1574
  }
1544
1575
 
1545
- // Creates the final CommaSequence_Selector by combining all the complex selectors
1546
- CommaSequence_Selector* final_result = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
1576
+ // Creates the final Selector_List by combining all the complex selectors
1577
+ Selector_List_Ptr final_result = SASS_MEMORY_NEW(Selector_List, pstate());
1547
1578
  for (auto itr = unified_complex_selectors.begin(); itr != unified_complex_selectors.end(); ++itr) {
1548
- *final_result << *itr;
1579
+ final_result->append(*itr);
1549
1580
  }
1550
1581
  return final_result;
1551
1582
  }
1552
1583
 
1553
- void CommaSequence_Selector::populate_extends(CommaSequence_Selector* extendee, Context& ctx, ExtensionSubsetMap& extends)
1584
+ void Selector_List::populate_extends(Selector_List_Obj extendee, Context& ctx, Subset_Map& extends)
1554
1585
  {
1555
1586
 
1556
- CommaSequence_Selector* extender = this;
1587
+ Selector_List_Ptr extender = this;
1557
1588
  for (auto complex_sel : extendee->elements()) {
1558
- Sequence_Selector* c = complex_sel;
1589
+ Complex_Selector_Obj c = complex_sel;
1559
1590
 
1560
1591
 
1561
- // Ignore any parent selectors, until we find the first non Selector_Reference head
1562
- SimpleSequence_Selector* compound_sel = c->head();
1563
- Sequence_Selector* pIter = complex_sel;
1592
+ // Ignore any parent selectors, until we find the first non Selectorerence head
1593
+ Compound_Selector_Obj compound_sel = c->head();
1594
+ Complex_Selector_Obj pIter = complex_sel;
1564
1595
  while (pIter) {
1565
- SimpleSequence_Selector* pHead = pIter->head();
1566
- if (pHead && dynamic_cast<Parent_Selector*>(pHead->elements()[0]) == NULL) {
1596
+ Compound_Selector_Obj pHead = pIter->head();
1597
+ if (pHead && SASS_MEMORY_CAST(Parent_Selector, pHead->elements()[0]) == NULL) {
1567
1598
  compound_sel = pHead;
1568
1599
  break;
1569
1600
  }
@@ -1578,30 +1609,28 @@ namespace Sass {
1578
1609
  compound_sel->is_optional(extendee->is_optional());
1579
1610
 
1580
1611
  for (size_t i = 0, L = extender->length(); i < L; ++i) {
1581
- extends.put(compound_sel->to_str_vec(), std::make_pair((*extender)[i], compound_sel));
1612
+ extends.put(compound_sel, std::make_pair(&(*extender)[i], &compound_sel));
1582
1613
  }
1583
1614
  }
1584
1615
  };
1585
1616
 
1586
- std::vector<std::string> SimpleSequence_Selector::to_str_vec()
1617
+ std::vector<std::string> Compound_Selector::to_str_vec()
1587
1618
  {
1588
- std::vector<std::string> result;
1589
- result.reserve(length());
1619
+ std::vector<std::string> result(length());
1590
1620
  for (size_t i = 0, L = length(); i < L; ++i)
1591
1621
  { result.push_back((*this)[i]->to_string()); }
1592
1622
  return result;
1593
1623
  }
1594
1624
 
1595
- SimpleSequence_Selector& SimpleSequence_Selector::operator<<(Simple_Selector* element)
1625
+ void Compound_Selector::append(Simple_Selector_Ptr element)
1596
1626
  {
1597
- Vectorized<Simple_Selector*>::operator<<(element);
1627
+ Vectorized<Simple_Selector_Obj>::append(element);
1598
1628
  pstate_.offset += element->pstate().offset;
1599
- return *this;
1600
1629
  }
1601
1630
 
1602
- SimpleSequence_Selector* SimpleSequence_Selector::minus(SimpleSequence_Selector* rhs, Context& ctx)
1631
+ Compound_Selector_Ptr Compound_Selector::minus(Compound_Selector_Ptr rhs, Context& ctx)
1603
1632
  {
1604
- SimpleSequence_Selector* result = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, pstate());
1633
+ Compound_Selector_Ptr result = SASS_MEMORY_NEW(Compound_Selector, pstate());
1605
1634
  // result->has_parent_reference(has_parent_reference());
1606
1635
 
1607
1636
  // not very efficient because it needs to preserve order
@@ -1617,50 +1646,44 @@ namespace Sass {
1617
1646
  break;
1618
1647
  }
1619
1648
  }
1620
- if (!found) (*result) << (*this)[i];
1649
+ if (!found) result->append(&(*this)[i]);
1621
1650
  }
1622
1651
 
1623
1652
  return result;
1624
1653
  }
1625
1654
 
1626
- void SimpleSequence_Selector::mergeSources(SourcesSet& sources, Context& ctx)
1655
+ void Compound_Selector::mergeSources(SourcesSet& sources, Context& ctx)
1627
1656
  {
1628
1657
  for (SourcesSet::iterator iterator = sources.begin(), endIterator = sources.end(); iterator != endIterator; ++iterator) {
1629
- this->sources_.insert((*iterator)->clone(ctx));
1658
+ this->sources_.insert(SASS_MEMORY_CLONE(*iterator));
1630
1659
  }
1631
1660
  }
1632
1661
 
1633
- Argument* Arguments::get_rest_argument()
1662
+ Argument_Obj Arguments::get_rest_argument()
1634
1663
  {
1635
- Argument* arg = 0;
1636
1664
  if (this->has_rest_argument()) {
1637
- for (auto a : this->elements()) {
1638
- if (a->is_rest_argument()) {
1639
- arg = a;
1640
- break;
1665
+ for (Argument_Obj arg : this->elements()) {
1666
+ if (arg->is_rest_argument()) {
1667
+ return arg;
1641
1668
  }
1642
1669
  }
1643
1670
  }
1644
-
1645
- return arg;
1671
+ return NULL;
1646
1672
  }
1647
1673
 
1648
- Argument* Arguments::get_keyword_argument()
1674
+ Argument_Obj Arguments::get_keyword_argument()
1649
1675
  {
1650
- Argument* arg = 0;
1651
1676
  if (this->has_keyword_argument()) {
1652
- for (auto a : this->elements()) {
1653
- if (a->is_keyword_argument()) {
1654
- arg = a;
1655
- break;
1677
+ for (Argument_Obj arg : this->elements()) {
1678
+ if (arg->is_keyword_argument()) {
1679
+ return arg;
1656
1680
  }
1657
1681
  }
1658
1682
  }
1659
-
1660
- return arg;
1683
+ return NULL;
1661
1684
  }
1662
1685
 
1663
- void Arguments::adjust_after_pushing(Argument* a)
1686
+ void Arguments::adjust_after_pushing(Argument_Obj a)
1664
1687
  {
1665
1688
  if (!a->name().empty()) {
1666
1689
  if (/* has_rest_argument_ || */ has_keyword_argument_) {
@@ -1694,7 +1717,7 @@ namespace Sass {
1694
1717
  }
1695
1718
 
1696
1719
  bool Ruleset::is_invisible() const {
1697
- if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(selector())) {
1720
+ if (Selector_List_Ptr sl = SASS_MEMORY_CAST(Selector_List, selector())) {
1698
1721
  for (size_t i = 0, L = sl->length(); i < L; ++i)
1699
1722
  if (!(*sl)[i]->has_placeholder()) return false;
1700
1723
  }
@@ -1703,7 +1726,8 @@ namespace Sass {
1703
1726
 
1704
1727
  bool Media_Block::is_invisible() const {
1705
1728
  for (size_t i = 0, L = block()->length(); i < L; ++i) {
1706
- if (!(*block())[i]->is_invisible()) return false;
1729
+ Statement_Obj stm = block()->at(i);
1730
+ if (!stm->is_invisible()) return false;
1707
1731
  }
1708
1732
  return true;
1709
1733
  }
@@ -2070,7 +2094,7 @@ namespace Sass {
2070
2094
 
2071
2095
  bool Custom_Warning::operator== (const Expression& rhs) const
2072
2096
  {
2073
- if (const Custom_Warning* r = dynamic_cast<const Custom_Warning*>(&rhs)) {
2097
+ if (Custom_Warning_Ptr_Const r = dynamic_cast<Custom_Warning_Ptr_Const>(&rhs)) {
2074
2098
  return message() == r->message();
2075
2099
  }
2076
2100
  return false;
@@ -2078,7 +2102,7 @@ namespace Sass {
2078
2102
 
2079
2103
  bool Custom_Error::operator== (const Expression& rhs) const
2080
2104
  {
2081
- if (const Custom_Error* r = dynamic_cast<const Custom_Error*>(&rhs)) {
2105
+ if (Custom_Error_Ptr_Const r = dynamic_cast<Custom_Error_Ptr_Const>(&rhs)) {
2082
2106
  return message() == r->message();
2083
2107
  }
2084
2108
  return false;
@@ -2086,7 +2110,7 @@ namespace Sass {
2086
2110
 
2087
2111
  bool Number::eq (const Expression& rhs) const
2088
2112
  {
2089
- if (const Number* r = dynamic_cast<const Number*>(&rhs)) {
2113
+ if (Number_Ptr_Const r = dynamic_cast<Number_Ptr_Const>(&rhs)) {
2090
2114
  size_t lhs_units = numerator_units_.size() + denominator_units_.size();
2091
2115
  size_t rhs_units = r->numerator_units_.size() + r->denominator_units_.size();
2092
2116
  if (!lhs_units && !rhs_units) {
@@ -2101,7 +2125,7 @@ namespace Sass {
2101
2125
 
2102
2126
  bool Number::operator== (const Expression& rhs) const
2103
2127
  {
2104
- if (const Number* r = dynamic_cast<const Number*>(&rhs)) {
2128
+ if (Number_Ptr_Const r = dynamic_cast<Number_Ptr_Const>(&rhs)) {
2105
2129
  size_t lhs_units = numerator_units_.size() + denominator_units_.size();
2106
2130
  size_t rhs_units = r->numerator_units_.size() + r->denominator_units_.size();
2107
2131
  // unitless and only having one unit seems equivalent (will change in future)
@@ -2124,7 +2148,7 @@ namespace Sass {
2124
2148
  return value() < rhs.value();
2125
2149
  }
2126
2150
 
2127
- Number tmp_r(rhs);
2151
+ Number tmp_r(&rhs); // copy
2128
2152
  tmp_r.normalize(find_convertible_unit());
2129
2153
  std::string l_unit(unit());
2130
2154
  std::string r_unit(tmp_r.unit());
@@ -2136,9 +2160,9 @@ namespace Sass {
2136
2160
 
2137
2161
  bool String_Quoted::operator== (const Expression& rhs) const
2138
2162
  {
2139
- if (const String_Quoted* qstr = dynamic_cast<const String_Quoted*>(&rhs)) {
2163
+ if (String_Quoted_Ptr_Const qstr = dynamic_cast<String_Quoted_Ptr_Const>(&rhs)) {
2140
2164
  return (value() == qstr->value());
2141
- } else if (const String_Constant* cstr = dynamic_cast<const String_Constant*>(&rhs)) {
2165
+ } else if (String_Constant_Ptr_Const cstr = dynamic_cast<String_Constant_Ptr_Const>(&rhs)) {
2142
2166
  return (value() == cstr->value());
2143
2167
  }
2144
2168
  return false;
@@ -2150,9 +2174,9 @@ namespace Sass {
2150
2174
 
2151
2175
  bool String_Constant::operator== (const Expression& rhs) const
2152
2176
  {
2153
- if (const String_Quoted* qstr = dynamic_cast<const String_Quoted*>(&rhs)) {
2177
+ if (String_Quoted_Ptr_Const qstr = dynamic_cast<String_Quoted_Ptr_Const>(&rhs)) {
2154
2178
  return (value() == qstr->value());
2155
- } else if (const String_Constant* cstr = dynamic_cast<const String_Constant*>(&rhs)) {
2179
+ } else if (String_Constant_Ptr_Const cstr = dynamic_cast<String_Constant_Ptr_Const>(&rhs)) {
2156
2180
  return (value() == cstr->value());
2157
2181
  }
2158
2182
  return false;
@@ -2169,11 +2193,11 @@ namespace Sass {
2169
2193
 
2170
2194
  bool String_Schema::operator== (const Expression& rhs) const
2171
2195
  {
2172
- if (const String_Schema* r = dynamic_cast<const String_Schema*>(&rhs)) {
2196
+ if (String_Schema_Ptr_Const r = dynamic_cast<String_Schema_Ptr_Const>(&rhs)) {
2173
2197
  if (length() != r->length()) return false;
2174
2198
  for (size_t i = 0, L = length(); i < L; ++i) {
2175
- Expression* rv = (*r)[i];
2176
- Expression* lv = (*this)[i];
2199
+ Expression_Obj rv = (*r)[i];
2200
+ Expression_Obj lv = (*this)[i];
2177
2201
  if (!lv || !rv) return false;
2178
2202
  if (!(*lv == *rv)) return false;
2179
2203
  }
@@ -2184,7 +2208,7 @@ namespace Sass {
2184
2208
 
2185
2209
  bool Boolean::operator== (const Expression& rhs) const
2186
2210
  {
2187
- if (const Boolean* r = dynamic_cast<const Boolean*>(&rhs)) {
2211
+ if (Boolean_Ptr_Const r = dynamic_cast<Boolean_Ptr_Const>(&rhs)) {
2188
2212
  return (value() == r->value());
2189
2213
  }
2190
2214
  return false;
@@ -2192,7 +2216,7 @@ namespace Sass {
2192
2216
 
2193
2217
  bool Color::operator== (const Expression& rhs) const
2194
2218
  {
2195
- if (const Color* r = dynamic_cast<const Color*>(&rhs)) {
2219
+ if (Color_Ptr_Const r = dynamic_cast<Color_Ptr_Const>(&rhs)) {
2196
2220
  return r_ == r->r() &&
2197
2221
  g_ == r->g() &&
2198
2222
  b_ == r->b() &&
@@ -2203,12 +2227,12 @@ namespace Sass {
2203
2227
 
2204
2228
  bool List::operator== (const Expression& rhs) const
2205
2229
  {
2206
- if (const List* r = dynamic_cast<const List*>(&rhs)) {
2230
+ if (List_Ptr_Const r = dynamic_cast<List_Ptr_Const>(&rhs)) {
2207
2231
  if (length() != r->length()) return false;
2208
2232
  if (separator() != r->separator()) return false;
2209
2233
  for (size_t i = 0, L = length(); i < L; ++i) {
2210
- Expression* rv = (*r)[i];
2211
- Expression* lv = (*this)[i];
2234
+ Expression_Obj rv = r->at(i);
2235
+ Expression_Obj lv = this->at(i);
2212
2236
  if (!lv || !rv) return false;
2213
2237
  if (!(*lv == *rv)) return false;
2214
2238
  }
@@ -2219,11 +2243,11 @@ namespace Sass {
2219
2243
 
2220
2244
  bool Map::operator== (const Expression& rhs) const
2221
2245
  {
2222
- if (const Map* r = dynamic_cast<const Map*>(&rhs)) {
2246
+ if (Map_Ptr_Const r = dynamic_cast<Map_Ptr_Const>(&rhs)) {
2223
2247
  if (length() != r->length()) return false;
2224
2248
  for (auto key : keys()) {
2225
- Expression* lv = at(key);
2226
- Expression* rv = r->at(key);
2249
+ Expression_Obj lv = at(key);
2250
+ Expression_Obj rv = r->at(key);
2227
2251
  if (!rv || !lv) return false;
2228
2252
  if (!(*lv == *rv)) return false;
2229
2253
  }
@@ -2242,18 +2266,19 @@ namespace Sass {
2242
2266
  // arglist expects a list of arguments
2243
2267
  // so we need to break before keywords
2244
2268
  for (size_t i = 0, L = length(); i < L; ++i) {
2245
- if (Argument* arg = dynamic_cast<Argument*>((*this)[i])) {
2269
+ Expression_Obj obj = this->at(i);
2270
+ if (Argument* arg = dynamic_cast<Argument*>(&obj)) {
2246
2271
  if (!arg->name().empty()) return i;
2247
2272
  }
2248
2273
  }
2249
2274
  return length();
2250
2275
  }
2251
2276
 
2252
- Expression* Hashed::at(Expression* k) const
2277
+ Expression_Obj Hashed::at(Expression_Obj k) const
2253
2278
  {
2254
2279
  if (elements_.count(k))
2255
2280
  { return elements_.at(k); }
2256
- else { return &sass_null; }
2281
+ else { return NULL; }
2257
2282
  }
2258
2283
 
2259
2284
  bool Binary_Expression::is_left_interpolant(void) const
@@ -2272,7 +2297,7 @@ namespace Sass {
2272
2297
  Inspect i(emitter);
2273
2298
  i.in_declaration = true;
2274
2299
  // ToDo: inspect should be const
2275
- const_cast<AST_Node*>(this)->perform(&i);
2300
+ const_cast<AST_Node_Ptr>(this)->perform(&i);
2276
2301
  return i.get_buffer();
2277
2302
  }
2278
2303
 
@@ -2294,32 +2319,133 @@ namespace Sass {
2294
2319
  //////////////////////////////////////////////////////////////////////////////////////////
2295
2320
  // Additional method on Lists to retrieve values directly or from an encompassed Argument.
2296
2321
  //////////////////////////////////////////////////////////////////////////////////////////
2297
- Expression* List::value_at_index(size_t i) {
2322
+ Expression_Obj List::value_at_index(size_t i) {
2323
+ Expression_Obj obj = this->at(i);
2298
2324
  if (is_arglist_) {
2299
- if (Argument* arg = dynamic_cast<Argument*>((*this)[i])) {
2325
+ if (Argument* arg = dynamic_cast<Argument*>(&obj)) {
2300
2326
  return arg->value();
2301
2327
  } else {
2302
- return (*this)[i];
2328
+ return &obj;
2303
2329
  }
2304
2330
  } else {
2305
- return (*this)[i];
2331
+ return &obj;
2306
2332
  }
2307
2333
  }
2308
2334
 
2309
2335
  //////////////////////////////////////////////////////////////////////////////////////////
2310
2336
  // Convert map to (key, value) list.
2311
2337
  //////////////////////////////////////////////////////////////////////////////////////////
2312
- List* Map::to_list(Context& ctx, ParserState& pstate) {
2313
- List* ret = SASS_MEMORY_NEW(ctx.mem, List, pstate, length(), SASS_COMMA);
2338
+ List_Obj Map::to_list(Context& ctx, ParserState& pstate) {
2339
+ List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);
2314
2340
 
2315
2341
  for (auto key : keys()) {
2316
- List* l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 2);
2317
- *l << key;
2318
- *l << at(key);
2319
- *ret << l;
2342
+ List_Obj l = SASS_MEMORY_NEW(List, pstate, 2);
2343
+ l->append(&key);
2344
+ l->append(at(key));
2345
+ ret->append(&l);
2320
2346
  }
2321
2347
 
2322
2348
  return ret;
2323
2349
  }
2324
2350
 
2351
+ //////////////////////////////////////////////////////////////////////////////////////////
2352
+ // Copy implementations
2353
+ //////////////////////////////////////////////////////////////////////////////////////////
2354
+
2355
+ #ifdef DEBUG_SHARED_PTR
2356
+
2357
+ #define IMPLEMENT_AST_OPERATORS(klass) \
2358
+ klass##_Ptr klass::copy(std::string file, size_t line) const { \
2359
+ klass##_Ptr cpy = new klass(this); \
2360
+ cpy->trace(file, line); \
2361
+ return cpy; \
2362
+ } \
2363
+ klass##_Ptr klass::clone(std::string file, size_t line) const { \
2364
+ klass##_Ptr cpy = copy(file, line); \
2365
+ cpy->cloneChildren(); \
2366
+ return cpy; \
2367
+ } \
2368
+
2369
+ #else
2370
+
2371
+ #define IMPLEMENT_AST_OPERATORS(klass) \
2372
+ klass##_Ptr klass::copy() const { \
2373
+ return new klass(this); \
2374
+ } \
2375
+ klass##_Ptr klass::clone() const { \
2376
+ klass##_Ptr cpy = copy(); \
2377
+ cpy->cloneChildren(); \
2378
+ return cpy; \
2379
+ } \
2380
+
2381
+ #endif
2382
+
2383
+ IMPLEMENT_AST_OPERATORS(Supports_Operator);
2384
+ IMPLEMENT_AST_OPERATORS(Supports_Negation);
2385
+ IMPLEMENT_AST_OPERATORS(Compound_Selector);
2386
+ IMPLEMENT_AST_OPERATORS(Complex_Selector);
2387
+ IMPLEMENT_AST_OPERATORS(Element_Selector);
2388
+ IMPLEMENT_AST_OPERATORS(Class_Selector);
2389
+ IMPLEMENT_AST_OPERATORS(Id_Selector);
2390
+ IMPLEMENT_AST_OPERATORS(Pseudo_Selector);
2391
+ IMPLEMENT_AST_OPERATORS(Wrapped_Selector);
2392
+ IMPLEMENT_AST_OPERATORS(Selector_List);
2393
+ IMPLEMENT_AST_OPERATORS(Ruleset);
2394
+ IMPLEMENT_AST_OPERATORS(Media_Block);
2395
+ IMPLEMENT_AST_OPERATORS(Custom_Warning);
2396
+ IMPLEMENT_AST_OPERATORS(Custom_Error);
2397
+ IMPLEMENT_AST_OPERATORS(List);
2398
+ IMPLEMENT_AST_OPERATORS(Map);
2399
+ IMPLEMENT_AST_OPERATORS(Number);
2400
+ IMPLEMENT_AST_OPERATORS(Binary_Expression);
2401
+ IMPLEMENT_AST_OPERATORS(String_Schema);
2402
+ IMPLEMENT_AST_OPERATORS(String_Constant);
2403
+ IMPLEMENT_AST_OPERATORS(String_Quoted);
2404
+ IMPLEMENT_AST_OPERATORS(Boolean);
2405
+ IMPLEMENT_AST_OPERATORS(Color);
2406
+ IMPLEMENT_AST_OPERATORS(Null);
2407
+ IMPLEMENT_AST_OPERATORS(Parent_Selector);
2408
+ IMPLEMENT_AST_OPERATORS(Import);
2409
+ IMPLEMENT_AST_OPERATORS(Import_Stub);
2410
+ IMPLEMENT_AST_OPERATORS(Function_Call);
2411
+ IMPLEMENT_AST_OPERATORS(Directive);
2412
+ IMPLEMENT_AST_OPERATORS(At_Root_Block);
2413
+ IMPLEMENT_AST_OPERATORS(Supports_Block);
2414
+ IMPLEMENT_AST_OPERATORS(While);
2415
+ IMPLEMENT_AST_OPERATORS(Each);
2416
+ IMPLEMENT_AST_OPERATORS(For);
2417
+ IMPLEMENT_AST_OPERATORS(If);
2418
+ IMPLEMENT_AST_OPERATORS(Mixin_Call);
2419
+ IMPLEMENT_AST_OPERATORS(Extension);
2420
+ IMPLEMENT_AST_OPERATORS(Media_Query);
2421
+ IMPLEMENT_AST_OPERATORS(Media_Query_Expression);
2422
+ IMPLEMENT_AST_OPERATORS(Debug);
2423
+ IMPLEMENT_AST_OPERATORS(Error);
2424
+ IMPLEMENT_AST_OPERATORS(Warning);
2425
+ IMPLEMENT_AST_OPERATORS(Assignment);
2426
+ IMPLEMENT_AST_OPERATORS(Return);
2427
+ IMPLEMENT_AST_OPERATORS(At_Root_Query);
2428
+ IMPLEMENT_AST_OPERATORS(Variable);
2429
+ IMPLEMENT_AST_OPERATORS(Comment);
2430
+ IMPLEMENT_AST_OPERATORS(Attribute_Selector);
2431
+ IMPLEMENT_AST_OPERATORS(Supports_Interpolation);
2432
+ IMPLEMENT_AST_OPERATORS(Supports_Declaration);
2433
+ IMPLEMENT_AST_OPERATORS(Supports_Condition);
2434
+ IMPLEMENT_AST_OPERATORS(Parameters);
2435
+ IMPLEMENT_AST_OPERATORS(Parameter);
2436
+ IMPLEMENT_AST_OPERATORS(Arguments);
2437
+ IMPLEMENT_AST_OPERATORS(Argument);
2438
+ IMPLEMENT_AST_OPERATORS(Unary_Expression);
2439
+ IMPLEMENT_AST_OPERATORS(Function_Call_Schema);
2440
+ IMPLEMENT_AST_OPERATORS(Block);
2441
+ IMPLEMENT_AST_OPERATORS(Content);
2442
+ IMPLEMENT_AST_OPERATORS(Textual);
2443
+ IMPLEMENT_AST_OPERATORS(Trace);
2444
+ IMPLEMENT_AST_OPERATORS(Keyframe_Rule);
2445
+ IMPLEMENT_AST_OPERATORS(Bubble);
2446
+ IMPLEMENT_AST_OPERATORS(Selector_Schema);
2447
+ IMPLEMENT_AST_OPERATORS(Placeholder_Selector);
2448
+ IMPLEMENT_AST_OPERATORS(Definition);
2449
+ IMPLEMENT_AST_OPERATORS(Declaration);
2450
+
2325
2451
  }