sassc 1.11.1 → 1.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
  }