sassc 2.0.1 → 2.1.0.pre1

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 (200) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +7 -3
  5. data/CHANGELOG.md +3 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +23 -8
  9. data/ext/extconf.rb +39 -0
  10. data/ext/libsass/.gitignore +1 -0
  11. data/ext/libsass/GNUmakefile.am +23 -39
  12. data/ext/libsass/Makefile +56 -91
  13. data/ext/libsass/Makefile.conf +16 -2
  14. data/ext/libsass/configure.ac +8 -12
  15. data/ext/libsass/include/sass/base.h +1 -0
  16. data/ext/libsass/include/sass/context.h +1 -1
  17. data/ext/libsass/src/GNUmakefile.am +1 -5
  18. data/ext/libsass/src/ast.cpp +747 -2010
  19. data/ext/libsass/src/ast.hpp +239 -2383
  20. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  21. data/ext/libsass/src/ast2c.hpp +39 -0
  22. data/ext/libsass/src/ast_def_macros.hpp +62 -10
  23. data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
  25. data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
  26. data/ext/libsass/src/ast_sel_unify.cpp +280 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1475 -0
  28. data/ext/libsass/src/ast_selectors.hpp +568 -0
  29. data/ext/libsass/src/ast_supports.cpp +130 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +967 -0
  32. data/ext/libsass/src/ast_values.hpp +489 -0
  33. data/ext/libsass/src/backtrace.cpp +4 -0
  34. data/ext/libsass/src/base64vlq.cpp +3 -0
  35. data/ext/libsass/src/bind.cpp +18 -17
  36. data/ext/libsass/src/bind.hpp +3 -1
  37. data/ext/libsass/src/c2ast.cpp +64 -0
  38. data/ext/libsass/src/c2ast.hpp +14 -0
  39. data/ext/libsass/src/cencode.c +2 -2
  40. data/ext/libsass/src/check_nesting.cpp +52 -56
  41. data/ext/libsass/src/check_nesting.hpp +35 -34
  42. data/ext/libsass/src/color_maps.cpp +156 -153
  43. data/ext/libsass/src/color_maps.hpp +152 -152
  44. data/ext/libsass/src/constants.cpp +15 -0
  45. data/ext/libsass/src/constants.hpp +13 -0
  46. data/ext/libsass/src/context.cpp +24 -14
  47. data/ext/libsass/src/context.hpp +6 -6
  48. data/ext/libsass/src/cssize.cpp +69 -71
  49. data/ext/libsass/src/cssize.hpp +50 -50
  50. data/ext/libsass/src/debugger.hpp +117 -110
  51. data/ext/libsass/src/emitter.cpp +13 -12
  52. data/ext/libsass/src/emitter.hpp +13 -9
  53. data/ext/libsass/src/environment.cpp +15 -1
  54. data/ext/libsass/src/environment.hpp +6 -0
  55. data/ext/libsass/src/error_handling.cpp +36 -59
  56. data/ext/libsass/src/error_handling.hpp +29 -16
  57. data/ext/libsass/src/eval.cpp +302 -323
  58. data/ext/libsass/src/eval.hpp +64 -55
  59. data/ext/libsass/src/expand.cpp +94 -88
  60. data/ext/libsass/src/expand.hpp +33 -37
  61. data/ext/libsass/src/extend.cpp +38 -36
  62. data/ext/libsass/src/extend.hpp +15 -15
  63. data/ext/libsass/src/file.cpp +34 -2
  64. data/ext/libsass/src/fn_colors.cpp +594 -0
  65. data/ext/libsass/src/fn_colors.hpp +85 -0
  66. data/ext/libsass/src/fn_lists.cpp +284 -0
  67. data/ext/libsass/src/fn_lists.hpp +34 -0
  68. data/ext/libsass/src/fn_maps.cpp +94 -0
  69. data/ext/libsass/src/fn_maps.hpp +30 -0
  70. data/ext/libsass/src/fn_miscs.cpp +256 -0
  71. data/ext/libsass/src/fn_miscs.hpp +40 -0
  72. data/ext/libsass/src/fn_numbers.cpp +220 -0
  73. data/ext/libsass/src/fn_numbers.hpp +45 -0
  74. data/ext/libsass/src/fn_selectors.cpp +235 -0
  75. data/ext/libsass/src/fn_selectors.hpp +35 -0
  76. data/ext/libsass/src/fn_strings.cpp +254 -0
  77. data/ext/libsass/src/fn_strings.hpp +34 -0
  78. data/ext/libsass/src/fn_utils.cpp +156 -0
  79. data/ext/libsass/src/fn_utils.hpp +56 -0
  80. data/ext/libsass/src/inspect.cpp +101 -152
  81. data/ext/libsass/src/inspect.hpp +69 -73
  82. data/ext/libsass/src/json.cpp +2 -2
  83. data/ext/libsass/src/lexer.cpp +6 -3
  84. data/ext/libsass/src/listize.cpp +9 -11
  85. data/ext/libsass/src/listize.hpp +11 -7
  86. data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
  87. data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
  88. data/ext/libsass/src/node.cpp +13 -10
  89. data/ext/libsass/src/node.hpp +3 -3
  90. data/ext/libsass/src/operation.hpp +184 -144
  91. data/ext/libsass/src/operators.cpp +43 -17
  92. data/ext/libsass/src/operators.hpp +5 -5
  93. data/ext/libsass/src/output.cpp +21 -18
  94. data/ext/libsass/src/output.hpp +14 -21
  95. data/ext/libsass/src/parser.cpp +215 -183
  96. data/ext/libsass/src/parser.hpp +28 -24
  97. data/ext/libsass/src/plugins.cpp +5 -1
  98. data/ext/libsass/src/position.cpp +3 -0
  99. data/ext/libsass/src/prelexer.cpp +9 -3
  100. data/ext/libsass/src/prelexer.hpp +9 -9
  101. data/ext/libsass/src/remove_placeholders.cpp +14 -11
  102. data/ext/libsass/src/remove_placeholders.hpp +8 -9
  103. data/ext/libsass/src/sass.cpp +9 -3
  104. data/ext/libsass/src/sass.hpp +12 -9
  105. data/ext/libsass/src/sass2scss.cpp +45 -14
  106. data/ext/libsass/src/sass_context.cpp +18 -15
  107. data/ext/libsass/src/sass_functions.cpp +6 -3
  108. data/ext/libsass/src/sass_functions.hpp +1 -1
  109. data/ext/libsass/src/sass_util.cpp +3 -0
  110. data/ext/libsass/src/sass_values.cpp +21 -13
  111. data/ext/libsass/src/source_map.cpp +5 -2
  112. data/ext/libsass/src/source_map.hpp +2 -2
  113. data/ext/libsass/src/subset_map.cpp +4 -1
  114. data/ext/libsass/src/to_value.cpp +23 -21
  115. data/ext/libsass/src/to_value.hpp +18 -22
  116. data/ext/libsass/src/units.cpp +4 -0
  117. data/ext/libsass/src/units.hpp +1 -0
  118. data/ext/libsass/src/utf8/checked.h +12 -10
  119. data/ext/libsass/src/utf8/core.h +3 -0
  120. data/ext/libsass/src/utf8_string.cpp +3 -0
  121. data/ext/libsass/src/util.cpp +67 -75
  122. data/ext/libsass/src/util.hpp +64 -19
  123. data/ext/libsass/src/util_string.cpp +75 -0
  124. data/ext/libsass/src/util_string.hpp +19 -0
  125. data/ext/libsass/src/values.cpp +22 -13
  126. data/ext/libsass/src/values.hpp +2 -2
  127. data/ext/libsass/win/libsass.targets +30 -4
  128. data/ext/libsass/win/libsass.vcxproj.filters +82 -4
  129. data/lib/sassc.rb +24 -0
  130. data/lib/sassc/engine.rb +2 -2
  131. data/lib/sassc/native.rb +8 -1
  132. data/lib/sassc/version.rb +1 -1
  133. data/sassc.gemspec +19 -11
  134. data/test/engine_test.rb +26 -1
  135. data/test/native_test.rb +1 -1
  136. metadata +66 -72
  137. data/ext/Rakefile +0 -3
  138. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  139. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  140. data/ext/libsass/.travis.yml +0 -64
  141. data/ext/libsass/Readme.md +0 -104
  142. data/ext/libsass/SECURITY.md +0 -10
  143. data/ext/libsass/appveyor.yml +0 -91
  144. data/ext/libsass/docs/README.md +0 -20
  145. data/ext/libsass/docs/api-context-example.md +0 -45
  146. data/ext/libsass/docs/api-context-internal.md +0 -163
  147. data/ext/libsass/docs/api-context.md +0 -295
  148. data/ext/libsass/docs/api-doc.md +0 -215
  149. data/ext/libsass/docs/api-function-example.md +0 -67
  150. data/ext/libsass/docs/api-function-internal.md +0 -8
  151. data/ext/libsass/docs/api-function.md +0 -74
  152. data/ext/libsass/docs/api-importer-example.md +0 -112
  153. data/ext/libsass/docs/api-importer-internal.md +0 -20
  154. data/ext/libsass/docs/api-importer.md +0 -86
  155. data/ext/libsass/docs/api-value-example.md +0 -55
  156. data/ext/libsass/docs/api-value-internal.md +0 -76
  157. data/ext/libsass/docs/api-value.md +0 -154
  158. data/ext/libsass/docs/build-on-darwin.md +0 -27
  159. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  160. data/ext/libsass/docs/build-on-windows.md +0 -139
  161. data/ext/libsass/docs/build-shared-library.md +0 -35
  162. data/ext/libsass/docs/build-with-autotools.md +0 -78
  163. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  164. data/ext/libsass/docs/build-with-mingw.md +0 -107
  165. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  166. data/ext/libsass/docs/build.md +0 -97
  167. data/ext/libsass/docs/compatibility-plan.md +0 -48
  168. data/ext/libsass/docs/contributing.md +0 -17
  169. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  170. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  171. data/ext/libsass/docs/implementations.md +0 -56
  172. data/ext/libsass/docs/plugins.md +0 -47
  173. data/ext/libsass/docs/setup-environment.md +0 -68
  174. data/ext/libsass/docs/source-map-internals.md +0 -51
  175. data/ext/libsass/docs/trace.md +0 -26
  176. data/ext/libsass/docs/triage.md +0 -17
  177. data/ext/libsass/docs/unicode.md +0 -39
  178. data/ext/libsass/extconf.rb +0 -6
  179. data/ext/libsass/script/bootstrap +0 -13
  180. data/ext/libsass/script/branding +0 -10
  181. data/ext/libsass/script/ci-build-libsass +0 -134
  182. data/ext/libsass/script/ci-build-plugin +0 -62
  183. data/ext/libsass/script/ci-install-compiler +0 -6
  184. data/ext/libsass/script/ci-install-deps +0 -20
  185. data/ext/libsass/script/ci-report-coverage +0 -42
  186. data/ext/libsass/script/spec +0 -5
  187. data/ext/libsass/script/tap-driver +0 -652
  188. data/ext/libsass/script/tap-runner +0 -1
  189. data/ext/libsass/script/test-leaks.pl +0 -103
  190. data/ext/libsass/src/functions.cpp +0 -2234
  191. data/ext/libsass/src/functions.hpp +0 -198
  192. data/ext/libsass/src/to_c.hpp +0 -39
  193. data/ext/libsass/test/test_node.cpp +0 -94
  194. data/ext/libsass/test/test_paths.cpp +0 -28
  195. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  196. data/ext/libsass/test/test_specificity.cpp +0 -25
  197. data/ext/libsass/test/test_subset_map.cpp +0 -472
  198. data/ext/libsass/test/test_superselector.cpp +0 -69
  199. data/ext/libsass/test/test_unification.cpp +0 -31
  200. data/lib/tasks/libsass.rb +0 -33
@@ -1,7 +1,10 @@
1
1
  #ifndef SASS_AST_H
2
2
  #define SASS_AST_H
3
3
 
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
4
6
  #include "sass.hpp"
7
+
5
8
  #include <set>
6
9
  #include <deque>
7
10
  #include <vector>
@@ -13,42 +16,6 @@
13
16
  #include "sass/base.h"
14
17
  #include "ast_fwd_decl.hpp"
15
18
 
16
- #ifdef DEBUG_SHARED_PTR
17
-
18
- #define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \
19
- virtual klass##_Ptr copy(std::string, size_t) const = 0; \
20
- virtual klass##_Ptr clone(std::string, size_t) const = 0; \
21
-
22
- #define ATTACH_AST_OPERATIONS(klass) \
23
- virtual klass##_Ptr copy(std::string, size_t) const; \
24
- virtual klass##_Ptr clone(std::string, size_t) const; \
25
-
26
- #else
27
-
28
- #define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \
29
- virtual klass##_Ptr copy() const = 0; \
30
- virtual klass##_Ptr clone() const = 0; \
31
-
32
- #define ATTACH_AST_OPERATIONS(klass) \
33
- virtual klass##_Ptr copy() const; \
34
- virtual klass##_Ptr clone() const; \
35
-
36
- #endif
37
-
38
- #ifdef __clang__
39
-
40
- /*
41
- * There are some overloads used here that trigger the clang overload
42
- * hiding warning. Specifically:
43
- *
44
- * Type type() which hides string type() from Expression
45
- *
46
- */
47
- #pragma clang diagnostic push
48
- #pragma clang diagnostic ignored "-Woverloaded-virtual"
49
-
50
- #endif
51
-
52
19
  #include "util.hpp"
53
20
  #include "units.hpp"
54
21
  #include "context.hpp"
@@ -63,6 +30,7 @@
63
30
  #include "ast_def_macros.hpp"
64
31
  #include "ast_fwd_decl.hpp"
65
32
  #include "source_map.hpp"
33
+ #include "fn_utils.hpp"
66
34
 
67
35
  #include "sass.h"
68
36
 
@@ -73,7 +41,7 @@ namespace Sass {
73
41
 
74
42
  // ToDo: should this really be hardcoded
75
43
  // Note: most methods follow precision option
76
- const double NUMBER_EPSILON = 0.00000000000001;
44
+ const double NUMBER_EPSILON = 1e-12;
77
45
 
78
46
  // macro to test if numbers are equal within a small error margin
79
47
  #define NEAR_EQUAL(lhs, rhs) std::fabs(lhs - rhs) < NUMBER_EPSILON
@@ -104,6 +72,10 @@ namespace Sass {
104
72
  }
105
73
  //////////////////////////////////////////////////////////
106
74
 
75
+ const char* sass_op_to_name(enum Sass_OP op);
76
+
77
+ const char* sass_op_separator(enum Sass_OP op);
78
+
107
79
  //////////////////////////////////////////////////////////
108
80
  // Abstract base class for all abstract syntax tree nodes.
109
81
  //////////////////////////////////////////////////////////
@@ -117,11 +89,16 @@ namespace Sass {
117
89
  : pstate_(ptr->pstate_)
118
90
  { }
119
91
 
92
+ // allow implicit conversion to string
93
+ // needed for by SharedPtr implementation
94
+ operator std::string() {
95
+ return to_string();
96
+ }
97
+
120
98
  // AST_Node(AST_Node& ptr) = delete;
121
99
 
122
100
  virtual ~AST_Node() = 0;
123
- virtual size_t hash() { return 0; }
124
- ATTACH_VIRTUAL_AST_OPERATIONS(AST_Node);
101
+ virtual size_t hash() const { return 0; }
125
102
  virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
126
103
  virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
127
104
  virtual const std::string to_string(Sass_Inspect_Options opt) const;
@@ -130,12 +107,11 @@ namespace Sass {
130
107
  // generic find function (not fully implemented yet)
131
108
  // ToDo: add specific implementions to all children
132
109
  virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };
133
- public:
134
110
  void update_pstate(const ParserState& pstate);
135
- public:
136
111
  Offset off() { return pstate(); }
137
112
  Position pos() { return pstate(); }
138
- ATTACH_OPERATIONS()
113
+ ATTACH_ABSTRACT_AST_OPERATIONS(AST_Node);
114
+ ATTACH_ABSTRACT_CRTP_PERFORM_METHODS()
139
115
  };
140
116
  inline AST_Node::~AST_Node() { }
141
117
 
@@ -162,7 +138,7 @@ namespace Sass {
162
138
  //////////////////////////////////////////////////////////////////////
163
139
  class Expression : public AST_Node {
164
140
  public:
165
- enum Concrete_Type {
141
+ enum Type {
166
142
  NONE,
167
143
  BOOLEAN,
168
144
  NUMBER,
@@ -177,86 +153,39 @@ namespace Sass {
177
153
  C_ERROR,
178
154
  FUNCTION,
179
155
  VARIABLE,
156
+ PARENT,
180
157
  NUM_TYPES
181
158
  };
182
- enum Simple_Type {
183
- SIMPLE,
184
- ATTR_SEL,
185
- PSEUDO_SEL,
186
- WRAPPED_SEL,
187
- };
188
159
  private:
189
160
  // expressions in some contexts shouldn't be evaluated
190
161
  ADD_PROPERTY(bool, is_delayed)
191
162
  ADD_PROPERTY(bool, is_expanded)
192
163
  ADD_PROPERTY(bool, is_interpolant)
193
- ADD_PROPERTY(Concrete_Type, concrete_type)
164
+ ADD_PROPERTY(Type, concrete_type)
194
165
  public:
195
- Expression(ParserState pstate,
196
- bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
197
- : AST_Node(pstate),
198
- is_delayed_(d),
199
- is_expanded_(e),
200
- is_interpolant_(i),
201
- concrete_type_(ct)
202
- { }
203
- Expression(const Expression* ptr)
204
- : AST_Node(ptr),
205
- is_delayed_(ptr->is_delayed_),
206
- is_expanded_(ptr->is_expanded_),
207
- is_interpolant_(ptr->is_interpolant_),
208
- concrete_type_(ptr->concrete_type_)
209
- { }
166
+ Expression(ParserState pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);
210
167
  virtual operator bool() { return true; }
211
168
  virtual ~Expression() { }
212
- virtual std::string type() const { return ""; /* TODO: raise an error? */ }
213
169
  virtual bool is_invisible() const { return false; }
170
+
171
+ virtual std::string type() const { return ""; }
214
172
  static std::string type_name() { return ""; }
173
+
215
174
  virtual bool is_false() { return false; }
216
175
  // virtual bool is_true() { return !is_false(); }
176
+ virtual bool operator< (const Expression& rhs) const { return false; }
217
177
  virtual bool operator== (const Expression& rhs) const { return false; }
178
+ inline bool operator>(const Expression& rhs) const { return rhs < *this; }
179
+ inline bool operator!=(const Expression& rhs) const { return !(rhs == *this); }
218
180
  virtual bool eq(const Expression& rhs) const { return *this == rhs; };
219
181
  virtual void set_delayed(bool delayed) { is_delayed(delayed); }
220
182
  virtual bool has_interpolant() const { return is_interpolant(); }
221
183
  virtual bool is_left_interpolant() const { return is_interpolant(); }
222
184
  virtual bool is_right_interpolant() const { return is_interpolant(); }
223
- virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
224
- virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
225
185
  ATTACH_VIRTUAL_AST_OPERATIONS(Expression);
226
- virtual size_t hash() { return 0; }
227
- };
228
-
229
- //////////////////////////////////////////////////////////////////////
230
- // Still just an expression, but with a to_string method
231
- //////////////////////////////////////////////////////////////////////
232
- class PreValue : public Expression {
233
- public:
234
- PreValue(ParserState pstate,
235
- bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
236
- : Expression(pstate, d, e, i, ct)
237
- { }
238
- PreValue(const PreValue* ptr)
239
- : Expression(ptr)
240
- { }
241
- ATTACH_VIRTUAL_AST_OPERATIONS(PreValue);
242
- virtual ~PreValue() { }
186
+ size_t hash() const override { return 0; }
243
187
  };
244
188
 
245
- //////////////////////////////////////////////////////////////////////
246
- // base class for values that support operations
247
- //////////////////////////////////////////////////////////////////////
248
- class Value : public Expression {
249
- public:
250
- Value(ParserState pstate,
251
- bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
252
- : Expression(pstate, d, e, i, ct)
253
- { }
254
- Value(const Value* ptr)
255
- : Expression(ptr)
256
- { }
257
- ATTACH_VIRTUAL_AST_OPERATIONS(Value);
258
- virtual bool operator== (const Expression& rhs) const = 0;
259
- };
260
189
  }
261
190
 
262
191
  /////////////////////////////////////////////////////////////////////////////////////
@@ -293,11 +222,11 @@ namespace Sass {
293
222
  class Vectorized {
294
223
  std::vector<T> elements_;
295
224
  protected:
296
- size_t hash_;
225
+ mutable size_t hash_;
297
226
  void reset_hash() { hash_ = 0; }
298
227
  virtual void adjust_after_pushing(T element) { }
299
228
  public:
300
- Vectorized(size_t s = 0) : elements_(std::vector<T>()), hash_(0)
229
+ Vectorized(size_t s = 0) : hash_(0)
301
230
  { elements_.reserve(s); }
302
231
  virtual ~Vectorized() = 0;
303
232
  size_t length() const { return elements_.size(); }
@@ -308,6 +237,7 @@ namespace Sass {
308
237
  T& operator[](size_t i) { return elements_[i]; }
309
238
  virtual const T& at(size_t i) const { return elements_.at(i); }
310
239
  virtual T& at(size_t i) { return elements_.at(i); }
240
+ const T& get(size_t i) const { return elements_[i]; }
311
241
  const T& operator[](size_t i) const { return elements_[i]; }
312
242
  virtual void append(T element)
313
243
  {
@@ -330,16 +260,22 @@ namespace Sass {
330
260
  const std::vector<T>& elements() const { return elements_; }
331
261
  std::vector<T>& elements(std::vector<T>& e) { elements_ = e; return elements_; }
332
262
 
333
- virtual size_t hash()
263
+ virtual size_t hash() const
334
264
  {
335
265
  if (hash_ == 0) {
336
- for (T& el : elements_) {
266
+ for (const T& el : elements_) {
337
267
  hash_combine(hash_, el->hash());
338
268
  }
339
269
  }
340
270
  return hash_;
341
271
  }
342
272
 
273
+ template <typename P, typename V>
274
+ typename std::vector<T>::iterator insert(P position, const V& val) {
275
+ reset_hash();
276
+ return elements_.insert(position, val);
277
+ }
278
+
343
279
  typename std::vector<T>::iterator end() { return elements_.end(); }
344
280
  typename std::vector<T>::iterator begin() { return elements_.begin(); }
345
281
  typename std::vector<T>::const_iterator end() const { return elements_.end(); }
@@ -360,16 +296,16 @@ namespace Sass {
360
296
  ExpressionMap elements_;
361
297
  std::vector<Expression_Obj> list_;
362
298
  protected:
363
- size_t hash_;
299
+ mutable size_t hash_;
364
300
  Expression_Obj duplicate_key_;
365
301
  void reset_hash() { hash_ = 0; }
366
- void reset_duplicate_key() { duplicate_key_ = 0; }
302
+ void reset_duplicate_key() { duplicate_key_ = {}; }
367
303
  virtual void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { }
368
304
  public:
369
305
  Hashed(size_t s = 0)
370
306
  : elements_(ExpressionMap(s)),
371
307
  list_(std::vector<Expression_Obj>()),
372
- hash_(0), duplicate_key_(NULL)
308
+ hash_(0), duplicate_key_({})
373
309
  { elements_.reserve(s); list_.reserve(s); }
374
310
  virtual ~Hashed();
375
311
  size_t length() const { return list_.size(); }
@@ -425,7 +361,7 @@ namespace Sass {
425
361
  /////////////////////////////////////////////////////////////////////////
426
362
  class Statement : public AST_Node {
427
363
  public:
428
- enum Statement_Type {
364
+ enum Type {
429
365
  NONE,
430
366
  RULESET,
431
367
  MEDIA,
@@ -451,60 +387,33 @@ namespace Sass {
451
387
  IF
452
388
  };
453
389
  private:
454
- ADD_PROPERTY(Statement_Type, statement_type)
390
+ ADD_PROPERTY(Type, statement_type)
455
391
  ADD_PROPERTY(size_t, tabs)
456
392
  ADD_PROPERTY(bool, group_end)
457
393
  public:
458
- Statement(ParserState pstate, Statement_Type st = NONE, size_t t = 0)
459
- : AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)
460
- { }
461
- Statement(const Statement* ptr)
462
- : AST_Node(ptr),
463
- statement_type_(ptr->statement_type_),
464
- tabs_(ptr->tabs_),
465
- group_end_(ptr->group_end_)
466
- { }
467
- virtual ~Statement() = 0;
394
+ Statement(ParserState pstate, Type st = NONE, size_t t = 0);
395
+ virtual ~Statement() = 0; // virtual destructor
468
396
  // needed for rearranging nested rulesets during CSS emission
469
- virtual bool is_invisible() const { return false; }
470
- virtual bool bubbles() { return false; }
471
- virtual bool has_content()
472
- {
473
- return statement_type_ == CONTENT;
474
- }
397
+ virtual bool bubbles();
398
+ virtual bool has_content();
399
+ virtual bool is_invisible() const;
400
+ ATTACH_VIRTUAL_AST_OPERATIONS(Statement)
475
401
  };
476
402
  inline Statement::~Statement() { }
477
403
 
478
404
  ////////////////////////
479
405
  // Blocks of statements.
480
406
  ////////////////////////
481
- class Block : public Statement, public Vectorized<Statement_Obj> {
407
+ class Block final : public Statement, public Vectorized<Statement_Obj> {
482
408
  ADD_PROPERTY(bool, is_root)
483
409
  // needed for properly formatted CSS emission
484
410
  protected:
485
- void adjust_after_pushing(Statement_Obj s)
486
- {
487
- }
411
+ void adjust_after_pushing(Statement_Obj s) override {}
488
412
  public:
489
- Block(ParserState pstate, size_t s = 0, bool r = false)
490
- : Statement(pstate),
491
- Vectorized<Statement_Obj>(s),
492
- is_root_(r)
493
- { }
494
- Block(const Block* ptr)
495
- : Statement(ptr),
496
- Vectorized<Statement_Obj>(*ptr),
497
- is_root_(ptr->is_root_)
498
- { }
499
- virtual bool has_content()
500
- {
501
- for (size_t i = 0, L = elements().size(); i < L; ++i) {
502
- if (elements()[i]->has_content()) return true;
503
- }
504
- return Statement::has_content();
505
- }
413
+ Block(ParserState pstate, size_t s = 0, bool r = false);
414
+ bool has_content() override;
506
415
  ATTACH_AST_OPERATIONS(Block)
507
- ATTACH_OPERATIONS()
416
+ ATTACH_CRTP_PERFORM_METHODS()
508
417
  };
509
418
 
510
419
  ////////////////////////////////////////////////////////////////////////
@@ -513,17 +422,10 @@ namespace Sass {
513
422
  class Has_Block : public Statement {
514
423
  ADD_PROPERTY(Block_Obj, block)
515
424
  public:
516
- Has_Block(ParserState pstate, Block_Obj b)
517
- : Statement(pstate), block_(b)
518
- { }
519
- Has_Block(const Has_Block* ptr)
520
- : Statement(ptr), block_(ptr->block_)
521
- { }
522
- virtual bool has_content()
523
- {
524
- return (block_ && block_->has_content()) || Statement::has_content();
525
- }
526
- virtual ~Has_Block() = 0;
425
+ Has_Block(ParserState pstate, Block_Obj b);
426
+ Has_Block(const Has_Block* ptr); // copy constructor
427
+ virtual ~Has_Block() = 0; // virtual destructor
428
+ virtual bool has_content() override;
527
429
  };
528
430
  inline Has_Block::~Has_Block() { }
529
431
 
@@ -531,422 +433,266 @@ namespace Sass {
531
433
  // Rulesets (i.e., sets of styles headed by a selector and containing a block
532
434
  // of style declarations.
533
435
  /////////////////////////////////////////////////////////////////////////////
534
- class Ruleset : public Has_Block {
436
+ class Ruleset final : public Has_Block {
535
437
  ADD_PROPERTY(Selector_List_Obj, selector)
536
438
  ADD_PROPERTY(bool, is_root);
537
439
  public:
538
- Ruleset(ParserState pstate, Selector_List_Obj s = 0, Block_Obj b = 0)
539
- : Has_Block(pstate, b), selector_(s), is_root_(false)
540
- { statement_type(RULESET); }
541
- Ruleset(const Ruleset* ptr)
542
- : Has_Block(ptr),
543
- selector_(ptr->selector_),
544
- is_root_(ptr->is_root_)
545
- { statement_type(RULESET); }
546
- bool is_invisible() const;
440
+ Ruleset(ParserState pstate, Selector_List_Obj s = {}, Block_Obj b = {});
441
+ bool is_invisible() const override;
547
442
  ATTACH_AST_OPERATIONS(Ruleset)
548
- ATTACH_OPERATIONS()
443
+ ATTACH_CRTP_PERFORM_METHODS()
549
444
  };
550
445
 
551
446
  /////////////////
552
447
  // Bubble.
553
448
  /////////////////
554
- class Bubble : public Statement {
449
+ class Bubble final : public Statement {
555
450
  ADD_PROPERTY(Statement_Obj, node)
556
451
  ADD_PROPERTY(bool, group_end)
557
452
  public:
558
- Bubble(ParserState pstate, Statement_Obj n, Statement_Obj g = 0, size_t t = 0)
559
- : Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == 0)
560
- { }
561
- Bubble(const Bubble* ptr)
562
- : Statement(ptr),
563
- node_(ptr->node_),
564
- group_end_(ptr->group_end_)
565
- { }
566
- bool bubbles() { return true; }
453
+ Bubble(ParserState pstate, Statement_Obj n, Statement_Obj g = {}, size_t t = 0);
454
+ bool bubbles() override;
567
455
  ATTACH_AST_OPERATIONS(Bubble)
568
- ATTACH_OPERATIONS()
456
+ ATTACH_CRTP_PERFORM_METHODS()
569
457
  };
570
458
 
571
459
  /////////////////
572
460
  // Trace.
573
461
  /////////////////
574
- class Trace : public Has_Block {
462
+ class Trace final : public Has_Block {
575
463
  ADD_CONSTREF(char, type)
576
464
  ADD_CONSTREF(std::string, name)
577
465
  public:
578
- Trace(ParserState pstate, std::string n, Block_Obj b = 0, char type = 'm')
579
- : Has_Block(pstate, b), type_(type), name_(n)
580
- { }
581
- Trace(const Trace* ptr)
582
- : Has_Block(ptr),
583
- type_(ptr->type_),
584
- name_(ptr->name_)
585
- { }
466
+ Trace(ParserState pstate, std::string n, Block_Obj b = {}, char type = 'm');
586
467
  ATTACH_AST_OPERATIONS(Trace)
587
- ATTACH_OPERATIONS()
468
+ ATTACH_CRTP_PERFORM_METHODS()
588
469
  };
589
470
 
590
471
  /////////////////
591
472
  // Media queries.
592
473
  /////////////////
593
- class Media_Block : public Has_Block {
474
+ class Media_Block final : public Has_Block {
594
475
  ADD_PROPERTY(List_Obj, media_queries)
595
476
  public:
596
- Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b)
597
- : Has_Block(pstate, b), media_queries_(mqs)
598
- { statement_type(MEDIA); }
599
- Media_Block(const Media_Block* ptr)
600
- : Has_Block(ptr), media_queries_(ptr->media_queries_)
601
- { statement_type(MEDIA); }
602
- bool bubbles() { return true; }
603
- bool is_invisible() const;
477
+ Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b);
478
+ bool bubbles() override;
479
+ bool is_invisible() const override;
604
480
  ATTACH_AST_OPERATIONS(Media_Block)
605
- ATTACH_OPERATIONS()
481
+ ATTACH_CRTP_PERFORM_METHODS()
606
482
  };
607
483
 
608
484
  ///////////////////////////////////////////////////////////////////////
609
485
  // At-rules -- arbitrary directives beginning with "@" that may have an
610
486
  // optional statement block.
611
487
  ///////////////////////////////////////////////////////////////////////
612
- class Directive : public Has_Block {
488
+ class Directive final : public Has_Block {
613
489
  ADD_CONSTREF(std::string, keyword)
614
490
  ADD_PROPERTY(Selector_List_Obj, selector)
615
491
  ADD_PROPERTY(Expression_Obj, value)
616
492
  public:
617
- Directive(ParserState pstate, std::string kwd, Selector_List_Obj sel = 0, Block_Obj b = 0, Expression_Obj val = 0)
618
- : Has_Block(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
619
- { statement_type(DIRECTIVE); }
620
- Directive(const Directive* ptr)
621
- : Has_Block(ptr),
622
- keyword_(ptr->keyword_),
623
- selector_(ptr->selector_),
624
- value_(ptr->value_) // set value manually if needed
625
- { statement_type(DIRECTIVE); }
626
- bool bubbles() { return is_keyframes() || is_media(); }
627
- bool is_media() {
628
- return keyword_.compare("@-webkit-media") == 0 ||
629
- keyword_.compare("@-moz-media") == 0 ||
630
- keyword_.compare("@-o-media") == 0 ||
631
- keyword_.compare("@media") == 0;
632
- }
633
- bool is_keyframes() {
634
- return keyword_.compare("@-webkit-keyframes") == 0 ||
635
- keyword_.compare("@-moz-keyframes") == 0 ||
636
- keyword_.compare("@-o-keyframes") == 0 ||
637
- keyword_.compare("@keyframes") == 0;
638
- }
493
+ Directive(ParserState pstate, std::string kwd, Selector_List_Obj sel = {}, Block_Obj b = {}, Expression_Obj val = {});
494
+ bool bubbles() override;
495
+ bool is_media();
496
+ bool is_keyframes();
639
497
  ATTACH_AST_OPERATIONS(Directive)
640
- ATTACH_OPERATIONS()
498
+ ATTACH_CRTP_PERFORM_METHODS()
641
499
  };
642
500
 
643
501
  ///////////////////////////////////////////////////////////////////////
644
502
  // Keyframe-rules -- the child blocks of "@keyframes" nodes.
645
503
  ///////////////////////////////////////////////////////////////////////
646
- class Keyframe_Rule : public Has_Block {
504
+ class Keyframe_Rule final : public Has_Block {
647
505
  // according to css spec, this should be <keyframes-name>
648
506
  // <keyframes-name> = <custom-ident> | <string>
649
507
  ADD_PROPERTY(Selector_List_Obj, name)
650
508
  public:
651
- Keyframe_Rule(ParserState pstate, Block_Obj b)
652
- : Has_Block(pstate, b), name_()
653
- { statement_type(KEYFRAMERULE); }
654
- Keyframe_Rule(const Keyframe_Rule* ptr)
655
- : Has_Block(ptr), name_(ptr->name_)
656
- { statement_type(KEYFRAMERULE); }
509
+ Keyframe_Rule(ParserState pstate, Block_Obj b);
657
510
  ATTACH_AST_OPERATIONS(Keyframe_Rule)
658
- ATTACH_OPERATIONS()
511
+ ATTACH_CRTP_PERFORM_METHODS()
659
512
  };
660
513
 
661
514
  ////////////////////////////////////////////////////////////////////////
662
515
  // Declarations -- style rules consisting of a property name and values.
663
516
  ////////////////////////////////////////////////////////////////////////
664
- class Declaration : public Has_Block {
517
+ class Declaration final : public Has_Block {
665
518
  ADD_PROPERTY(String_Obj, property)
666
519
  ADD_PROPERTY(Expression_Obj, value)
667
520
  ADD_PROPERTY(bool, is_important)
668
521
  ADD_PROPERTY(bool, is_custom_property)
669
522
  ADD_PROPERTY(bool, is_indented)
670
523
  public:
671
- Declaration(ParserState pstate,
672
- String_Obj prop, Expression_Obj val, bool i = false, bool c = false, Block_Obj b = 0)
673
- : Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_custom_property_(c), is_indented_(false)
674
- { statement_type(DECLARATION); }
675
- Declaration(const Declaration* ptr)
676
- : Has_Block(ptr),
677
- property_(ptr->property_),
678
- value_(ptr->value_),
679
- is_important_(ptr->is_important_),
680
- is_custom_property_(ptr->is_custom_property_),
681
- is_indented_(ptr->is_indented_)
682
- { statement_type(DECLARATION); }
683
- virtual bool is_invisible() const;
524
+ Declaration(ParserState pstate, String_Obj prop, Expression_Obj val, bool i = false, bool c = false, Block_Obj b = {});
525
+ bool is_invisible() const override;
684
526
  ATTACH_AST_OPERATIONS(Declaration)
685
- ATTACH_OPERATIONS()
527
+ ATTACH_CRTP_PERFORM_METHODS()
686
528
  };
687
529
 
688
530
  /////////////////////////////////////
689
531
  // Assignments -- variable and value.
690
532
  /////////////////////////////////////
691
- class Assignment : public Statement {
533
+ class Assignment final : public Statement {
692
534
  ADD_CONSTREF(std::string, variable)
693
535
  ADD_PROPERTY(Expression_Obj, value)
694
536
  ADD_PROPERTY(bool, is_default)
695
537
  ADD_PROPERTY(bool, is_global)
696
538
  public:
697
- Assignment(ParserState pstate,
698
- std::string var, Expression_Obj val,
699
- bool is_default = false,
700
- bool is_global = false)
701
- : Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
702
- { statement_type(ASSIGNMENT); }
703
- Assignment(const Assignment* ptr)
704
- : Statement(ptr),
705
- variable_(ptr->variable_),
706
- value_(ptr->value_),
707
- is_default_(ptr->is_default_),
708
- is_global_(ptr->is_global_)
709
- { statement_type(ASSIGNMENT); }
539
+ Assignment(ParserState pstate, std::string var, Expression_Obj val, bool is_default = false, bool is_global = false);
710
540
  ATTACH_AST_OPERATIONS(Assignment)
711
- ATTACH_OPERATIONS()
541
+ ATTACH_CRTP_PERFORM_METHODS()
712
542
  };
713
543
 
714
544
  ////////////////////////////////////////////////////////////////////////////
715
545
  // Import directives. CSS and Sass import lists can be intermingled, so it's
716
546
  // necessary to store a list of each in an Import node.
717
547
  ////////////////////////////////////////////////////////////////////////////
718
- class Import : public Statement {
548
+ class Import final : public Statement {
719
549
  std::vector<Expression_Obj> urls_;
720
- std::vector<Include> incs_;
550
+ std::vector<Include> incs_;
721
551
  ADD_PROPERTY(List_Obj, import_queries);
722
552
  public:
723
- Import(ParserState pstate)
724
- : Statement(pstate),
725
- urls_(std::vector<Expression_Obj>()),
726
- incs_(std::vector<Include>()),
727
- import_queries_()
728
- { statement_type(IMPORT); }
729
- Import(const Import* ptr)
730
- : Statement(ptr),
731
- urls_(ptr->urls_),
732
- incs_(ptr->incs_),
733
- import_queries_(ptr->import_queries_)
734
- { statement_type(IMPORT); }
735
- std::vector<Expression_Obj>& urls() { return urls_; }
736
- std::vector<Include>& incs() { return incs_; }
553
+ Import(ParserState pstate);
554
+ std::vector<Include>& incs();
555
+ std::vector<Expression_Obj>& urls();
737
556
  ATTACH_AST_OPERATIONS(Import)
738
- ATTACH_OPERATIONS()
557
+ ATTACH_CRTP_PERFORM_METHODS()
739
558
  };
740
559
 
741
560
  // not yet resolved single import
742
561
  // so far we only know requested name
743
- class Import_Stub : public Statement {
562
+ class Import_Stub final : public Statement {
744
563
  Include resource_;
745
564
  public:
746
- std::string abs_path() { return resource_.abs_path; };
747
- std::string imp_path() { return resource_.imp_path; };
748
- Include resource() { return resource_; };
749
-
750
- Import_Stub(ParserState pstate, Include res)
751
- : Statement(pstate), resource_(res)
752
- { statement_type(IMPORT_STUB); }
753
- Import_Stub(const Import_Stub* ptr)
754
- : Statement(ptr), resource_(ptr->resource_)
755
- { statement_type(IMPORT_STUB); }
565
+ Import_Stub(ParserState pstate, Include res);
566
+ Include resource();
567
+ std::string imp_path();
568
+ std::string abs_path();
756
569
  ATTACH_AST_OPERATIONS(Import_Stub)
757
- ATTACH_OPERATIONS()
570
+ ATTACH_CRTP_PERFORM_METHODS()
758
571
  };
759
572
 
760
573
  //////////////////////////////
761
574
  // The Sass `@warn` directive.
762
575
  //////////////////////////////
763
- class Warning : public Statement {
576
+ class Warning final : public Statement {
764
577
  ADD_PROPERTY(Expression_Obj, message)
765
578
  public:
766
- Warning(ParserState pstate, Expression_Obj msg)
767
- : Statement(pstate), message_(msg)
768
- { statement_type(WARNING); }
769
- Warning(const Warning* ptr)
770
- : Statement(ptr), message_(ptr->message_)
771
- { statement_type(WARNING); }
579
+ Warning(ParserState pstate, Expression_Obj msg);
772
580
  ATTACH_AST_OPERATIONS(Warning)
773
- ATTACH_OPERATIONS()
581
+ ATTACH_CRTP_PERFORM_METHODS()
774
582
  };
775
583
 
776
584
  ///////////////////////////////
777
585
  // The Sass `@error` directive.
778
586
  ///////////////////////////////
779
- class Error : public Statement {
587
+ class Error final : public Statement {
780
588
  ADD_PROPERTY(Expression_Obj, message)
781
589
  public:
782
- Error(ParserState pstate, Expression_Obj msg)
783
- : Statement(pstate), message_(msg)
784
- { statement_type(ERROR); }
785
- Error(const Error* ptr)
786
- : Statement(ptr), message_(ptr->message_)
787
- { statement_type(ERROR); }
590
+ Error(ParserState pstate, Expression_Obj msg);
788
591
  ATTACH_AST_OPERATIONS(Error)
789
- ATTACH_OPERATIONS()
592
+ ATTACH_CRTP_PERFORM_METHODS()
790
593
  };
791
594
 
792
595
  ///////////////////////////////
793
596
  // The Sass `@debug` directive.
794
597
  ///////////////////////////////
795
- class Debug : public Statement {
598
+ class Debug final : public Statement {
796
599
  ADD_PROPERTY(Expression_Obj, value)
797
600
  public:
798
- Debug(ParserState pstate, Expression_Obj val)
799
- : Statement(pstate), value_(val)
800
- { statement_type(DEBUGSTMT); }
801
- Debug(const Debug* ptr)
802
- : Statement(ptr), value_(ptr->value_)
803
- { statement_type(DEBUGSTMT); }
601
+ Debug(ParserState pstate, Expression_Obj val);
804
602
  ATTACH_AST_OPERATIONS(Debug)
805
- ATTACH_OPERATIONS()
603
+ ATTACH_CRTP_PERFORM_METHODS()
806
604
  };
807
605
 
808
606
  ///////////////////////////////////////////
809
607
  // CSS comments. These may be interpolated.
810
608
  ///////////////////////////////////////////
811
- class Comment : public Statement {
609
+ class Comment final : public Statement {
812
610
  ADD_PROPERTY(String_Obj, text)
813
611
  ADD_PROPERTY(bool, is_important)
814
612
  public:
815
- Comment(ParserState pstate, String_Obj txt, bool is_important)
816
- : Statement(pstate), text_(txt), is_important_(is_important)
817
- { statement_type(COMMENT); }
818
- Comment(const Comment* ptr)
819
- : Statement(ptr),
820
- text_(ptr->text_),
821
- is_important_(ptr->is_important_)
822
- { statement_type(COMMENT); }
823
- virtual bool is_invisible() const
824
- { return /* is_important() == */ false; }
613
+ Comment(ParserState pstate, String_Obj txt, bool is_important);
614
+ virtual bool is_invisible() const override;
825
615
  ATTACH_AST_OPERATIONS(Comment)
826
- ATTACH_OPERATIONS()
616
+ ATTACH_CRTP_PERFORM_METHODS()
827
617
  };
828
618
 
829
619
  ////////////////////////////////////
830
620
  // The Sass `@if` control directive.
831
621
  ////////////////////////////////////
832
- class If : public Has_Block {
622
+ class If final : public Has_Block {
833
623
  ADD_PROPERTY(Expression_Obj, predicate)
834
624
  ADD_PROPERTY(Block_Obj, alternative)
835
625
  public:
836
- If(ParserState pstate, Expression_Obj pred, Block_Obj con, Block_Obj alt = 0)
837
- : Has_Block(pstate, con), predicate_(pred), alternative_(alt)
838
- { statement_type(IF); }
839
- If(const If* ptr)
840
- : Has_Block(ptr),
841
- predicate_(ptr->predicate_),
842
- alternative_(ptr->alternative_)
843
- { statement_type(IF); }
844
- virtual bool has_content()
845
- {
846
- return Has_Block::has_content() || (alternative_ && alternative_->has_content());
847
- }
626
+ If(ParserState pstate, Expression_Obj pred, Block_Obj con, Block_Obj alt = {});
627
+ virtual bool has_content() override;
848
628
  ATTACH_AST_OPERATIONS(If)
849
- ATTACH_OPERATIONS()
629
+ ATTACH_CRTP_PERFORM_METHODS()
850
630
  };
851
631
 
852
632
  /////////////////////////////////////
853
633
  // The Sass `@for` control directive.
854
634
  /////////////////////////////////////
855
- class For : public Has_Block {
635
+ class For final : public Has_Block {
856
636
  ADD_CONSTREF(std::string, variable)
857
637
  ADD_PROPERTY(Expression_Obj, lower_bound)
858
638
  ADD_PROPERTY(Expression_Obj, upper_bound)
859
639
  ADD_PROPERTY(bool, is_inclusive)
860
640
  public:
861
- For(ParserState pstate,
862
- std::string var, Expression_Obj lo, Expression_Obj hi, Block_Obj b, bool inc)
863
- : Has_Block(pstate, b),
864
- variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc)
865
- { statement_type(FOR); }
866
- For(const For* ptr)
867
- : Has_Block(ptr),
868
- variable_(ptr->variable_),
869
- lower_bound_(ptr->lower_bound_),
870
- upper_bound_(ptr->upper_bound_),
871
- is_inclusive_(ptr->is_inclusive_)
872
- { statement_type(FOR); }
641
+ For(ParserState pstate, std::string var, Expression_Obj lo, Expression_Obj hi, Block_Obj b, bool inc);
873
642
  ATTACH_AST_OPERATIONS(For)
874
- ATTACH_OPERATIONS()
643
+ ATTACH_CRTP_PERFORM_METHODS()
875
644
  };
876
645
 
877
646
  //////////////////////////////////////
878
647
  // The Sass `@each` control directive.
879
648
  //////////////////////////////////////
880
- class Each : public Has_Block {
649
+ class Each final : public Has_Block {
881
650
  ADD_PROPERTY(std::vector<std::string>, variables)
882
651
  ADD_PROPERTY(Expression_Obj, list)
883
652
  public:
884
- Each(ParserState pstate, std::vector<std::string> vars, Expression_Obj lst, Block_Obj b)
885
- : Has_Block(pstate, b), variables_(vars), list_(lst)
886
- { statement_type(EACH); }
887
- Each(const Each* ptr)
888
- : Has_Block(ptr), variables_(ptr->variables_), list_(ptr->list_)
889
- { statement_type(EACH); }
653
+ Each(ParserState pstate, std::vector<std::string> vars, Expression_Obj lst, Block_Obj b);
890
654
  ATTACH_AST_OPERATIONS(Each)
891
- ATTACH_OPERATIONS()
655
+ ATTACH_CRTP_PERFORM_METHODS()
892
656
  };
893
657
 
894
658
  ///////////////////////////////////////
895
659
  // The Sass `@while` control directive.
896
660
  ///////////////////////////////////////
897
- class While : public Has_Block {
661
+ class While final : public Has_Block {
898
662
  ADD_PROPERTY(Expression_Obj, predicate)
899
663
  public:
900
- While(ParserState pstate, Expression_Obj pred, Block_Obj b)
901
- : Has_Block(pstate, b), predicate_(pred)
902
- { statement_type(WHILE); }
903
- While(const While* ptr)
904
- : Has_Block(ptr), predicate_(ptr->predicate_)
905
- { statement_type(WHILE); }
664
+ While(ParserState pstate, Expression_Obj pred, Block_Obj b);
906
665
  ATTACH_AST_OPERATIONS(While)
907
- ATTACH_OPERATIONS()
666
+ ATTACH_CRTP_PERFORM_METHODS()
908
667
  };
909
668
 
910
669
  /////////////////////////////////////////////////////////////
911
670
  // The @return directive for use inside SassScript functions.
912
671
  /////////////////////////////////////////////////////////////
913
- class Return : public Statement {
672
+ class Return final : public Statement {
914
673
  ADD_PROPERTY(Expression_Obj, value)
915
674
  public:
916
- Return(ParserState pstate, Expression_Obj val)
917
- : Statement(pstate), value_(val)
918
- { statement_type(RETURN); }
919
- Return(const Return* ptr)
920
- : Statement(ptr), value_(ptr->value_)
921
- { statement_type(RETURN); }
675
+ Return(ParserState pstate, Expression_Obj val);
922
676
  ATTACH_AST_OPERATIONS(Return)
923
- ATTACH_OPERATIONS()
677
+ ATTACH_CRTP_PERFORM_METHODS()
924
678
  };
925
679
 
926
680
  ////////////////////////////////
927
681
  // The Sass `@extend` directive.
928
682
  ////////////////////////////////
929
- class Extension : public Statement {
683
+ class Extension final : public Statement {
930
684
  ADD_PROPERTY(Selector_List_Obj, selector)
931
685
  public:
932
- Extension(ParserState pstate, Selector_List_Obj s)
933
- : Statement(pstate), selector_(s)
934
- { statement_type(EXTEND); }
935
- Extension(const Extension* ptr)
936
- : Statement(ptr), selector_(ptr->selector_)
937
- { statement_type(EXTEND); }
686
+ Extension(ParserState pstate, Selector_List_Obj s);
938
687
  ATTACH_AST_OPERATIONS(Extension)
939
- ATTACH_OPERATIONS()
688
+ ATTACH_CRTP_PERFORM_METHODS()
940
689
  };
941
690
 
942
691
  /////////////////////////////////////////////////////////////////////////////
943
692
  // Definitions for both mixins and functions. The two cases are distinguished
944
693
  // by a type tag.
945
694
  /////////////////////////////////////////////////////////////////////////////
946
- struct Backtrace;
947
- typedef const char* Signature;
948
- typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtraces, std::vector<Selector_List_Obj>);
949
- class Definition : public Has_Block {
695
+ class Definition final : public Has_Block {
950
696
  public:
951
697
  enum Type { MIXIN, FUNCTION };
952
698
  ADD_CONSTREF(std::string, name)
@@ -959,439 +705,85 @@ namespace Sass {
959
705
  ADD_PROPERTY(bool, is_overload_stub)
960
706
  ADD_PROPERTY(Signature, signature)
961
707
  public:
962
- Definition(const Definition* ptr)
963
- : Has_Block(ptr),
964
- name_(ptr->name_),
965
- parameters_(ptr->parameters_),
966
- environment_(ptr->environment_),
967
- type_(ptr->type_),
968
- native_function_(ptr->native_function_),
969
- c_function_(ptr->c_function_),
970
- cookie_(ptr->cookie_),
971
- is_overload_stub_(ptr->is_overload_stub_),
972
- signature_(ptr->signature_)
973
- { }
974
-
975
708
  Definition(ParserState pstate,
976
709
  std::string n,
977
710
  Parameters_Obj params,
978
711
  Block_Obj b,
979
- Type t)
980
- : Has_Block(pstate, b),
981
- name_(n),
982
- parameters_(params),
983
- environment_(0),
984
- type_(t),
985
- native_function_(0),
986
- c_function_(0),
987
- cookie_(0),
988
- is_overload_stub_(false),
989
- signature_(0)
990
- { }
712
+ Type t);
991
713
  Definition(ParserState pstate,
992
714
  Signature sig,
993
715
  std::string n,
994
716
  Parameters_Obj params,
995
717
  Native_Function func_ptr,
996
- bool overload_stub = false)
997
- : Has_Block(pstate, 0),
998
- name_(n),
999
- parameters_(params),
1000
- environment_(0),
1001
- type_(FUNCTION),
1002
- native_function_(func_ptr),
1003
- c_function_(0),
1004
- cookie_(0),
1005
- is_overload_stub_(overload_stub),
1006
- signature_(sig)
1007
- { }
718
+ bool overload_stub = false);
1008
719
  Definition(ParserState pstate,
1009
720
  Signature sig,
1010
721
  std::string n,
1011
722
  Parameters_Obj params,
1012
- Sass_Function_Entry c_func,
1013
- bool whatever,
1014
- bool whatever2)
1015
- : Has_Block(pstate, 0),
1016
- name_(n),
1017
- parameters_(params),
1018
- environment_(0),
1019
- type_(FUNCTION),
1020
- native_function_(0),
1021
- c_function_(c_func),
1022
- cookie_(sass_function_get_cookie(c_func)),
1023
- is_overload_stub_(false),
1024
- signature_(sig)
1025
- { }
723
+ Sass_Function_Entry c_func);
1026
724
  ATTACH_AST_OPERATIONS(Definition)
1027
- ATTACH_OPERATIONS()
725
+ ATTACH_CRTP_PERFORM_METHODS()
1028
726
  };
1029
727
 
1030
728
  //////////////////////////////////////
1031
729
  // Mixin calls (i.e., `@include ...`).
1032
730
  //////////////////////////////////////
1033
- class Mixin_Call : public Has_Block {
731
+ class Mixin_Call final : public Has_Block {
1034
732
  ADD_CONSTREF(std::string, name)
1035
733
  ADD_PROPERTY(Arguments_Obj, arguments)
734
+ ADD_PROPERTY(Parameters_Obj, block_parameters)
1036
735
  public:
1037
- Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Block_Obj b = 0)
1038
- : Has_Block(pstate, b), name_(n), arguments_(args)
1039
- { }
1040
- Mixin_Call(const Mixin_Call* ptr)
1041
- : Has_Block(ptr),
1042
- name_(ptr->name_),
1043
- arguments_(ptr->arguments_)
1044
- { }
736
+ Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Parameters_Obj b_params = {}, Block_Obj b = {});
1045
737
  ATTACH_AST_OPERATIONS(Mixin_Call)
1046
- ATTACH_OPERATIONS()
738
+ ATTACH_CRTP_PERFORM_METHODS()
1047
739
  };
1048
740
 
1049
741
  ///////////////////////////////////////////////////
1050
742
  // The @content directive for mixin content blocks.
1051
743
  ///////////////////////////////////////////////////
1052
- class Content : public Statement {
1053
- ADD_PROPERTY(Media_Block_Ptr, media_block)
744
+ class Content final : public Statement {
745
+ ADD_PROPERTY(Arguments_Obj, arguments)
1054
746
  public:
1055
- Content(ParserState pstate)
1056
- : Statement(pstate),
1057
- media_block_(NULL)
1058
- { statement_type(CONTENT); }
1059
- Content(const Content* ptr)
1060
- : Statement(ptr),
1061
- media_block_(ptr->media_block_)
1062
- { statement_type(CONTENT); }
747
+ Content(ParserState pstate, Arguments_Obj args);
1063
748
  ATTACH_AST_OPERATIONS(Content)
1064
- ATTACH_OPERATIONS()
1065
- };
1066
-
1067
- ///////////////////////////////////////////////////////////////////////
1068
- // Lists of values, both comma- and space-separated (distinguished by a
1069
- // type-tag.) Also used to represent variable-length argument lists.
1070
- ///////////////////////////////////////////////////////////////////////
1071
- class List : public Value, public Vectorized<Expression_Obj> {
1072
- void adjust_after_pushing(Expression_Obj e) { is_expanded(false); }
1073
- private:
1074
- ADD_PROPERTY(enum Sass_Separator, separator)
1075
- ADD_PROPERTY(bool, is_arglist)
1076
- ADD_PROPERTY(bool, is_bracketed)
1077
- ADD_PROPERTY(bool, from_selector)
1078
- public:
1079
- List(ParserState pstate,
1080
- size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false, bool bracket = false)
1081
- : Value(pstate),
1082
- Vectorized<Expression_Obj>(size),
1083
- separator_(sep),
1084
- is_arglist_(argl),
1085
- is_bracketed_(bracket),
1086
- from_selector_(false)
1087
- { concrete_type(LIST); }
1088
- List(const List* ptr)
1089
- : Value(ptr),
1090
- Vectorized<Expression_Obj>(*ptr),
1091
- separator_(ptr->separator_),
1092
- is_arglist_(ptr->is_arglist_),
1093
- is_bracketed_(ptr->is_bracketed_),
1094
- from_selector_(ptr->from_selector_)
1095
- { concrete_type(LIST); }
1096
- std::string type() const { return is_arglist_ ? "arglist" : "list"; }
1097
- static std::string type_name() { return "list"; }
1098
- const char* sep_string(bool compressed = false) const {
1099
- return separator() == SASS_SPACE ?
1100
- " " : (compressed ? "," : ", ");
1101
- }
1102
- bool is_invisible() const { return empty() && !is_bracketed(); }
1103
- Expression_Obj value_at_index(size_t i);
1104
-
1105
- virtual size_t size() const;
1106
-
1107
- virtual size_t hash()
1108
- {
1109
- if (hash_ == 0) {
1110
- hash_ = std::hash<std::string>()(sep_string());
1111
- hash_combine(hash_, std::hash<bool>()(is_bracketed()));
1112
- for (size_t i = 0, L = length(); i < L; ++i)
1113
- hash_combine(hash_, (elements()[i])->hash());
1114
- }
1115
- return hash_;
1116
- }
1117
-
1118
- virtual void set_delayed(bool delayed)
1119
- {
1120
- is_delayed(delayed);
1121
- // don't set children
1122
- }
1123
-
1124
- virtual bool operator== (const Expression& rhs) const;
1125
-
1126
- ATTACH_AST_OPERATIONS(List)
1127
- ATTACH_OPERATIONS()
1128
- };
1129
-
1130
- ///////////////////////////////////////////////////////////////////////
1131
- // Key value paris.
1132
- ///////////////////////////////////////////////////////////////////////
1133
- class Map : public Value, public Hashed {
1134
- void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { is_expanded(false); }
1135
- public:
1136
- Map(ParserState pstate,
1137
- size_t size = 0)
1138
- : Value(pstate),
1139
- Hashed(size)
1140
- { concrete_type(MAP); }
1141
- Map(const Map* ptr)
1142
- : Value(ptr),
1143
- Hashed(*ptr)
1144
- { concrete_type(MAP); }
1145
- std::string type() const { return "map"; }
1146
- static std::string type_name() { return "map"; }
1147
- bool is_invisible() const { return empty(); }
1148
- List_Obj to_list(ParserState& pstate);
1149
-
1150
- virtual size_t hash()
1151
- {
1152
- if (hash_ == 0) {
1153
- for (auto key : keys()) {
1154
- hash_combine(hash_, key->hash());
1155
- hash_combine(hash_, at(key)->hash());
1156
- }
1157
- }
1158
-
1159
- return hash_;
1160
- }
1161
-
1162
- virtual bool operator== (const Expression& rhs) const;
1163
-
1164
- ATTACH_AST_OPERATIONS(Map)
1165
- ATTACH_OPERATIONS()
1166
- };
1167
-
1168
- inline static const std::string sass_op_to_name(enum Sass_OP op) {
1169
- switch (op) {
1170
- case AND: return "and";
1171
- case OR: return "or";
1172
- case EQ: return "eq";
1173
- case NEQ: return "neq";
1174
- case GT: return "gt";
1175
- case GTE: return "gte";
1176
- case LT: return "lt";
1177
- case LTE: return "lte";
1178
- case ADD: return "plus";
1179
- case SUB: return "sub";
1180
- case MUL: return "times";
1181
- case DIV: return "div";
1182
- case MOD: return "mod";
1183
- // this is only used internally!
1184
- case NUM_OPS: return "[OPS]";
1185
- default: return "invalid";
1186
- }
1187
- }
1188
-
1189
- inline static const std::string sass_op_separator(enum Sass_OP op) {
1190
- switch (op) {
1191
- case AND: return "&&";
1192
- case OR: return "||";
1193
- case EQ: return "==";
1194
- case NEQ: return "!=";
1195
- case GT: return ">";
1196
- case GTE: return ">=";
1197
- case LT: return "<";
1198
- case LTE: return "<=";
1199
- case ADD: return "+";
1200
- case SUB: return "-";
1201
- case MUL: return "*";
1202
- case DIV: return "/";
1203
- case MOD: return "%";
1204
- // this is only used internally!
1205
- case NUM_OPS: return "[OPS]";
1206
- default: return "invalid";
1207
- }
1208
- }
1209
-
1210
- //////////////////////////////////////////////////////////////////////////
1211
- // Binary expressions. Represents logical, relational, and arithmetic
1212
- // operations. Templatized to avoid large switch statements and repetitive
1213
- // subclassing.
1214
- //////////////////////////////////////////////////////////////////////////
1215
- class Binary_Expression : public PreValue {
1216
- private:
1217
- HASH_PROPERTY(Operand, op)
1218
- HASH_PROPERTY(Expression_Obj, left)
1219
- HASH_PROPERTY(Expression_Obj, right)
1220
- size_t hash_;
1221
- public:
1222
- Binary_Expression(ParserState pstate,
1223
- Operand op, Expression_Obj lhs, Expression_Obj rhs)
1224
- : PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)
1225
- { }
1226
- Binary_Expression(const Binary_Expression* ptr)
1227
- : PreValue(ptr),
1228
- op_(ptr->op_),
1229
- left_(ptr->left_),
1230
- right_(ptr->right_),
1231
- hash_(ptr->hash_)
1232
- { }
1233
- const std::string type_name() {
1234
- return sass_op_to_name(optype());
1235
- }
1236
- const std::string separator() {
1237
- return sass_op_separator(optype());
1238
- }
1239
- bool is_left_interpolant(void) const;
1240
- bool is_right_interpolant(void) const;
1241
- bool has_interpolant() const
1242
- {
1243
- return is_left_interpolant() ||
1244
- is_right_interpolant();
1245
- }
1246
- virtual void set_delayed(bool delayed)
1247
- {
1248
- right()->set_delayed(delayed);
1249
- left()->set_delayed(delayed);
1250
- is_delayed(delayed);
1251
- }
1252
- virtual bool operator==(const Expression& rhs) const
1253
- {
1254
- try
1255
- {
1256
- Binary_Expression_Ptr_Const m = Cast<Binary_Expression>(&rhs);
1257
- if (m == 0) return false;
1258
- return type() == m->type() &&
1259
- *left() == *m->left() &&
1260
- *right() == *m->right();
1261
- }
1262
- catch (std::bad_cast&)
1263
- {
1264
- return false;
1265
- }
1266
- catch (...) { throw; }
1267
- }
1268
- virtual size_t hash()
1269
- {
1270
- if (hash_ == 0) {
1271
- hash_ = std::hash<size_t>()(optype());
1272
- hash_combine(hash_, left()->hash());
1273
- hash_combine(hash_, right()->hash());
1274
- }
1275
- return hash_;
1276
- }
1277
- enum Sass_OP optype() const { return op_.operand; }
1278
- ATTACH_AST_OPERATIONS(Binary_Expression)
1279
- ATTACH_OPERATIONS()
749
+ ATTACH_CRTP_PERFORM_METHODS()
1280
750
  };
1281
751
 
1282
752
  ////////////////////////////////////////////////////////////////////////////
1283
753
  // Arithmetic negation (logical negation is just an ordinary function call).
1284
754
  ////////////////////////////////////////////////////////////////////////////
1285
- class Unary_Expression : public Expression {
755
+ class Unary_Expression final : public Expression {
1286
756
  public:
1287
757
  enum Type { PLUS, MINUS, NOT, SLASH };
1288
758
  private:
1289
759
  HASH_PROPERTY(Type, optype)
1290
760
  HASH_PROPERTY(Expression_Obj, operand)
1291
- size_t hash_;
761
+ mutable size_t hash_;
1292
762
  public:
1293
- Unary_Expression(ParserState pstate, Type t, Expression_Obj o)
1294
- : Expression(pstate), optype_(t), operand_(o), hash_(0)
1295
- { }
1296
- Unary_Expression(const Unary_Expression* ptr)
1297
- : Expression(ptr),
1298
- optype_(ptr->optype_),
1299
- operand_(ptr->operand_),
1300
- hash_(ptr->hash_)
1301
- { }
1302
- const std::string type_name() {
1303
- switch (optype_) {
1304
- case PLUS: return "plus";
1305
- case MINUS: return "minus";
1306
- case SLASH: return "slash";
1307
- case NOT: return "not";
1308
- default: return "invalid";
1309
- }
1310
- }
1311
- virtual bool operator==(const Expression& rhs) const
1312
- {
1313
- try
1314
- {
1315
- Unary_Expression_Ptr_Const m = Cast<Unary_Expression>(&rhs);
1316
- if (m == 0) return false;
1317
- return type() == m->type() &&
1318
- *operand() == *m->operand();
1319
- }
1320
- catch (std::bad_cast&)
1321
- {
1322
- return false;
1323
- }
1324
- catch (...) { throw; }
1325
- }
1326
- virtual size_t hash()
1327
- {
1328
- if (hash_ == 0) {
1329
- hash_ = std::hash<size_t>()(optype_);
1330
- hash_combine(hash_, operand()->hash());
1331
- };
1332
- return hash_;
1333
- }
763
+ Unary_Expression(ParserState pstate, Type t, Expression_Obj o);
764
+ const std::string type_name();
765
+ virtual bool operator==(const Expression& rhs) const override;
766
+ size_t hash() const override;
1334
767
  ATTACH_AST_OPERATIONS(Unary_Expression)
1335
- ATTACH_OPERATIONS()
768
+ ATTACH_CRTP_PERFORM_METHODS()
1336
769
  };
1337
770
 
1338
771
  ////////////////////////////////////////////////////////////
1339
772
  // Individual argument objects for mixin and function calls.
1340
773
  ////////////////////////////////////////////////////////////
1341
- class Argument : public Expression {
774
+ class Argument final : public Expression {
1342
775
  HASH_PROPERTY(Expression_Obj, value)
1343
776
  HASH_CONSTREF(std::string, name)
1344
777
  ADD_PROPERTY(bool, is_rest_argument)
1345
778
  ADD_PROPERTY(bool, is_keyword_argument)
1346
- size_t hash_;
779
+ mutable size_t hash_;
1347
780
  public:
1348
- Argument(ParserState pstate, Expression_Obj val, std::string n = "", bool rest = false, bool keyword = false)
1349
- : Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)
1350
- {
1351
- if (!name_.empty() && is_rest_argument_) {
1352
- coreError("variable-length argument may not be passed by name", pstate_);
1353
- }
1354
- }
1355
- Argument(const Argument* ptr)
1356
- : Expression(ptr),
1357
- value_(ptr->value_),
1358
- name_(ptr->name_),
1359
- is_rest_argument_(ptr->is_rest_argument_),
1360
- is_keyword_argument_(ptr->is_keyword_argument_),
1361
- hash_(ptr->hash_)
1362
- {
1363
- if (!name_.empty() && is_rest_argument_) {
1364
- coreError("variable-length argument may not be passed by name", pstate_);
1365
- }
1366
- }
1367
-
1368
- virtual void set_delayed(bool delayed);
1369
- virtual bool operator==(const Expression& rhs) const
1370
- {
1371
- try
1372
- {
1373
- Argument_Ptr_Const m = Cast<Argument>(&rhs);
1374
- if (!(m && name() == m->name())) return false;
1375
- return *value() == *m->value();
1376
- }
1377
- catch (std::bad_cast&)
1378
- {
1379
- return false;
1380
- }
1381
- catch (...) { throw; }
1382
- }
1383
-
1384
- virtual size_t hash()
1385
- {
1386
- if (hash_ == 0) {
1387
- hash_ = std::hash<std::string>()(name());
1388
- hash_combine(hash_, value()->hash());
1389
- }
1390
- return hash_;
1391
- }
1392
-
781
+ Argument(ParserState pstate, Expression_Obj val, std::string n = "", bool rest = false, bool keyword = false);
782
+ void set_delayed(bool delayed) override;
783
+ bool operator==(const Expression& rhs) const override;
784
+ size_t hash() const override;
1393
785
  ATTACH_AST_OPERATIONS(Argument)
1394
- ATTACH_OPERATIONS()
786
+ ATTACH_CRTP_PERFORM_METHODS()
1395
787
  };
1396
788
 
1397
789
  ////////////////////////////////////////////////////////////////////////
@@ -1399,1650 +791,114 @@ namespace Sass {
1399
791
  // error checking (e.g., ensuring that all ordinal arguments precede all
1400
792
  // named arguments).
1401
793
  ////////////////////////////////////////////////////////////////////////
1402
- class Arguments : public Expression, public Vectorized<Argument_Obj> {
794
+ class Arguments final : public Expression, public Vectorized<Argument_Obj> {
1403
795
  ADD_PROPERTY(bool, has_named_arguments)
1404
796
  ADD_PROPERTY(bool, has_rest_argument)
1405
797
  ADD_PROPERTY(bool, has_keyword_argument)
1406
798
  protected:
1407
- void adjust_after_pushing(Argument_Obj a);
799
+ void adjust_after_pushing(Argument_Obj a) override;
1408
800
  public:
1409
- Arguments(ParserState pstate)
1410
- : Expression(pstate),
1411
- Vectorized<Argument_Obj>(),
1412
- has_named_arguments_(false),
1413
- has_rest_argument_(false),
1414
- has_keyword_argument_(false)
1415
- { }
1416
- Arguments(const Arguments* ptr)
1417
- : Expression(ptr),
1418
- Vectorized<Argument_Obj>(*ptr),
1419
- has_named_arguments_(ptr->has_named_arguments_),
1420
- has_rest_argument_(ptr->has_rest_argument_),
1421
- has_keyword_argument_(ptr->has_keyword_argument_)
1422
- { }
1423
-
1424
- virtual void set_delayed(bool delayed);
1425
-
801
+ Arguments(ParserState pstate);
802
+ void set_delayed(bool delayed) override;
1426
803
  Argument_Obj get_rest_argument();
1427
804
  Argument_Obj get_keyword_argument();
1428
-
1429
805
  ATTACH_AST_OPERATIONS(Arguments)
1430
- ATTACH_OPERATIONS()
806
+ ATTACH_CRTP_PERFORM_METHODS()
807
+ };
808
+
809
+ /////////////////
810
+ // Media queries.
811
+ /////////////////
812
+ class Media_Query final : public Expression,
813
+ public Vectorized<Media_Query_Expression_Obj> {
814
+ ADD_PROPERTY(String_Obj, media_type)
815
+ ADD_PROPERTY(bool, is_negated)
816
+ ADD_PROPERTY(bool, is_restricted)
817
+ public:
818
+ Media_Query(ParserState pstate, String_Obj t = {}, size_t s = 0, bool n = false, bool r = false);
819
+ ATTACH_AST_OPERATIONS(Media_Query)
820
+ ATTACH_CRTP_PERFORM_METHODS()
1431
821
  };
1432
822
 
1433
823
  ////////////////////////////////////////////////////
1434
- // Function reference.
824
+ // Media expressions (for use inside media queries).
1435
825
  ////////////////////////////////////////////////////
1436
- class Function : public Value {
1437
- public:
1438
- ADD_PROPERTY(Definition_Obj, definition)
1439
- ADD_PROPERTY(bool, is_css)
826
+ class Media_Query_Expression final : public Expression {
827
+ ADD_PROPERTY(Expression_Obj, feature)
828
+ ADD_PROPERTY(Expression_Obj, value)
829
+ ADD_PROPERTY(bool, is_interpolated)
1440
830
  public:
1441
- Function(ParserState pstate, Definition_Obj def, bool css)
1442
- : Value(pstate), definition_(def), is_css_(css)
1443
- { concrete_type(FUNCTION_VAL); }
1444
- Function(const Function* ptr)
1445
- : Value(ptr), definition_(ptr->definition_), is_css_(ptr->is_css_)
1446
- { concrete_type(FUNCTION_VAL); }
1447
-
1448
- std::string type() const { return "function"; }
1449
- static std::string type_name() { return "function"; }
1450
- bool is_invisible() const { return true; }
1451
-
1452
- std::string name() {
1453
- if (definition_) {
1454
- return definition_->name();
1455
- }
1456
- return "";
1457
- }
1458
-
1459
- virtual bool operator== (const Expression& rhs) const;
1460
-
1461
- ATTACH_AST_OPERATIONS(Function)
1462
- ATTACH_OPERATIONS()
831
+ Media_Query_Expression(ParserState pstate, Expression_Obj f, Expression_Obj v, bool i = false);
832
+ ATTACH_AST_OPERATIONS(Media_Query_Expression)
833
+ ATTACH_CRTP_PERFORM_METHODS()
1463
834
  };
1464
835
 
1465
- //////////////////
1466
- // Function calls.
1467
- //////////////////
1468
- class Function_Call : public PreValue {
1469
- HASH_CONSTREF(std::string, name)
1470
- HASH_PROPERTY(Arguments_Obj, arguments)
1471
- HASH_PROPERTY(Function_Obj, func)
1472
- ADD_PROPERTY(bool, via_call)
1473
- ADD_PROPERTY(void*, cookie)
1474
- size_t hash_;
836
+ /////////////////////////////////////////////////
837
+ // At root expressions (for use inside @at-root).
838
+ /////////////////////////////////////////////////
839
+ class At_Root_Query final : public Expression {
840
+ private:
841
+ ADD_PROPERTY(Expression_Obj, feature)
842
+ ADD_PROPERTY(Expression_Obj, value)
1475
843
  public:
1476
- Function_Call(ParserState pstate, std::string n, Arguments_Obj args, void* cookie)
1477
- : PreValue(pstate), name_(n), arguments_(args), func_(0), via_call_(false), cookie_(cookie), hash_(0)
1478
- { concrete_type(FUNCTION); }
1479
- Function_Call(ParserState pstate, std::string n, Arguments_Obj args, Function_Obj func)
1480
- : PreValue(pstate), name_(n), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
1481
- { concrete_type(FUNCTION); }
1482
- Function_Call(ParserState pstate, std::string n, Arguments_Obj args)
1483
- : PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)
1484
- { concrete_type(FUNCTION); }
1485
- Function_Call(const Function_Call* ptr)
1486
- : PreValue(ptr),
1487
- name_(ptr->name_),
1488
- arguments_(ptr->arguments_),
1489
- func_(ptr->func_),
1490
- via_call_(ptr->via_call_),
1491
- cookie_(ptr->cookie_),
1492
- hash_(ptr->hash_)
1493
- { concrete_type(FUNCTION); }
1494
-
1495
- bool is_css() {
1496
- if (func_) return func_->is_css();
1497
- return false;
1498
- }
1499
-
1500
- virtual bool operator==(const Expression& rhs) const
1501
- {
1502
- try
1503
- {
1504
- Function_Call_Ptr_Const m = Cast<Function_Call>(&rhs);
1505
- if (!(m && name() == m->name())) return false;
1506
- if (!(m && arguments()->length() == m->arguments()->length())) return false;
1507
- for (size_t i =0, L = arguments()->length(); i < L; ++i)
1508
- if (!(*(*arguments())[i] == *(*m->arguments())[i])) return false;
1509
- return true;
1510
- }
1511
- catch (std::bad_cast&)
1512
- {
1513
- return false;
1514
- }
1515
- catch (...) { throw; }
1516
- }
1517
-
1518
- virtual size_t hash()
1519
- {
1520
- if (hash_ == 0) {
1521
- hash_ = std::hash<std::string>()(name());
1522
- for (auto argument : arguments()->elements())
1523
- hash_combine(hash_, argument->hash());
1524
- }
1525
- return hash_;
1526
- }
1527
- ATTACH_AST_OPERATIONS(Function_Call)
1528
- ATTACH_OPERATIONS()
844
+ At_Root_Query(ParserState pstate, Expression_Obj f = {}, Expression_Obj v = {}, bool i = false);
845
+ bool exclude(std::string str);
846
+ ATTACH_AST_OPERATIONS(At_Root_Query)
847
+ ATTACH_CRTP_PERFORM_METHODS()
1529
848
  };
1530
849
 
1531
- /////////////////////////
1532
- // Function call schemas.
1533
- /////////////////////////
1534
- class Function_Call_Schema : public Expression {
1535
- ADD_PROPERTY(String_Obj, name)
1536
- ADD_PROPERTY(Arguments_Obj, arguments)
850
+ ///////////
851
+ // At-root.
852
+ ///////////
853
+ class At_Root_Block final : public Has_Block {
854
+ ADD_PROPERTY(At_Root_Query_Obj, expression)
1537
855
  public:
1538
- Function_Call_Schema(ParserState pstate, String_Obj n, Arguments_Obj args)
1539
- : Expression(pstate), name_(n), arguments_(args)
1540
- { concrete_type(STRING); }
1541
- Function_Call_Schema(const Function_Call_Schema* ptr)
1542
- : Expression(ptr),
1543
- name_(ptr->name_),
1544
- arguments_(ptr->arguments_)
1545
- { concrete_type(STRING); }
1546
- ATTACH_AST_OPERATIONS(Function_Call_Schema)
1547
- ATTACH_OPERATIONS()
856
+ At_Root_Block(ParserState pstate, Block_Obj b = {}, At_Root_Query_Obj e = {});
857
+ bool bubbles() override;
858
+ bool exclude_node(Statement_Obj s);
859
+ ATTACH_AST_OPERATIONS(At_Root_Block)
860
+ ATTACH_CRTP_PERFORM_METHODS()
1548
861
  };
1549
862
 
1550
- ///////////////////////
1551
- // Variable references.
1552
- ///////////////////////
1553
- class Variable : public PreValue {
863
+ /////////////////////////////////////////////////////////
864
+ // Individual parameter objects for mixins and functions.
865
+ /////////////////////////////////////////////////////////
866
+ class Parameter final : public AST_Node {
1554
867
  ADD_CONSTREF(std::string, name)
868
+ ADD_PROPERTY(Expression_Obj, default_value)
869
+ ADD_PROPERTY(bool, is_rest_parameter)
1555
870
  public:
1556
- Variable(ParserState pstate, std::string n)
1557
- : PreValue(pstate), name_(n)
1558
- { concrete_type(VARIABLE); }
1559
- Variable(const Variable* ptr)
1560
- : PreValue(ptr), name_(ptr->name_)
1561
- { concrete_type(VARIABLE); }
1562
-
1563
- virtual bool operator==(const Expression& rhs) const
1564
- {
1565
- try
1566
- {
1567
- Variable_Ptr_Const e = Cast<Variable>(&rhs);
1568
- return e && name() == e->name();
1569
- }
1570
- catch (std::bad_cast&)
1571
- {
1572
- return false;
1573
- }
1574
- catch (...) { throw; }
1575
- }
1576
-
1577
- virtual size_t hash()
1578
- {
1579
- return std::hash<std::string>()(name());
1580
- }
1581
-
1582
- ATTACH_AST_OPERATIONS(Variable)
1583
- ATTACH_OPERATIONS()
871
+ Parameter(ParserState pstate, std::string n, Expression_Obj def = {}, bool rest = false);
872
+ ATTACH_AST_OPERATIONS(Parameter)
873
+ ATTACH_CRTP_PERFORM_METHODS()
1584
874
  };
1585
875
 
1586
- ////////////////////////////////////////////////
1587
- // Numbers, percentages, dimensions, and colors.
1588
- ////////////////////////////////////////////////
1589
- class Number : public Value, public Units {
1590
- HASH_PROPERTY(double, value)
1591
- ADD_PROPERTY(bool, zero)
1592
- size_t hash_;
876
+ /////////////////////////////////////////////////////////////////////////
877
+ // Parameter lists -- in their own class to facilitate context-sensitive
878
+ // error checking (e.g., ensuring that all optional parameters follow all
879
+ // required parameters).
880
+ /////////////////////////////////////////////////////////////////////////
881
+ class Parameters final : public AST_Node, public Vectorized<Parameter_Obj> {
882
+ ADD_PROPERTY(bool, has_optional_parameters)
883
+ ADD_PROPERTY(bool, has_rest_parameter)
884
+ protected:
885
+ void adjust_after_pushing(Parameter_Obj p) override;
1593
886
  public:
1594
- Number(ParserState pstate, double val, std::string u = "", bool zero = true);
1595
-
1596
- Number(const Number* ptr)
1597
- : Value(ptr),
1598
- Units(ptr),
1599
- value_(ptr->value_), zero_(ptr->zero_),
1600
- hash_(ptr->hash_)
1601
- { concrete_type(NUMBER); }
1602
-
1603
- bool zero() { return zero_; }
1604
- std::string type() const { return "number"; }
1605
- static std::string type_name() { return "number"; }
1606
-
1607
- void reduce();
1608
- void normalize();
1609
-
1610
- virtual size_t hash()
1611
- {
1612
- if (hash_ == 0) {
1613
- hash_ = std::hash<double>()(value_);
1614
- for (const auto numerator : numerators)
1615
- hash_combine(hash_, std::hash<std::string>()(numerator));
1616
- for (const auto denominator : denominators)
1617
- hash_combine(hash_, std::hash<std::string>()(denominator));
1618
- }
1619
- return hash_;
1620
- }
1621
-
1622
- virtual bool operator< (const Number& rhs) const;
1623
- virtual bool operator== (const Number& rhs) const;
1624
- virtual bool operator== (const Expression& rhs) const;
1625
- ATTACH_AST_OPERATIONS(Number)
1626
- ATTACH_OPERATIONS()
887
+ Parameters(ParserState pstate);
888
+ ATTACH_AST_OPERATIONS(Parameters)
889
+ ATTACH_CRTP_PERFORM_METHODS()
1627
890
  };
1628
891
 
1629
- //////////
1630
- // Colors.
1631
- //////////
1632
- class Color : public Value {
1633
- HASH_PROPERTY(double, r)
1634
- HASH_PROPERTY(double, g)
1635
- HASH_PROPERTY(double, b)
1636
- HASH_PROPERTY(double, a)
1637
- ADD_CONSTREF(std::string, disp)
1638
- size_t hash_;
1639
- public:
1640
- Color(ParserState pstate, double r, double g, double b, double a = 1, const std::string disp = "")
1641
- : Value(pstate), r_(r), g_(g), b_(b), a_(a), disp_(disp),
1642
- hash_(0)
1643
- { concrete_type(COLOR); }
1644
- Color(const Color* ptr)
1645
- : Value(ptr),
1646
- r_(ptr->r_),
1647
- g_(ptr->g_),
1648
- b_(ptr->b_),
1649
- a_(ptr->a_),
1650
- disp_(ptr->disp_),
1651
- hash_(ptr->hash_)
1652
- { concrete_type(COLOR); }
1653
- std::string type() const { return "color"; }
1654
- static std::string type_name() { return "color"; }
1655
-
1656
- virtual size_t hash()
1657
- {
1658
- if (hash_ == 0) {
1659
- hash_ = std::hash<double>()(a_);
1660
- hash_combine(hash_, std::hash<double>()(r_));
1661
- hash_combine(hash_, std::hash<double>()(g_));
1662
- hash_combine(hash_, std::hash<double>()(b_));
1663
- }
1664
- return hash_;
1665
- }
1666
-
1667
- virtual bool operator== (const Expression& rhs) const;
1668
-
1669
- ATTACH_AST_OPERATIONS(Color)
1670
- ATTACH_OPERATIONS()
1671
- };
1672
-
1673
- //////////////////////////////
1674
- // Errors from Sass_Values.
1675
- //////////////////////////////
1676
- class Custom_Error : public Value {
1677
- ADD_CONSTREF(std::string, message)
1678
- public:
1679
- Custom_Error(ParserState pstate, std::string msg)
1680
- : Value(pstate), message_(msg)
1681
- { concrete_type(C_ERROR); }
1682
- Custom_Error(const Custom_Error* ptr)
1683
- : Value(ptr), message_(ptr->message_)
1684
- { concrete_type(C_ERROR); }
1685
- virtual bool operator== (const Expression& rhs) const;
1686
- ATTACH_AST_OPERATIONS(Custom_Error)
1687
- ATTACH_OPERATIONS()
1688
- };
1689
-
1690
- //////////////////////////////
1691
- // Warnings from Sass_Values.
1692
- //////////////////////////////
1693
- class Custom_Warning : public Value {
1694
- ADD_CONSTREF(std::string, message)
1695
- public:
1696
- Custom_Warning(ParserState pstate, std::string msg)
1697
- : Value(pstate), message_(msg)
1698
- { concrete_type(C_WARNING); }
1699
- Custom_Warning(const Custom_Warning* ptr)
1700
- : Value(ptr), message_(ptr->message_)
1701
- { concrete_type(C_WARNING); }
1702
- virtual bool operator== (const Expression& rhs) const;
1703
- ATTACH_AST_OPERATIONS(Custom_Warning)
1704
- ATTACH_OPERATIONS()
1705
- };
1706
-
1707
- ////////////
1708
- // Booleans.
1709
- ////////////
1710
- class Boolean : public Value {
1711
- HASH_PROPERTY(bool, value)
1712
- size_t hash_;
1713
- public:
1714
- Boolean(ParserState pstate, bool val)
1715
- : Value(pstate), value_(val),
1716
- hash_(0)
1717
- { concrete_type(BOOLEAN); }
1718
- Boolean(const Boolean* ptr)
1719
- : Value(ptr),
1720
- value_(ptr->value_),
1721
- hash_(ptr->hash_)
1722
- { concrete_type(BOOLEAN); }
1723
- virtual operator bool() { return value_; }
1724
- std::string type() const { return "bool"; }
1725
- static std::string type_name() { return "bool"; }
1726
- virtual bool is_false() { return !value_; }
1727
-
1728
- virtual size_t hash()
1729
- {
1730
- if (hash_ == 0) {
1731
- hash_ = std::hash<bool>()(value_);
1732
- }
1733
- return hash_;
1734
- }
1735
-
1736
- virtual bool operator== (const Expression& rhs) const;
1737
-
1738
- ATTACH_AST_OPERATIONS(Boolean)
1739
- ATTACH_OPERATIONS()
1740
- };
1741
-
1742
- ////////////////////////////////////////////////////////////////////////
1743
- // Abstract base class for Sass string values. Includes interpolated and
1744
- // "flat" strings.
1745
- ////////////////////////////////////////////////////////////////////////
1746
- class String : public Value {
1747
- public:
1748
- String(ParserState pstate, bool delayed = false)
1749
- : Value(pstate, delayed)
1750
- { concrete_type(STRING); }
1751
- String(const String* ptr)
1752
- : Value(ptr)
1753
- { concrete_type(STRING); }
1754
- static std::string type_name() { return "string"; }
1755
- virtual ~String() = 0;
1756
- virtual void rtrim() = 0;
1757
- virtual bool operator==(const Expression& rhs) const = 0;
1758
- virtual bool operator<(const Expression& rhs) const {
1759
- return this->to_string() < rhs.to_string();
1760
- };
1761
- ATTACH_VIRTUAL_AST_OPERATIONS(String);
1762
- ATTACH_OPERATIONS()
1763
- };
1764
- inline String::~String() { };
1765
-
1766
- ///////////////////////////////////////////////////////////////////////
1767
- // Interpolated strings. Meant to be reduced to flat strings during the
1768
- // evaluation phase.
1769
- ///////////////////////////////////////////////////////////////////////
1770
- class String_Schema : public String, public Vectorized<Expression_Obj> {
1771
- ADD_PROPERTY(bool, css)
1772
- size_t hash_;
1773
- public:
1774
- String_Schema(ParserState pstate, size_t size = 0, bool css = true)
1775
- : String(pstate), Vectorized<Expression_Obj>(size), css_(css), hash_(0)
1776
- { concrete_type(STRING); }
1777
- String_Schema(const String_Schema* ptr)
1778
- : String(ptr),
1779
- Vectorized<Expression_Obj>(*ptr),
1780
- css_(ptr->css_),
1781
- hash_(ptr->hash_)
1782
- { concrete_type(STRING); }
1783
-
1784
- std::string type() const { return "string"; }
1785
- static std::string type_name() { return "string"; }
1786
-
1787
- bool is_left_interpolant(void) const;
1788
- bool is_right_interpolant(void) const;
1789
- // void has_interpolants(bool tc) { }
1790
- bool has_interpolants() {
1791
- for (auto el : elements()) {
1792
- if (el->is_interpolant()) return true;
1793
- }
1794
- return false;
1795
- }
1796
- virtual void rtrim();
1797
-
1798
- virtual size_t hash()
1799
- {
1800
- if (hash_ == 0) {
1801
- for (auto string : elements())
1802
- hash_combine(hash_, string->hash());
1803
- }
1804
- return hash_;
1805
- }
1806
-
1807
- virtual void set_delayed(bool delayed) {
1808
- is_delayed(delayed);
1809
- }
1810
-
1811
- virtual bool operator==(const Expression& rhs) const;
1812
- ATTACH_AST_OPERATIONS(String_Schema)
1813
- ATTACH_OPERATIONS()
1814
- };
1815
-
1816
- ////////////////////////////////////////////////////////
1817
- // Flat strings -- the lowest level of raw textual data.
1818
- ////////////////////////////////////////////////////////
1819
- class String_Constant : public String {
1820
- ADD_PROPERTY(char, quote_mark)
1821
- ADD_PROPERTY(bool, can_compress_whitespace)
1822
- HASH_CONSTREF(std::string, value)
1823
- protected:
1824
- size_t hash_;
1825
- public:
1826
- String_Constant(const String_Constant* ptr)
1827
- : String(ptr),
1828
- quote_mark_(ptr->quote_mark_),
1829
- can_compress_whitespace_(ptr->can_compress_whitespace_),
1830
- value_(ptr->value_),
1831
- hash_(ptr->hash_)
1832
- { }
1833
- String_Constant(ParserState pstate, std::string val, bool css = true)
1834
- : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val, css)), hash_(0)
1835
- { }
1836
- String_Constant(ParserState pstate, const char* beg, bool css = true)
1837
- : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg), css)), hash_(0)
1838
- { }
1839
- String_Constant(ParserState pstate, const char* beg, const char* end, bool css = true)
1840
- : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg), css)), hash_(0)
1841
- { }
1842
- String_Constant(ParserState pstate, const Token& tok, bool css = true)
1843
- : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end), css)), hash_(0)
1844
- { }
1845
- std::string type() const { return "string"; }
1846
- static std::string type_name() { return "string"; }
1847
- virtual bool is_invisible() const;
1848
- virtual void rtrim();
1849
-
1850
- virtual size_t hash()
1851
- {
1852
- if (hash_ == 0) {
1853
- hash_ = std::hash<std::string>()(value_);
1854
- }
1855
- return hash_;
1856
- }
1857
-
1858
- virtual bool operator==(const Expression& rhs) const;
1859
- virtual std::string inspect() const; // quotes are forced on inspection
1860
-
1861
- // static char auto_quote() { return '*'; }
1862
- static char double_quote() { return '"'; }
1863
- static char single_quote() { return '\''; }
1864
-
1865
- ATTACH_AST_OPERATIONS(String_Constant)
1866
- ATTACH_OPERATIONS()
1867
- };
1868
-
1869
- ////////////////////////////////////////////////////////
1870
- // Possibly quoted string (unquote on instantiation)
1871
- ////////////////////////////////////////////////////////
1872
- class String_Quoted : public String_Constant {
1873
- public:
1874
- String_Quoted(ParserState pstate, std::string val, char q = 0,
1875
- bool keep_utf8_escapes = false, bool skip_unquoting = false,
1876
- bool strict_unquoting = true, bool css = true)
1877
- : String_Constant(pstate, val, css)
1878
- {
1879
- if (skip_unquoting == false) {
1880
- value_ = unquote(value_, &quote_mark_, keep_utf8_escapes, strict_unquoting);
1881
- }
1882
- if (q && quote_mark_) quote_mark_ = q;
1883
- }
1884
- String_Quoted(const String_Quoted* ptr)
1885
- : String_Constant(ptr)
1886
- { }
1887
- virtual bool operator==(const Expression& rhs) const;
1888
- virtual std::string inspect() const; // quotes are forced on inspection
1889
- ATTACH_AST_OPERATIONS(String_Quoted)
1890
- ATTACH_OPERATIONS()
1891
- };
1892
-
1893
- /////////////////
1894
- // Media queries.
1895
- /////////////////
1896
- class Media_Query : public Expression,
1897
- public Vectorized<Media_Query_Expression_Obj> {
1898
- ADD_PROPERTY(String_Obj, media_type)
1899
- ADD_PROPERTY(bool, is_negated)
1900
- ADD_PROPERTY(bool, is_restricted)
1901
- public:
1902
- Media_Query(ParserState pstate,
1903
- String_Obj t = 0, size_t s = 0, bool n = false, bool r = false)
1904
- : Expression(pstate), Vectorized<Media_Query_Expression_Obj>(s),
1905
- media_type_(t), is_negated_(n), is_restricted_(r)
1906
- { }
1907
- Media_Query(const Media_Query* ptr)
1908
- : Expression(ptr),
1909
- Vectorized<Media_Query_Expression_Obj>(*ptr),
1910
- media_type_(ptr->media_type_),
1911
- is_negated_(ptr->is_negated_),
1912
- is_restricted_(ptr->is_restricted_)
1913
- { }
1914
- ATTACH_AST_OPERATIONS(Media_Query)
1915
- ATTACH_OPERATIONS()
1916
- };
1917
-
1918
- ////////////////////////////////////////////////////
1919
- // Media expressions (for use inside media queries).
1920
- ////////////////////////////////////////////////////
1921
- class Media_Query_Expression : public Expression {
1922
- ADD_PROPERTY(Expression_Obj, feature)
1923
- ADD_PROPERTY(Expression_Obj, value)
1924
- ADD_PROPERTY(bool, is_interpolated)
1925
- public:
1926
- Media_Query_Expression(ParserState pstate,
1927
- Expression_Obj f, Expression_Obj v, bool i = false)
1928
- : Expression(pstate), feature_(f), value_(v), is_interpolated_(i)
1929
- { }
1930
- Media_Query_Expression(const Media_Query_Expression* ptr)
1931
- : Expression(ptr),
1932
- feature_(ptr->feature_),
1933
- value_(ptr->value_),
1934
- is_interpolated_(ptr->is_interpolated_)
1935
- { }
1936
- ATTACH_AST_OPERATIONS(Media_Query_Expression)
1937
- ATTACH_OPERATIONS()
1938
- };
1939
-
1940
- ////////////////////
1941
- // `@supports` rule.
1942
- ////////////////////
1943
- class Supports_Block : public Has_Block {
1944
- ADD_PROPERTY(Supports_Condition_Obj, condition)
1945
- public:
1946
- Supports_Block(ParserState pstate, Supports_Condition_Obj condition, Block_Obj block = 0)
1947
- : Has_Block(pstate, block), condition_(condition)
1948
- { statement_type(SUPPORTS); }
1949
- Supports_Block(const Supports_Block* ptr)
1950
- : Has_Block(ptr), condition_(ptr->condition_)
1951
- { statement_type(SUPPORTS); }
1952
- bool bubbles() { return true; }
1953
- ATTACH_AST_OPERATIONS(Supports_Block)
1954
- ATTACH_OPERATIONS()
1955
- };
1956
-
1957
- //////////////////////////////////////////////////////
1958
- // The abstract superclass of all Supports conditions.
1959
- //////////////////////////////////////////////////////
1960
- class Supports_Condition : public Expression {
1961
- public:
1962
- Supports_Condition(ParserState pstate)
1963
- : Expression(pstate)
1964
- { }
1965
- Supports_Condition(const Supports_Condition* ptr)
1966
- : Expression(ptr)
1967
- { }
1968
- virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
1969
- ATTACH_AST_OPERATIONS(Supports_Condition)
1970
- ATTACH_OPERATIONS()
1971
- };
1972
-
1973
- ////////////////////////////////////////////////////////////
1974
- // An operator condition (e.g. `CONDITION1 and CONDITION2`).
1975
- ////////////////////////////////////////////////////////////
1976
- class Supports_Operator : public Supports_Condition {
1977
- public:
1978
- enum Operand { AND, OR };
1979
- private:
1980
- ADD_PROPERTY(Supports_Condition_Obj, left);
1981
- ADD_PROPERTY(Supports_Condition_Obj, right);
1982
- ADD_PROPERTY(Operand, operand);
1983
- public:
1984
- Supports_Operator(ParserState pstate, Supports_Condition_Obj l, Supports_Condition_Obj r, Operand o)
1985
- : Supports_Condition(pstate), left_(l), right_(r), operand_(o)
1986
- { }
1987
- Supports_Operator(const Supports_Operator* ptr)
1988
- : Supports_Condition(ptr),
1989
- left_(ptr->left_),
1990
- right_(ptr->right_),
1991
- operand_(ptr->operand_)
1992
- { }
1993
- virtual bool needs_parens(Supports_Condition_Obj cond) const;
1994
- ATTACH_AST_OPERATIONS(Supports_Operator)
1995
- ATTACH_OPERATIONS()
1996
- };
1997
-
1998
- //////////////////////////////////////////
1999
- // A negation condition (`not CONDITION`).
2000
- //////////////////////////////////////////
2001
- class Supports_Negation : public Supports_Condition {
2002
- private:
2003
- ADD_PROPERTY(Supports_Condition_Obj, condition);
2004
- public:
2005
- Supports_Negation(ParserState pstate, Supports_Condition_Obj c)
2006
- : Supports_Condition(pstate), condition_(c)
2007
- { }
2008
- Supports_Negation(const Supports_Negation* ptr)
2009
- : Supports_Condition(ptr), condition_(ptr->condition_)
2010
- { }
2011
- virtual bool needs_parens(Supports_Condition_Obj cond) const;
2012
- ATTACH_AST_OPERATIONS(Supports_Negation)
2013
- ATTACH_OPERATIONS()
2014
- };
2015
-
2016
- /////////////////////////////////////////////////////
2017
- // A declaration condition (e.g. `(feature: value)`).
2018
- /////////////////////////////////////////////////////
2019
- class Supports_Declaration : public Supports_Condition {
2020
- private:
2021
- ADD_PROPERTY(Expression_Obj, feature);
2022
- ADD_PROPERTY(Expression_Obj, value);
2023
- public:
2024
- Supports_Declaration(ParserState pstate, Expression_Obj f, Expression_Obj v)
2025
- : Supports_Condition(pstate), feature_(f), value_(v)
2026
- { }
2027
- Supports_Declaration(const Supports_Declaration* ptr)
2028
- : Supports_Condition(ptr),
2029
- feature_(ptr->feature_),
2030
- value_(ptr->value_)
2031
- { }
2032
- virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
2033
- ATTACH_AST_OPERATIONS(Supports_Declaration)
2034
- ATTACH_OPERATIONS()
2035
- };
2036
-
2037
- ///////////////////////////////////////////////
2038
- // An interpolation condition (e.g. `#{$var}`).
2039
- ///////////////////////////////////////////////
2040
- class Supports_Interpolation : public Supports_Condition {
2041
- private:
2042
- ADD_PROPERTY(Expression_Obj, value);
2043
- public:
2044
- Supports_Interpolation(ParserState pstate, Expression_Obj v)
2045
- : Supports_Condition(pstate), value_(v)
2046
- { }
2047
- Supports_Interpolation(const Supports_Interpolation* ptr)
2048
- : Supports_Condition(ptr),
2049
- value_(ptr->value_)
2050
- { }
2051
- virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
2052
- ATTACH_AST_OPERATIONS(Supports_Interpolation)
2053
- ATTACH_OPERATIONS()
2054
- };
2055
-
2056
- /////////////////////////////////////////////////
2057
- // At root expressions (for use inside @at-root).
2058
- /////////////////////////////////////////////////
2059
- class At_Root_Query : public Expression {
2060
- private:
2061
- ADD_PROPERTY(Expression_Obj, feature)
2062
- ADD_PROPERTY(Expression_Obj, value)
2063
- public:
2064
- At_Root_Query(ParserState pstate, Expression_Obj f = 0, Expression_Obj v = 0, bool i = false)
2065
- : Expression(pstate), feature_(f), value_(v)
2066
- { }
2067
- At_Root_Query(const At_Root_Query* ptr)
2068
- : Expression(ptr),
2069
- feature_(ptr->feature_),
2070
- value_(ptr->value_)
2071
- { }
2072
- bool exclude(std::string str);
2073
- ATTACH_AST_OPERATIONS(At_Root_Query)
2074
- ATTACH_OPERATIONS()
2075
- };
2076
-
2077
- ///////////
2078
- // At-root.
2079
- ///////////
2080
- class At_Root_Block : public Has_Block {
2081
- ADD_PROPERTY(At_Root_Query_Obj, expression)
2082
- public:
2083
- At_Root_Block(ParserState pstate, Block_Obj b = 0, At_Root_Query_Obj e = 0)
2084
- : Has_Block(pstate, b), expression_(e)
2085
- { statement_type(ATROOT); }
2086
- At_Root_Block(const At_Root_Block* ptr)
2087
- : Has_Block(ptr), expression_(ptr->expression_)
2088
- { statement_type(ATROOT); }
2089
- bool bubbles() { return true; }
2090
- bool exclude_node(Statement_Obj s) {
2091
- if (expression() == 0)
2092
- {
2093
- return s->statement_type() == Statement::RULESET;
2094
- }
2095
-
2096
- if (s->statement_type() == Statement::DIRECTIVE)
2097
- {
2098
- if (Directive_Obj dir = Cast<Directive>(s))
2099
- {
2100
- std::string keyword(dir->keyword());
2101
- if (keyword.length() > 0) keyword.erase(0, 1);
2102
- return expression()->exclude(keyword);
2103
- }
2104
- }
2105
- if (s->statement_type() == Statement::MEDIA)
2106
- {
2107
- return expression()->exclude("media");
2108
- }
2109
- if (s->statement_type() == Statement::RULESET)
2110
- {
2111
- return expression()->exclude("rule");
2112
- }
2113
- if (s->statement_type() == Statement::SUPPORTS)
2114
- {
2115
- return expression()->exclude("supports");
2116
- }
2117
- if (Directive_Obj dir = Cast<Directive>(s))
2118
- {
2119
- if (dir->is_keyframes()) return expression()->exclude("keyframes");
2120
- }
2121
- return false;
2122
- }
2123
- ATTACH_AST_OPERATIONS(At_Root_Block)
2124
- ATTACH_OPERATIONS()
2125
- };
2126
-
2127
- //////////////////
2128
- // The null value.
2129
- //////////////////
2130
- class Null : public Value {
2131
- public:
2132
- Null(ParserState pstate) : Value(pstate) { concrete_type(NULL_VAL); }
2133
- Null(const Null* ptr) : Value(ptr) { concrete_type(NULL_VAL); }
2134
- std::string type() const { return "null"; }
2135
- static std::string type_name() { return "null"; }
2136
- bool is_invisible() const { return true; }
2137
- operator bool() { return false; }
2138
- bool is_false() { return true; }
2139
-
2140
- virtual size_t hash()
2141
- {
2142
- return -1;
2143
- }
2144
-
2145
- virtual bool operator== (const Expression& rhs) const;
2146
-
2147
- ATTACH_AST_OPERATIONS(Null)
2148
- ATTACH_OPERATIONS()
2149
- };
2150
-
2151
- /////////////////////////////////
2152
- // Thunks for delayed evaluation.
2153
- /////////////////////////////////
2154
- class Thunk : public Expression {
2155
- ADD_PROPERTY(Expression_Obj, expression)
2156
- ADD_PROPERTY(Env*, environment)
2157
- public:
2158
- Thunk(ParserState pstate, Expression_Obj exp, Env* env = 0)
2159
- : Expression(pstate), expression_(exp), environment_(env)
2160
- { }
2161
- };
2162
-
2163
- /////////////////////////////////////////////////////////
2164
- // Individual parameter objects for mixins and functions.
2165
- /////////////////////////////////////////////////////////
2166
- class Parameter : public AST_Node {
2167
- ADD_CONSTREF(std::string, name)
2168
- ADD_PROPERTY(Expression_Obj, default_value)
2169
- ADD_PROPERTY(bool, is_rest_parameter)
2170
- public:
2171
- Parameter(ParserState pstate,
2172
- std::string n, Expression_Obj def = 0, bool rest = false)
2173
- : AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)
2174
- {
2175
- // tried to come up with a spec test for this, but it does no longer
2176
- // get past the parser (it error out earlier). A spec test was added!
2177
- // if (default_value_ && is_rest_parameter_) {
2178
- // error("variable-length parameter may not have a default value", pstate_);
2179
- // }
2180
- }
2181
- Parameter(const Parameter* ptr)
2182
- : AST_Node(ptr),
2183
- name_(ptr->name_),
2184
- default_value_(ptr->default_value_),
2185
- is_rest_parameter_(ptr->is_rest_parameter_)
2186
- {
2187
- // tried to come up with a spec test for this, but it does no longer
2188
- // get past the parser (it error out earlier). A spec test was added!
2189
- // if (default_value_ && is_rest_parameter_) {
2190
- // error("variable-length parameter may not have a default value", pstate_);
2191
- // }
2192
- }
2193
- ATTACH_AST_OPERATIONS(Parameter)
2194
- ATTACH_OPERATIONS()
2195
- };
2196
-
2197
- /////////////////////////////////////////////////////////////////////////
2198
- // Parameter lists -- in their own class to facilitate context-sensitive
2199
- // error checking (e.g., ensuring that all optional parameters follow all
2200
- // required parameters).
2201
- /////////////////////////////////////////////////////////////////////////
2202
- class Parameters : public AST_Node, public Vectorized<Parameter_Obj> {
2203
- ADD_PROPERTY(bool, has_optional_parameters)
2204
- ADD_PROPERTY(bool, has_rest_parameter)
2205
- protected:
2206
- void adjust_after_pushing(Parameter_Obj p)
2207
- {
2208
- if (p->default_value()) {
2209
- if (has_rest_parameter()) {
2210
- coreError("optional parameters may not be combined with variable-length parameters", p->pstate());
2211
- }
2212
- has_optional_parameters(true);
2213
- }
2214
- else if (p->is_rest_parameter()) {
2215
- if (has_rest_parameter()) {
2216
- coreError("functions and mixins cannot have more than one variable-length parameter", p->pstate());
2217
- }
2218
- has_rest_parameter(true);
2219
- }
2220
- else {
2221
- if (has_rest_parameter()) {
2222
- coreError("required parameters must precede variable-length parameters", p->pstate());
2223
- }
2224
- if (has_optional_parameters()) {
2225
- coreError("required parameters must precede optional parameters", p->pstate());
2226
- }
2227
- }
2228
- }
2229
- public:
2230
- Parameters(ParserState pstate)
2231
- : AST_Node(pstate),
2232
- Vectorized<Parameter_Obj>(),
2233
- has_optional_parameters_(false),
2234
- has_rest_parameter_(false)
2235
- { }
2236
- Parameters(const Parameters* ptr)
2237
- : AST_Node(ptr),
2238
- Vectorized<Parameter_Obj>(*ptr),
2239
- has_optional_parameters_(ptr->has_optional_parameters_),
2240
- has_rest_parameter_(ptr->has_rest_parameter_)
2241
- { }
2242
- ATTACH_AST_OPERATIONS(Parameters)
2243
- ATTACH_OPERATIONS()
2244
- };
2245
-
2246
- /////////////////////////////////////////
2247
- // Abstract base class for CSS selectors.
2248
- /////////////////////////////////////////
2249
- class Selector : public Expression {
2250
- // ADD_PROPERTY(bool, has_reference)
2251
- // line break before list separator
2252
- ADD_PROPERTY(bool, has_line_feed)
2253
- // line break after list separator
2254
- ADD_PROPERTY(bool, has_line_break)
2255
- // maybe we have optional flag
2256
- ADD_PROPERTY(bool, is_optional)
2257
- // parent block pointers
2258
-
2259
- // must not be a reference counted object
2260
- // otherwise we create circular references
2261
- ADD_PROPERTY(Media_Block_Ptr, media_block)
2262
- protected:
2263
- size_t hash_;
2264
- public:
2265
- Selector(ParserState pstate)
2266
- : Expression(pstate),
2267
- has_line_feed_(false),
2268
- has_line_break_(false),
2269
- is_optional_(false),
2270
- media_block_(0),
2271
- hash_(0)
2272
- { concrete_type(SELECTOR); }
2273
- Selector(const Selector* ptr)
2274
- : Expression(ptr),
2275
- // has_reference_(ptr->has_reference_),
2276
- has_line_feed_(ptr->has_line_feed_),
2277
- has_line_break_(ptr->has_line_break_),
2278
- is_optional_(ptr->is_optional_),
2279
- media_block_(ptr->media_block_),
2280
- hash_(ptr->hash_)
2281
- { concrete_type(SELECTOR); }
2282
- virtual ~Selector() = 0;
2283
- virtual size_t hash() = 0;
2284
- virtual unsigned long specificity() const = 0;
2285
- virtual void set_media_block(Media_Block_Ptr mb) {
2286
- media_block(mb);
2287
- }
2288
- virtual bool has_parent_ref() const {
2289
- return false;
2290
- }
2291
- virtual bool has_real_parent_ref() const {
2292
- return false;
2293
- }
2294
- // dispatch to correct handlers
2295
- virtual bool operator<(const Selector& rhs) const = 0;
2296
- virtual bool operator==(const Selector& rhs) const = 0;
2297
- ATTACH_VIRTUAL_AST_OPERATIONS(Selector);
2298
- };
2299
- inline Selector::~Selector() { }
2300
-
2301
- /////////////////////////////////////////////////////////////////////////
2302
- // Interpolated selectors -- the interpolated String will be expanded and
2303
- // re-parsed into a normal selector class.
2304
- /////////////////////////////////////////////////////////////////////////
2305
- class Selector_Schema : public AST_Node {
2306
- ADD_PROPERTY(String_Obj, contents)
2307
- ADD_PROPERTY(bool, connect_parent);
2308
- // must not be a reference counted object
2309
- // otherwise we create circular references
2310
- ADD_PROPERTY(Media_Block_Ptr, media_block)
2311
- // store computed hash
2312
- size_t hash_;
2313
- public:
2314
- Selector_Schema(ParserState pstate, String_Obj c)
2315
- : AST_Node(pstate),
2316
- contents_(c),
2317
- connect_parent_(true),
2318
- media_block_(NULL),
2319
- hash_(0)
2320
- { }
2321
- Selector_Schema(const Selector_Schema* ptr)
2322
- : AST_Node(ptr),
2323
- contents_(ptr->contents_),
2324
- connect_parent_(ptr->connect_parent_),
2325
- media_block_(ptr->media_block_),
2326
- hash_(ptr->hash_)
2327
- { }
2328
- virtual bool has_parent_ref() const;
2329
- virtual bool has_real_parent_ref() const;
2330
- virtual bool operator<(const Selector& rhs) const;
2331
- virtual bool operator==(const Selector& rhs) const;
2332
- // selector schema is not yet a final selector, so we do not
2333
- // have a specificity for it yet. We need to
2334
- virtual unsigned long specificity() const { return 0; }
2335
- virtual size_t hash() {
2336
- if (hash_ == 0) {
2337
- hash_combine(hash_, contents_->hash());
2338
- }
2339
- return hash_;
2340
- }
2341
- ATTACH_AST_OPERATIONS(Selector_Schema)
2342
- ATTACH_OPERATIONS()
2343
- };
2344
-
2345
- ////////////////////////////////////////////
2346
- // Abstract base class for simple selectors.
2347
- ////////////////////////////////////////////
2348
- class Simple_Selector : public Selector {
2349
- ADD_CONSTREF(std::string, ns)
2350
- ADD_CONSTREF(std::string, name)
2351
- ADD_PROPERTY(Simple_Type, simple_type)
2352
- ADD_PROPERTY(bool, has_ns)
2353
- public:
2354
- Simple_Selector(ParserState pstate, std::string n = "")
2355
- : Selector(pstate), ns_(""), name_(n), has_ns_(false)
2356
- {
2357
- simple_type(SIMPLE);
2358
- size_t pos = n.find('|');
2359
- // found some namespace
2360
- if (pos != std::string::npos) {
2361
- has_ns_ = true;
2362
- ns_ = n.substr(0, pos);
2363
- name_ = n.substr(pos + 1);
2364
- }
2365
- }
2366
- Simple_Selector(const Simple_Selector* ptr)
2367
- : Selector(ptr),
2368
- ns_(ptr->ns_),
2369
- name_(ptr->name_),
2370
- has_ns_(ptr->has_ns_)
2371
- { simple_type(SIMPLE); }
2372
- virtual std::string ns_name() const
2373
- {
2374
- std::string name("");
2375
- if (has_ns_)
2376
- name += ns_ + "|";
2377
- return name + name_;
2378
- }
2379
- virtual size_t hash()
2380
- {
2381
- if (hash_ == 0) {
2382
- hash_combine(hash_, std::hash<int>()(SELECTOR));
2383
- hash_combine(hash_, std::hash<std::string>()(ns()));
2384
- hash_combine(hash_, std::hash<std::string>()(name()));
2385
- }
2386
- return hash_;
2387
- }
2388
- // namespace compare functions
2389
- bool is_ns_eq(const Simple_Selector& r) const;
2390
- // namespace query functions
2391
- bool is_universal_ns() const
2392
- {
2393
- return has_ns_ && ns_ == "*";
2394
- }
2395
- bool has_universal_ns() const
2396
- {
2397
- return !has_ns_ || ns_ == "*";
2398
- }
2399
- bool is_empty_ns() const
2400
- {
2401
- return !has_ns_ || ns_ == "";
2402
- }
2403
- bool has_empty_ns() const
2404
- {
2405
- return has_ns_ && ns_ == "";
2406
- }
2407
- bool has_qualified_ns() const
2408
- {
2409
- return has_ns_ && ns_ != "" && ns_ != "*";
2410
- }
2411
- // name query functions
2412
- bool is_universal() const
2413
- {
2414
- return name_ == "*";
2415
- }
2416
-
2417
- virtual bool has_placeholder() {
2418
- return false;
2419
- }
2420
-
2421
- virtual ~Simple_Selector() = 0;
2422
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2423
- virtual bool has_parent_ref() const { return false; };
2424
- virtual bool has_real_parent_ref() const { return false; };
2425
- virtual bool is_pseudo_element() const { return false; }
2426
-
2427
- virtual bool is_superselector_of(Compound_Selector_Obj sub) { return false; }
2428
-
2429
- virtual bool operator==(const Selector& rhs) const;
2430
- virtual bool operator==(const Simple_Selector& rhs) const;
2431
- inline bool operator!=(const Simple_Selector& rhs) const { return !(*this == rhs); }
2432
-
2433
- bool operator<(const Selector& rhs) const;
2434
- bool operator<(const Simple_Selector& rhs) const;
2435
- // default implementation should work for most of the simple selectors (otherwise overload)
2436
- ATTACH_VIRTUAL_AST_OPERATIONS(Simple_Selector);
2437
- ATTACH_OPERATIONS();
2438
- };
2439
- inline Simple_Selector::~Simple_Selector() { }
2440
-
2441
-
2442
- //////////////////////////////////
2443
- // The Parent Selector Expression.
2444
- //////////////////////////////////
2445
- // parent selectors can occur in selectors but also
2446
- // inside strings in declarations (Compound_Selector).
2447
- // only one simple parent selector means the first case.
2448
- class Parent_Selector : public Simple_Selector {
2449
- ADD_PROPERTY(bool, real)
2450
- public:
2451
- Parent_Selector(ParserState pstate, bool r = true)
2452
- : Simple_Selector(pstate, "&"), real_(r)
2453
- { /* has_reference(true); */ }
2454
- Parent_Selector(const Parent_Selector* ptr)
2455
- : Simple_Selector(ptr), real_(ptr->real_)
2456
- { /* has_reference(true); */ }
2457
- bool is_real_parent_ref() const { return real(); };
2458
- virtual bool has_parent_ref() const { return true; };
2459
- virtual bool has_real_parent_ref() const { return is_real_parent_ref(); };
2460
- virtual unsigned long specificity() const
2461
- {
2462
- return 0;
2463
- }
2464
- std::string type() const { return "selector"; }
2465
- static std::string type_name() { return "selector"; }
2466
- ATTACH_AST_OPERATIONS(Parent_Selector)
2467
- ATTACH_OPERATIONS()
2468
- };
2469
-
2470
- /////////////////////////////////////////////////////////////////////////
2471
- // Placeholder selectors (e.g., "%foo") for use in extend-only selectors.
2472
- /////////////////////////////////////////////////////////////////////////
2473
- class Placeholder_Selector : public Simple_Selector {
2474
- public:
2475
- Placeholder_Selector(ParserState pstate, std::string n)
2476
- : Simple_Selector(pstate, n)
2477
- { }
2478
- Placeholder_Selector(const Placeholder_Selector* ptr)
2479
- : Simple_Selector(ptr)
2480
- { }
2481
- virtual unsigned long specificity() const
2482
- {
2483
- return Constants::Specificity_Base;
2484
- }
2485
- virtual bool has_placeholder() {
2486
- return true;
2487
- }
2488
- virtual ~Placeholder_Selector() {};
2489
- ATTACH_AST_OPERATIONS(Placeholder_Selector)
2490
- ATTACH_OPERATIONS()
2491
- };
2492
-
2493
- /////////////////////////////////////////////////////////////////////
2494
- // Element selectors (and the universal selector) -- e.g., div, span, *.
2495
- /////////////////////////////////////////////////////////////////////
2496
- class Element_Selector : public Simple_Selector {
2497
- public:
2498
- Element_Selector(ParserState pstate, std::string n)
2499
- : Simple_Selector(pstate, n)
2500
- { }
2501
- Element_Selector(const Element_Selector* ptr)
2502
- : Simple_Selector(ptr)
2503
- { }
2504
- virtual unsigned long specificity() const
2505
- {
2506
- if (name() == "*") return 0;
2507
- else return Constants::Specificity_Element;
2508
- }
2509
- virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr);
2510
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2511
- virtual bool operator==(const Simple_Selector& rhs) const;
2512
- virtual bool operator==(const Element_Selector& rhs) const;
2513
- virtual bool operator<(const Simple_Selector& rhs) const;
2514
- virtual bool operator<(const Element_Selector& rhs) const;
2515
- ATTACH_AST_OPERATIONS(Element_Selector)
2516
- ATTACH_OPERATIONS()
2517
- };
2518
-
2519
- ////////////////////////////////////////////////
2520
- // Class selectors -- i.e., .foo.
2521
- ////////////////////////////////////////////////
2522
- class Class_Selector : public Simple_Selector {
2523
- public:
2524
- Class_Selector(ParserState pstate, std::string n)
2525
- : Simple_Selector(pstate, n)
2526
- { }
2527
- Class_Selector(const Class_Selector* ptr)
2528
- : Simple_Selector(ptr)
2529
- { }
2530
- virtual unsigned long specificity() const
2531
- {
2532
- return Constants::Specificity_Class;
2533
- }
2534
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2535
- ATTACH_AST_OPERATIONS(Class_Selector)
2536
- ATTACH_OPERATIONS()
2537
- };
2538
-
2539
- ////////////////////////////////////////////////
2540
- // ID selectors -- i.e., #foo.
2541
- ////////////////////////////////////////////////
2542
- class Id_Selector : public Simple_Selector {
2543
- public:
2544
- Id_Selector(ParserState pstate, std::string n)
2545
- : Simple_Selector(pstate, n)
2546
- { }
2547
- Id_Selector(const Id_Selector* ptr)
2548
- : Simple_Selector(ptr)
2549
- { }
2550
- virtual unsigned long specificity() const
2551
- {
2552
- return Constants::Specificity_ID;
2553
- }
2554
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2555
- ATTACH_AST_OPERATIONS(Id_Selector)
2556
- ATTACH_OPERATIONS()
2557
- };
2558
-
2559
- ///////////////////////////////////////////////////
2560
- // Attribute selectors -- e.g., [src*=".jpg"], etc.
2561
- ///////////////////////////////////////////////////
2562
- class Attribute_Selector : public Simple_Selector {
2563
- ADD_CONSTREF(std::string, matcher)
2564
- // this cannot be changed to obj atm!!!!!!????!!!!!!!
2565
- ADD_PROPERTY(String_Obj, value) // might be interpolated
2566
- ADD_PROPERTY(char, modifier);
2567
- public:
2568
- Attribute_Selector(ParserState pstate, std::string n, std::string m, String_Obj v, char o = 0)
2569
- : Simple_Selector(pstate, n), matcher_(m), value_(v), modifier_(o)
2570
- { simple_type(ATTR_SEL); }
2571
- Attribute_Selector(const Attribute_Selector* ptr)
2572
- : Simple_Selector(ptr),
2573
- matcher_(ptr->matcher_),
2574
- value_(ptr->value_),
2575
- modifier_(ptr->modifier_)
2576
- { simple_type(ATTR_SEL); }
2577
- virtual size_t hash()
2578
- {
2579
- if (hash_ == 0) {
2580
- hash_combine(hash_, Simple_Selector::hash());
2581
- hash_combine(hash_, std::hash<std::string>()(matcher()));
2582
- if (value_) hash_combine(hash_, value_->hash());
2583
- }
2584
- return hash_;
2585
- }
2586
- virtual unsigned long specificity() const
2587
- {
2588
- return Constants::Specificity_Attr;
2589
- }
2590
- virtual bool operator==(const Simple_Selector& rhs) const;
2591
- virtual bool operator==(const Attribute_Selector& rhs) const;
2592
- virtual bool operator<(const Simple_Selector& rhs) const;
2593
- virtual bool operator<(const Attribute_Selector& rhs) const;
2594
- ATTACH_AST_OPERATIONS(Attribute_Selector)
2595
- ATTACH_OPERATIONS()
2596
- };
2597
-
2598
- //////////////////////////////////////////////////////////////////
2599
- // Pseudo selectors -- e.g., :first-child, :nth-of-type(...), etc.
2600
- //////////////////////////////////////////////////////////////////
2601
- /* '::' starts a pseudo-element, ':' a pseudo-class */
2602
- /* Except :first-line, :first-letter, :before and :after */
2603
- /* Note that pseudo-elements are restricted to one per selector */
2604
- /* and occur only in the last simple_selector_sequence. */
2605
- inline bool is_pseudo_class_element(const std::string& name)
2606
- {
2607
- return name == ":before" ||
2608
- name == ":after" ||
2609
- name == ":first-line" ||
2610
- name == ":first-letter";
2611
- }
2612
-
2613
- // Pseudo Selector cannot have any namespace?
2614
- class Pseudo_Selector : public Simple_Selector {
2615
- ADD_PROPERTY(String_Obj, expression)
2616
- public:
2617
- Pseudo_Selector(ParserState pstate, std::string n, String_Obj expr = 0)
2618
- : Simple_Selector(pstate, n), expression_(expr)
2619
- { simple_type(PSEUDO_SEL); }
2620
- Pseudo_Selector(const Pseudo_Selector* ptr)
2621
- : Simple_Selector(ptr), expression_(ptr->expression_)
2622
- { simple_type(PSEUDO_SEL); }
2623
-
2624
- // A pseudo-element is made of two colons (::) followed by the name.
2625
- // The `::` notation is introduced by the current document in order to
2626
- // establish a discrimination between pseudo-classes and pseudo-elements.
2627
- // For compatibility with existing style sheets, user agents must also
2628
- // accept the previous one-colon notation for pseudo-elements introduced
2629
- // in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and
2630
- // :after). This compatibility is not allowed for the new pseudo-elements
2631
- // introduced in this specification.
2632
- virtual bool is_pseudo_element() const
2633
- {
2634
- return (name_[0] == ':' && name_[1] == ':')
2635
- || is_pseudo_class_element(name_);
2636
- }
2637
- virtual size_t hash()
2638
- {
2639
- if (hash_ == 0) {
2640
- hash_combine(hash_, Simple_Selector::hash());
2641
- if (expression_) hash_combine(hash_, expression_->hash());
2642
- }
2643
- return hash_;
2644
- }
2645
- virtual unsigned long specificity() const
2646
- {
2647
- if (is_pseudo_element())
2648
- return Constants::Specificity_Element;
2649
- return Constants::Specificity_Pseudo;
2650
- }
2651
- virtual bool operator==(const Simple_Selector& rhs) const;
2652
- virtual bool operator==(const Pseudo_Selector& rhs) const;
2653
- virtual bool operator<(const Simple_Selector& rhs) const;
2654
- virtual bool operator<(const Pseudo_Selector& rhs) const;
2655
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2656
- ATTACH_AST_OPERATIONS(Pseudo_Selector)
2657
- ATTACH_OPERATIONS()
2658
- };
2659
-
2660
- /////////////////////////////////////////////////
2661
- // Wrapped selector -- pseudo selector that takes a list of selectors as argument(s) e.g., :not(:first-of-type), :-moz-any(ol p.blah, ul, menu, dir)
2662
- /////////////////////////////////////////////////
2663
- class Wrapped_Selector : public Simple_Selector {
2664
- ADD_PROPERTY(Selector_List_Obj, selector)
2665
- public:
2666
- Wrapped_Selector(ParserState pstate, std::string n, Selector_List_Obj sel)
2667
- : Simple_Selector(pstate, n), selector_(sel)
2668
- { simple_type(WRAPPED_SEL); }
2669
- Wrapped_Selector(const Wrapped_Selector* ptr)
2670
- : Simple_Selector(ptr), selector_(ptr->selector_)
2671
- { simple_type(WRAPPED_SEL); }
2672
- virtual bool is_superselector_of(Wrapped_Selector_Obj sub);
2673
- // Selectors inside the negation pseudo-class are counted like any
2674
- // other, but the negation itself does not count as a pseudo-class.
2675
- virtual size_t hash();
2676
- virtual bool has_parent_ref() const;
2677
- virtual bool has_real_parent_ref() const;
2678
- virtual unsigned long specificity() const;
2679
- virtual bool find ( bool (*f)(AST_Node_Obj) );
2680
- virtual bool operator==(const Simple_Selector& rhs) const;
2681
- virtual bool operator==(const Wrapped_Selector& rhs) const;
2682
- virtual bool operator<(const Simple_Selector& rhs) const;
2683
- virtual bool operator<(const Wrapped_Selector& rhs) const;
2684
- virtual void cloneChildren();
2685
- ATTACH_AST_OPERATIONS(Wrapped_Selector)
2686
- ATTACH_OPERATIONS()
2687
- };
2688
-
2689
- ////////////////////////////////////////////////////////////////////////////
2690
- // Simple selector sequences. Maintains flags indicating whether it contains
2691
- // any parent references or placeholders, to simplify expansion.
2692
- ////////////////////////////////////////////////////////////////////////////
2693
- class Compound_Selector : public Selector, public Vectorized<Simple_Selector_Obj> {
2694
- private:
2695
- ComplexSelectorSet sources_;
2696
- ADD_PROPERTY(bool, extended);
2697
- ADD_PROPERTY(bool, has_parent_reference);
2698
- protected:
2699
- void adjust_after_pushing(Simple_Selector_Obj s)
2700
- {
2701
- // if (s->has_reference()) has_reference(true);
2702
- // if (s->has_placeholder()) has_placeholder(true);
2703
- }
2704
- public:
2705
- Compound_Selector(ParserState pstate, size_t s = 0)
2706
- : Selector(pstate),
2707
- Vectorized<Simple_Selector_Obj>(s),
2708
- extended_(false),
2709
- has_parent_reference_(false)
2710
- { }
2711
- Compound_Selector(const Compound_Selector* ptr)
2712
- : Selector(ptr),
2713
- Vectorized<Simple_Selector_Obj>(*ptr),
2714
- extended_(ptr->extended_),
2715
- has_parent_reference_(ptr->has_parent_reference_)
2716
- { }
2717
- bool contains_placeholder() {
2718
- for (size_t i = 0, L = length(); i < L; ++i) {
2719
- if ((*this)[i]->has_placeholder()) return true;
2720
- }
2721
- return false;
2722
- };
2723
-
2724
- void append(Simple_Selector_Ptr element);
2725
-
2726
- bool is_universal() const
2727
- {
2728
- return length() == 1 && (*this)[0]->is_universal();
2729
- }
2730
-
2731
- Complex_Selector_Obj to_complex();
2732
- Compound_Selector_Ptr unify_with(Compound_Selector_Ptr rhs);
2733
- // virtual Placeholder_Selector_Ptr find_placeholder();
2734
- virtual bool has_parent_ref() const;
2735
- virtual bool has_real_parent_ref() const;
2736
- Simple_Selector_Ptr base() const {
2737
- if (length() == 0) return 0;
2738
- // ToDo: why is this needed?
2739
- if (Cast<Element_Selector>((*this)[0]))
2740
- return (*this)[0];
2741
- return 0;
2742
- }
2743
- virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapped = "");
2744
- virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapped = "");
2745
- virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapped = "");
2746
- virtual size_t hash()
2747
- {
2748
- if (Selector::hash_ == 0) {
2749
- hash_combine(Selector::hash_, std::hash<int>()(SELECTOR));
2750
- if (length()) hash_combine(Selector::hash_, Vectorized::hash());
2751
- }
2752
- return Selector::hash_;
2753
- }
2754
- virtual unsigned long specificity() const
2755
- {
2756
- int sum = 0;
2757
- for (size_t i = 0, L = length(); i < L; ++i)
2758
- { sum += (*this)[i]->specificity(); }
2759
- return sum;
2760
- }
2761
-
2762
- virtual bool has_placeholder()
2763
- {
2764
- if (length() == 0) return false;
2765
- if (Simple_Selector_Obj ss = elements().front()) {
2766
- if (ss->has_placeholder()) return true;
2767
- }
2768
- return false;
2769
- }
2770
-
2771
- bool is_empty_reference()
2772
- {
2773
- return length() == 1 &&
2774
- Cast<Parent_Selector>((*this)[0]);
2775
- }
2776
-
2777
- virtual bool find ( bool (*f)(AST_Node_Obj) );
2778
- virtual bool operator<(const Selector& rhs) const;
2779
- virtual bool operator==(const Selector& rhs) const;
2780
- virtual bool operator<(const Compound_Selector& rhs) const;
2781
- virtual bool operator==(const Compound_Selector& rhs) const;
2782
- inline bool operator!=(const Compound_Selector& rhs) const { return !(*this == rhs); }
2783
-
2784
- ComplexSelectorSet& sources() { return sources_; }
2785
- void clearSources() { sources_.clear(); }
2786
- void mergeSources(ComplexSelectorSet& sources);
2787
-
2788
- Compound_Selector_Ptr minus(Compound_Selector_Ptr rhs);
2789
- virtual void cloneChildren();
2790
- ATTACH_AST_OPERATIONS(Compound_Selector)
2791
- ATTACH_OPERATIONS()
2792
- };
2793
-
2794
- ////////////////////////////////////////////////////////////////////////////
2795
- // General selectors -- i.e., simple sequences combined with one of the four
2796
- // CSS selector combinators (">", "+", "~", and whitespace). Essentially a
2797
- // linked list.
2798
- ////////////////////////////////////////////////////////////////////////////
2799
- class Complex_Selector : public Selector {
2800
- public:
2801
- enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE };
2802
- private:
2803
- HASH_CONSTREF(Combinator, combinator)
2804
- HASH_PROPERTY(Compound_Selector_Obj, head)
2805
- HASH_PROPERTY(Complex_Selector_Obj, tail)
2806
- HASH_PROPERTY(String_Obj, reference);
2807
- public:
2808
- bool contains_placeholder() {
2809
- if (head() && head()->contains_placeholder()) return true;
2810
- if (tail() && tail()->contains_placeholder()) return true;
2811
- return false;
2812
- };
2813
- Complex_Selector(ParserState pstate,
2814
- Combinator c = ANCESTOR_OF,
2815
- Compound_Selector_Obj h = 0,
2816
- Complex_Selector_Obj t = 0,
2817
- String_Obj r = 0)
2818
- : Selector(pstate),
2819
- combinator_(c),
2820
- head_(h), tail_(t),
2821
- reference_(r)
2822
- {}
2823
- Complex_Selector(const Complex_Selector* ptr)
2824
- : Selector(ptr),
2825
- combinator_(ptr->combinator_),
2826
- head_(ptr->head_), tail_(ptr->tail_),
2827
- reference_(ptr->reference_)
2828
- {};
2829
- virtual bool has_parent_ref() const;
2830
- virtual bool has_real_parent_ref() const;
2831
-
2832
- Complex_Selector_Obj skip_empty_reference()
2833
- {
2834
- if ((!head_ || !head_->length() || head_->is_empty_reference()) &&
2835
- combinator() == Combinator::ANCESTOR_OF)
2836
- {
2837
- if (!tail_) return 0;
2838
- tail_->has_line_feed_ = this->has_line_feed_;
2839
- // tail_->has_line_break_ = this->has_line_break_;
2840
- return tail_->skip_empty_reference();
2841
- }
2842
- return this;
2843
- }
2844
-
2845
- // can still have a tail
2846
- bool is_empty_ancestor() const
2847
- {
2848
- return (!head() || head()->length() == 0) &&
2849
- combinator() == Combinator::ANCESTOR_OF;
2850
- }
2851
-
2852
- Selector_List_Ptr tails(Selector_List_Ptr tails);
2853
-
2854
- // front returns the first real tail
2855
- // skips over parent and empty ones
2856
- Complex_Selector_Obj first();
2857
- // last returns the last real tail
2858
- Complex_Selector_Obj last();
2859
-
2860
- // some shortcuts that should be removed
2861
- Complex_Selector_Obj innermost() { return last(); };
2862
-
2863
- size_t length() const;
2864
- Selector_List_Ptr resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, Backtraces& traces, bool implicit_parent = true);
2865
- virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = "");
2866
- virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = "");
2867
- virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = "");
2868
- Selector_List_Ptr unify_with(Complex_Selector_Ptr rhs);
2869
- Combinator clear_innermost();
2870
- void append(Complex_Selector_Obj, Backtraces& traces);
2871
- void set_innermost(Complex_Selector_Obj, Combinator);
2872
- virtual size_t hash()
2873
- {
2874
- if (hash_ == 0) {
2875
- hash_combine(hash_, std::hash<int>()(SELECTOR));
2876
- hash_combine(hash_, std::hash<int>()(combinator_));
2877
- if (head_) hash_combine(hash_, head_->hash());
2878
- if (tail_) hash_combine(hash_, tail_->hash());
2879
- }
2880
- return hash_;
2881
- }
2882
- virtual unsigned long specificity() const
2883
- {
2884
- int sum = 0;
2885
- if (head()) sum += head()->specificity();
2886
- if (tail()) sum += tail()->specificity();
2887
- return sum;
2888
- }
2889
- virtual void set_media_block(Media_Block_Ptr mb) {
2890
- media_block(mb);
2891
- if (tail_) tail_->set_media_block(mb);
2892
- if (head_) head_->set_media_block(mb);
2893
- }
2894
- virtual bool has_placeholder() {
2895
- if (head_ && head_->has_placeholder()) return true;
2896
- if (tail_ && tail_->has_placeholder()) return true;
2897
- return false;
2898
- }
2899
- virtual bool find ( bool (*f)(AST_Node_Obj) );
2900
- virtual bool operator<(const Selector& rhs) const;
2901
- virtual bool operator==(const Selector& rhs) const;
2902
- virtual bool operator<(const Complex_Selector& rhs) const;
2903
- virtual bool operator==(const Complex_Selector& rhs) const;
2904
- inline bool operator!=(const Complex_Selector& rhs) const { return !(*this == rhs); }
2905
- const ComplexSelectorSet sources()
2906
- {
2907
- //s = Set.new
2908
- //seq.map {|sseq_or_op| s.merge sseq_or_op.sources if sseq_or_op.is_a?(SimpleSequence)}
2909
- //s
2910
-
2911
- ComplexSelectorSet srcs;
2912
-
2913
- Compound_Selector_Obj pHead = head();
2914
- Complex_Selector_Obj pTail = tail();
2915
-
2916
- if (pHead) {
2917
- const ComplexSelectorSet& headSources = pHead->sources();
2918
- srcs.insert(headSources.begin(), headSources.end());
2919
- }
2920
-
2921
- if (pTail) {
2922
- const ComplexSelectorSet& tailSources = pTail->sources();
2923
- srcs.insert(tailSources.begin(), tailSources.end());
2924
- }
2925
-
2926
- return srcs;
2927
- }
2928
- void addSources(ComplexSelectorSet& sources) {
2929
- // members.map! {|m| m.is_a?(SimpleSequence) ? m.with_more_sources(sources) : m}
2930
- Complex_Selector_Ptr pIter = this;
2931
- while (pIter) {
2932
- Compound_Selector_Ptr pHead = pIter->head();
2933
-
2934
- if (pHead) {
2935
- pHead->mergeSources(sources);
2936
- }
2937
-
2938
- pIter = pIter->tail();
2939
- }
2940
- }
2941
- void clearSources() {
2942
- Complex_Selector_Ptr pIter = this;
2943
- while (pIter) {
2944
- Compound_Selector_Ptr pHead = pIter->head();
2945
-
2946
- if (pHead) {
2947
- pHead->clearSources();
2948
- }
2949
-
2950
- pIter = pIter->tail();
2951
- }
2952
- }
2953
-
2954
- virtual void cloneChildren();
2955
- ATTACH_AST_OPERATIONS(Complex_Selector)
2956
- ATTACH_OPERATIONS()
2957
- };
2958
-
2959
- ///////////////////////////////////
2960
- // Comma-separated selector groups.
2961
- ///////////////////////////////////
2962
- class Selector_List : public Selector, public Vectorized<Complex_Selector_Obj> {
2963
- ADD_PROPERTY(Selector_Schema_Obj, schema)
2964
- ADD_CONSTREF(std::vector<std::string>, wspace)
2965
- protected:
2966
- void adjust_after_pushing(Complex_Selector_Obj c);
2967
- public:
2968
- Selector_List(ParserState pstate, size_t s = 0)
2969
- : Selector(pstate),
2970
- Vectorized<Complex_Selector_Obj>(s),
2971
- schema_(NULL),
2972
- wspace_(0)
2973
- { }
2974
- Selector_List(const Selector_List* ptr)
2975
- : Selector(ptr),
2976
- Vectorized<Complex_Selector_Obj>(*ptr),
2977
- schema_(ptr->schema_),
2978
- wspace_(ptr->wspace_)
2979
- { }
2980
- std::string type() const { return "list"; }
2981
- // remove parent selector references
2982
- // basically unwraps parsed selectors
2983
- virtual bool has_parent_ref() const;
2984
- virtual bool has_real_parent_ref() const;
2985
- void remove_parent_selectors();
2986
- Selector_List_Ptr resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, Backtraces& traces, bool implicit_parent = true);
2987
- virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = "");
2988
- virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = "");
2989
- virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = "");
2990
- Selector_List_Ptr unify_with(Selector_List_Ptr);
2991
- void populate_extends(Selector_List_Obj, Subset_Map&);
2992
- Selector_List_Obj eval(Eval& eval);
2993
- virtual size_t hash()
2994
- {
2995
- if (Selector::hash_ == 0) {
2996
- hash_combine(Selector::hash_, std::hash<int>()(SELECTOR));
2997
- hash_combine(Selector::hash_, Vectorized::hash());
2998
- }
2999
- return Selector::hash_;
3000
- }
3001
- virtual unsigned long specificity() const
3002
- {
3003
- unsigned long sum = 0;
3004
- unsigned long specificity;
3005
- for (size_t i = 0, L = length(); i < L; ++i)
3006
- {
3007
- specificity = (*this)[i]->specificity();
3008
- if (sum < specificity) sum = specificity;
3009
- }
3010
- return sum;
3011
- }
3012
- virtual void set_media_block(Media_Block_Ptr mb) {
3013
- media_block(mb);
3014
- for (Complex_Selector_Obj cs : elements()) {
3015
- cs->set_media_block(mb);
3016
- }
3017
- }
3018
- virtual bool has_placeholder() {
3019
- for (Complex_Selector_Obj cs : elements()) {
3020
- if (cs->has_placeholder()) return true;
3021
- }
3022
- return false;
3023
- }
3024
- virtual bool find ( bool (*f)(AST_Node_Obj) );
3025
- virtual bool operator<(const Selector& rhs) const;
3026
- virtual bool operator==(const Selector& rhs) const;
3027
- virtual bool operator<(const Selector_List& rhs) const;
3028
- virtual bool operator==(const Selector_List& rhs) const;
3029
- // Selector Lists can be compared to comma lists
3030
- virtual bool operator==(const Expression& rhs) const;
3031
- virtual void cloneChildren();
3032
- ATTACH_AST_OPERATIONS(Selector_List)
3033
- ATTACH_OPERATIONS()
3034
- };
3035
-
3036
- // compare function for sorting and probably other other uses
3037
- struct cmp_complex_selector { inline bool operator() (const Complex_Selector_Obj l, const Complex_Selector_Obj r) { return (*l < *r); } };
3038
- struct cmp_compound_selector { inline bool operator() (const Compound_Selector_Obj l, const Compound_Selector_Obj r) { return (*l < *r); } };
3039
- struct cmp_simple_selector { inline bool operator() (const Simple_Selector_Obj l, const Simple_Selector_Obj r) { return (*l < *r); } };
3040
-
3041
892
  }
3042
893
 
894
+ #include "ast_values.hpp"
895
+ #include "ast_supports.hpp"
896
+ #include "ast_selectors.hpp"
897
+
3043
898
  #ifdef __clang__
3044
899
 
3045
- #pragma clang diagnostic pop
900
+ // #pragma clang diagnostic pop
901
+ // #pragma clang diagnostic push
3046
902
 
3047
903
  #endif
3048
904