sassc 2.0.1 → 2.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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