sassc 2.0.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +36 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +43 -7
  9. data/ext/depend +4 -0
  10. data/ext/extconf.rb +92 -0
  11. data/ext/libsass/VERSION +1 -0
  12. data/ext/libsass/include/sass/base.h +9 -1
  13. data/ext/libsass/include/sass/context.h +5 -1
  14. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  15. data/ext/libsass/src/ast.cpp +755 -2028
  16. data/ext/libsass/src/ast.hpp +492 -2477
  17. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  18. data/ext/libsass/src/ast2c.hpp +39 -0
  19. data/ext/libsass/src/ast_def_macros.hpp +70 -10
  20. data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
  21. data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
  22. data/ext/libsass/src/ast_helpers.hpp +292 -0
  23. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  24. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  25. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  26. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  28. data/ext/libsass/src/ast_selectors.hpp +522 -0
  29. data/ext/libsass/src/ast_supports.cpp +114 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +1154 -0
  32. data/ext/libsass/src/ast_values.hpp +498 -0
  33. data/ext/libsass/src/backtrace.cpp +11 -7
  34. data/ext/libsass/src/backtrace.hpp +5 -5
  35. data/ext/libsass/src/base64vlq.cpp +5 -2
  36. data/ext/libsass/src/base64vlq.hpp +1 -1
  37. data/ext/libsass/src/bind.cpp +35 -34
  38. data/ext/libsass/src/bind.hpp +3 -1
  39. data/ext/libsass/src/c2ast.cpp +64 -0
  40. data/ext/libsass/src/c2ast.hpp +14 -0
  41. data/ext/libsass/src/cencode.c +4 -6
  42. data/ext/libsass/src/check_nesting.cpp +83 -88
  43. data/ext/libsass/src/check_nesting.hpp +39 -34
  44. data/ext/libsass/src/color_maps.cpp +168 -164
  45. data/ext/libsass/src/color_maps.hpp +152 -160
  46. data/ext/libsass/src/constants.cpp +20 -0
  47. data/ext/libsass/src/constants.hpp +19 -0
  48. data/ext/libsass/src/context.cpp +104 -121
  49. data/ext/libsass/src/context.hpp +43 -55
  50. data/ext/libsass/src/cssize.cpp +103 -188
  51. data/ext/libsass/src/cssize.hpp +45 -51
  52. data/ext/libsass/src/dart_helpers.hpp +199 -0
  53. data/ext/libsass/src/debugger.hpp +524 -361
  54. data/ext/libsass/src/emitter.cpp +26 -26
  55. data/ext/libsass/src/emitter.hpp +20 -18
  56. data/ext/libsass/src/environment.cpp +41 -27
  57. data/ext/libsass/src/environment.hpp +33 -22
  58. data/ext/libsass/src/error_handling.cpp +92 -94
  59. data/ext/libsass/src/error_handling.hpp +73 -50
  60. data/ext/libsass/src/eval.cpp +380 -515
  61. data/ext/libsass/src/eval.hpp +64 -57
  62. data/ext/libsass/src/eval_selectors.cpp +75 -0
  63. data/ext/libsass/src/expand.cpp +322 -263
  64. data/ext/libsass/src/expand.hpp +55 -39
  65. data/ext/libsass/src/extender.cpp +1188 -0
  66. data/ext/libsass/src/extender.hpp +399 -0
  67. data/ext/libsass/src/extension.cpp +43 -0
  68. data/ext/libsass/src/extension.hpp +89 -0
  69. data/ext/libsass/src/file.cpp +134 -88
  70. data/ext/libsass/src/file.hpp +28 -37
  71. data/ext/libsass/src/fn_colors.cpp +596 -0
  72. data/ext/libsass/src/fn_colors.hpp +85 -0
  73. data/ext/libsass/src/fn_lists.cpp +285 -0
  74. data/ext/libsass/src/fn_lists.hpp +34 -0
  75. data/ext/libsass/src/fn_maps.cpp +94 -0
  76. data/ext/libsass/src/fn_maps.hpp +30 -0
  77. data/ext/libsass/src/fn_miscs.cpp +244 -0
  78. data/ext/libsass/src/fn_miscs.hpp +40 -0
  79. data/ext/libsass/src/fn_numbers.cpp +227 -0
  80. data/ext/libsass/src/fn_numbers.hpp +45 -0
  81. data/ext/libsass/src/fn_selectors.cpp +205 -0
  82. data/ext/libsass/src/fn_selectors.hpp +35 -0
  83. data/ext/libsass/src/fn_strings.cpp +268 -0
  84. data/ext/libsass/src/fn_strings.hpp +34 -0
  85. data/ext/libsass/src/fn_utils.cpp +158 -0
  86. data/ext/libsass/src/fn_utils.hpp +62 -0
  87. data/ext/libsass/src/inspect.cpp +253 -266
  88. data/ext/libsass/src/inspect.hpp +72 -74
  89. data/ext/libsass/src/json.cpp +2 -2
  90. data/ext/libsass/src/lexer.cpp +25 -84
  91. data/ext/libsass/src/lexer.hpp +5 -16
  92. data/ext/libsass/src/listize.cpp +27 -43
  93. data/ext/libsass/src/listize.hpp +14 -11
  94. data/ext/libsass/src/mapping.hpp +1 -0
  95. data/ext/libsass/src/memory.hpp +12 -0
  96. data/ext/libsass/src/memory/allocator.cpp +48 -0
  97. data/ext/libsass/src/memory/allocator.hpp +138 -0
  98. data/ext/libsass/src/memory/config.hpp +20 -0
  99. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  100. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  101. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  102. data/ext/libsass/src/operation.hpp +193 -143
  103. data/ext/libsass/src/operators.cpp +56 -29
  104. data/ext/libsass/src/operators.hpp +11 -11
  105. data/ext/libsass/src/ordered_map.hpp +112 -0
  106. data/ext/libsass/src/output.cpp +59 -75
  107. data/ext/libsass/src/output.hpp +15 -22
  108. data/ext/libsass/src/parser.cpp +662 -818
  109. data/ext/libsass/src/parser.hpp +96 -100
  110. data/ext/libsass/src/parser_selectors.cpp +189 -0
  111. data/ext/libsass/src/permutate.hpp +164 -0
  112. data/ext/libsass/src/plugins.cpp +12 -8
  113. data/ext/libsass/src/plugins.hpp +8 -8
  114. data/ext/libsass/src/position.cpp +10 -26
  115. data/ext/libsass/src/position.hpp +44 -21
  116. data/ext/libsass/src/prelexer.cpp +14 -8
  117. data/ext/libsass/src/prelexer.hpp +9 -9
  118. data/ext/libsass/src/remove_placeholders.cpp +59 -57
  119. data/ext/libsass/src/remove_placeholders.hpp +20 -18
  120. data/ext/libsass/src/sass.cpp +25 -18
  121. data/ext/libsass/src/sass.hpp +22 -14
  122. data/ext/libsass/src/sass2scss.cpp +49 -18
  123. data/ext/libsass/src/sass_context.cpp +104 -132
  124. data/ext/libsass/src/sass_context.hpp +2 -2
  125. data/ext/libsass/src/sass_functions.cpp +7 -4
  126. data/ext/libsass/src/sass_functions.hpp +1 -1
  127. data/ext/libsass/src/sass_values.cpp +26 -21
  128. data/ext/libsass/src/settings.hpp +19 -0
  129. data/ext/libsass/src/source.cpp +69 -0
  130. data/ext/libsass/src/source.hpp +95 -0
  131. data/ext/libsass/src/source_data.hpp +32 -0
  132. data/ext/libsass/src/source_map.cpp +27 -20
  133. data/ext/libsass/src/source_map.hpp +14 -11
  134. data/ext/libsass/src/stylesheet.cpp +22 -0
  135. data/ext/libsass/src/stylesheet.hpp +57 -0
  136. data/ext/libsass/src/to_value.cpp +24 -22
  137. data/ext/libsass/src/to_value.hpp +18 -22
  138. data/ext/libsass/src/units.cpp +28 -22
  139. data/ext/libsass/src/units.hpp +9 -8
  140. data/ext/libsass/src/utf8/checked.h +12 -10
  141. data/ext/libsass/src/utf8/core.h +3 -0
  142. data/ext/libsass/src/utf8_string.cpp +12 -10
  143. data/ext/libsass/src/utf8_string.hpp +7 -6
  144. data/ext/libsass/src/util.cpp +97 -107
  145. data/ext/libsass/src/util.hpp +74 -30
  146. data/ext/libsass/src/util_string.cpp +125 -0
  147. data/ext/libsass/src/util_string.hpp +73 -0
  148. data/ext/libsass/src/values.cpp +33 -24
  149. data/ext/libsass/src/values.hpp +2 -2
  150. data/lib/sassc.rb +24 -0
  151. data/lib/sassc/engine.rb +7 -5
  152. data/lib/sassc/functions_handler.rb +11 -13
  153. data/lib/sassc/native.rb +10 -9
  154. data/lib/sassc/native/native_functions_api.rb +0 -5
  155. data/lib/sassc/script.rb +4 -6
  156. data/lib/sassc/version.rb +1 -1
  157. data/sassc.gemspec +32 -12
  158. data/test/engine_test.rb +32 -2
  159. data/test/functions_test.rb +38 -1
  160. data/test/native_test.rb +4 -4
  161. metadata +95 -109
  162. data/ext/Rakefile +0 -3
  163. data/ext/libsass/.editorconfig +0 -15
  164. data/ext/libsass/.gitattributes +0 -2
  165. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  166. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  167. data/ext/libsass/.gitignore +0 -85
  168. data/ext/libsass/.travis.yml +0 -64
  169. data/ext/libsass/COPYING +0 -25
  170. data/ext/libsass/GNUmakefile.am +0 -88
  171. data/ext/libsass/INSTALL +0 -1
  172. data/ext/libsass/LICENSE +0 -25
  173. data/ext/libsass/Makefile +0 -351
  174. data/ext/libsass/Makefile.conf +0 -55
  175. data/ext/libsass/Readme.md +0 -104
  176. data/ext/libsass/SECURITY.md +0 -10
  177. data/ext/libsass/appveyor.yml +0 -91
  178. data/ext/libsass/configure.ac +0 -138
  179. data/ext/libsass/contrib/libsass.spec +0 -66
  180. data/ext/libsass/docs/README.md +0 -20
  181. data/ext/libsass/docs/api-context-example.md +0 -45
  182. data/ext/libsass/docs/api-context-internal.md +0 -163
  183. data/ext/libsass/docs/api-context.md +0 -295
  184. data/ext/libsass/docs/api-doc.md +0 -215
  185. data/ext/libsass/docs/api-function-example.md +0 -67
  186. data/ext/libsass/docs/api-function-internal.md +0 -8
  187. data/ext/libsass/docs/api-function.md +0 -74
  188. data/ext/libsass/docs/api-importer-example.md +0 -112
  189. data/ext/libsass/docs/api-importer-internal.md +0 -20
  190. data/ext/libsass/docs/api-importer.md +0 -86
  191. data/ext/libsass/docs/api-value-example.md +0 -55
  192. data/ext/libsass/docs/api-value-internal.md +0 -76
  193. data/ext/libsass/docs/api-value.md +0 -154
  194. data/ext/libsass/docs/build-on-darwin.md +0 -27
  195. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  196. data/ext/libsass/docs/build-on-windows.md +0 -139
  197. data/ext/libsass/docs/build-shared-library.md +0 -35
  198. data/ext/libsass/docs/build-with-autotools.md +0 -78
  199. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  200. data/ext/libsass/docs/build-with-mingw.md +0 -107
  201. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  202. data/ext/libsass/docs/build.md +0 -97
  203. data/ext/libsass/docs/compatibility-plan.md +0 -48
  204. data/ext/libsass/docs/contributing.md +0 -17
  205. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  206. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  207. data/ext/libsass/docs/implementations.md +0 -56
  208. data/ext/libsass/docs/plugins.md +0 -47
  209. data/ext/libsass/docs/setup-environment.md +0 -68
  210. data/ext/libsass/docs/source-map-internals.md +0 -51
  211. data/ext/libsass/docs/trace.md +0 -26
  212. data/ext/libsass/docs/triage.md +0 -17
  213. data/ext/libsass/docs/unicode.md +0 -39
  214. data/ext/libsass/extconf.rb +0 -6
  215. data/ext/libsass/include/sass/version.h.in +0 -12
  216. data/ext/libsass/m4/.gitkeep +0 -0
  217. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
  218. data/ext/libsass/res/resource.rc +0 -35
  219. data/ext/libsass/script/bootstrap +0 -13
  220. data/ext/libsass/script/branding +0 -10
  221. data/ext/libsass/script/ci-build-libsass +0 -134
  222. data/ext/libsass/script/ci-build-plugin +0 -62
  223. data/ext/libsass/script/ci-install-compiler +0 -6
  224. data/ext/libsass/script/ci-install-deps +0 -20
  225. data/ext/libsass/script/ci-report-coverage +0 -42
  226. data/ext/libsass/script/spec +0 -5
  227. data/ext/libsass/script/tap-driver +0 -652
  228. data/ext/libsass/script/tap-runner +0 -1
  229. data/ext/libsass/script/test-leaks.pl +0 -103
  230. data/ext/libsass/src/GNUmakefile.am +0 -54
  231. data/ext/libsass/src/extend.cpp +0 -2130
  232. data/ext/libsass/src/extend.hpp +0 -86
  233. data/ext/libsass/src/functions.cpp +0 -2234
  234. data/ext/libsass/src/functions.hpp +0 -198
  235. data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
  236. data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
  237. data/ext/libsass/src/node.cpp +0 -319
  238. data/ext/libsass/src/node.hpp +0 -118
  239. data/ext/libsass/src/paths.hpp +0 -71
  240. data/ext/libsass/src/sass_util.cpp +0 -149
  241. data/ext/libsass/src/sass_util.hpp +0 -256
  242. data/ext/libsass/src/subset_map.cpp +0 -55
  243. data/ext/libsass/src/subset_map.hpp +0 -76
  244. data/ext/libsass/src/support/libsass.pc.in +0 -11
  245. data/ext/libsass/src/to_c.hpp +0 -39
  246. data/ext/libsass/test/test_node.cpp +0 -94
  247. data/ext/libsass/test/test_paths.cpp +0 -28
  248. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  249. data/ext/libsass/test/test_specificity.cpp +0 -25
  250. data/ext/libsass/test/test_subset_map.cpp +0 -472
  251. data/ext/libsass/test/test_superselector.cpp +0 -69
  252. data/ext/libsass/test/test_unification.cpp +0 -31
  253. data/ext/libsass/version.sh +0 -10
  254. data/ext/libsass/win/libsass.sln +0 -39
  255. data/ext/libsass/win/libsass.sln.DotSettings +0 -9
  256. data/ext/libsass/win/libsass.targets +0 -118
  257. data/ext/libsass/win/libsass.vcxproj +0 -188
  258. data/ext/libsass/win/libsass.vcxproj.filters +0 -357
  259. data/lib/sassc/native/lib_c.rb +0 -21
  260. data/lib/tasks/libsass.rb +0 -33
@@ -1,83 +1,26 @@
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"
5
- #include <set>
6
- #include <deque>
7
- #include <vector>
8
- #include <string>
9
- #include <sstream>
10
- #include <iostream>
7
+
11
8
  #include <typeinfo>
12
- #include <algorithm>
9
+ #include <unordered_map>
10
+
13
11
  #include "sass/base.h"
12
+ #include "ast_helpers.hpp"
14
13
  #include "ast_fwd_decl.hpp"
14
+ #include "ast_def_macros.hpp"
15
15
 
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
- #include "util.hpp"
53
- #include "units.hpp"
54
- #include "context.hpp"
16
+ #include "file.hpp"
55
17
  #include "position.hpp"
56
- #include "constants.hpp"
57
18
  #include "operation.hpp"
58
- #include "position.hpp"
59
- #include "inspect.hpp"
60
- #include "source_map.hpp"
61
19
  #include "environment.hpp"
62
- #include "error_handling.hpp"
63
- #include "ast_def_macros.hpp"
64
- #include "ast_fwd_decl.hpp"
65
- #include "source_map.hpp"
66
-
67
- #include "sass.h"
20
+ #include "fn_utils.hpp"
68
21
 
69
22
  namespace Sass {
70
23
 
71
- // easier to search with name
72
- const bool DELAYED = true;
73
-
74
- // ToDo: should this really be hardcoded
75
- // Note: most methods follow precision option
76
- const double NUMBER_EPSILON = 0.00000000000001;
77
-
78
- // macro to test if numbers are equal within a small error margin
79
- #define NEAR_EQUAL(lhs, rhs) std::fabs(lhs - rhs) < NUMBER_EPSILON
80
-
81
24
  // ToDo: where does this fit best?
82
25
  // We don't share this with C-API?
83
26
  class Operand {
@@ -104,38 +47,59 @@ namespace Sass {
104
47
  }
105
48
  //////////////////////////////////////////////////////////
106
49
 
50
+ const char* sass_op_to_name(enum Sass_OP op);
51
+
52
+ const char* sass_op_separator(enum Sass_OP op);
53
+
107
54
  //////////////////////////////////////////////////////////
108
55
  // Abstract base class for all abstract syntax tree nodes.
109
56
  //////////////////////////////////////////////////////////
110
57
  class AST_Node : public SharedObj {
111
- ADD_PROPERTY(ParserState, pstate)
58
+ ADD_PROPERTY(SourceSpan, pstate)
112
59
  public:
113
- AST_Node(ParserState pstate)
60
+ AST_Node(SourceSpan pstate)
114
61
  : pstate_(pstate)
115
62
  { }
116
63
  AST_Node(const AST_Node* ptr)
117
64
  : pstate_(ptr->pstate_)
118
65
  { }
119
66
 
67
+ // allow implicit conversion to string
68
+ // needed for by SharedPtr implementation
69
+ operator sass::string() {
70
+ return to_string();
71
+ }
72
+
120
73
  // AST_Node(AST_Node& ptr) = delete;
121
74
 
122
75
  virtual ~AST_Node() = 0;
123
- virtual size_t hash() { return 0; }
124
- ATTACH_VIRTUAL_AST_OPERATIONS(AST_Node);
125
- virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
126
- virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
127
- virtual const std::string to_string(Sass_Inspect_Options opt) const;
128
- virtual const std::string to_string() const;
76
+ virtual size_t hash() const { return 0; }
77
+ virtual sass::string inspect() const { return to_string({ INSPECT, 5 }); }
78
+ virtual sass::string to_sass() const { return to_string({ TO_SASS, 5 }); }
79
+ virtual sass::string to_string(Sass_Inspect_Options opt) const;
80
+ virtual sass::string to_css(Sass_Inspect_Options opt) const;
81
+ virtual sass::string to_string() const;
129
82
  virtual void cloneChildren() {};
130
83
  // generic find function (not fully implemented yet)
131
- // ToDo: add specific implementions to all children
84
+ // ToDo: add specific implementations to all children
132
85
  virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };
133
- public:
134
- void update_pstate(const ParserState& pstate);
135
- public:
136
- Offset off() { return pstate(); }
137
- Position pos() { return pstate(); }
138
- ATTACH_OPERATIONS()
86
+ void update_pstate(const SourceSpan& pstate);
87
+
88
+ // Some objects are not meant to be compared
89
+ // ToDo: maybe fall-back to pointer comparison?
90
+ virtual bool operator== (const AST_Node& rhs) const {
91
+ throw std::runtime_error("operator== not implemented");
92
+ }
93
+
94
+ // We can give some reasonable implementations by using
95
+ // invert operators on the specialized implementations
96
+ virtual bool operator!= (const AST_Node& rhs) const {
97
+ // Unequal if not equal
98
+ return !(*this == rhs);
99
+ }
100
+
101
+ ATTACH_ABSTRACT_AST_OPERATIONS(AST_Node);
102
+ ATTACH_ABSTRACT_CRTP_PERFORM_METHODS()
139
103
  };
140
104
  inline AST_Node::~AST_Node() { }
141
105
 
@@ -162,7 +126,7 @@ namespace Sass {
162
126
  //////////////////////////////////////////////////////////////////////
163
127
  class Expression : public AST_Node {
164
128
  public:
165
- enum Concrete_Type {
129
+ enum Type {
166
130
  NONE,
167
131
  BOOLEAN,
168
132
  NUMBER,
@@ -177,86 +141,39 @@ namespace Sass {
177
141
  C_ERROR,
178
142
  FUNCTION,
179
143
  VARIABLE,
144
+ PARENT,
180
145
  NUM_TYPES
181
146
  };
182
- enum Simple_Type {
183
- SIMPLE,
184
- ATTR_SEL,
185
- PSEUDO_SEL,
186
- WRAPPED_SEL,
187
- };
188
147
  private:
189
148
  // expressions in some contexts shouldn't be evaluated
190
149
  ADD_PROPERTY(bool, is_delayed)
191
150
  ADD_PROPERTY(bool, is_expanded)
192
151
  ADD_PROPERTY(bool, is_interpolant)
193
- ADD_PROPERTY(Concrete_Type, concrete_type)
152
+ ADD_PROPERTY(Type, concrete_type)
194
153
  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
- { }
154
+ Expression(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);
210
155
  virtual operator bool() { return true; }
211
156
  virtual ~Expression() { }
212
- virtual std::string type() const { return ""; /* TODO: raise an error? */ }
213
157
  virtual bool is_invisible() const { return false; }
214
- static std::string type_name() { return ""; }
158
+
159
+ virtual sass::string type() const { return ""; }
160
+ static sass::string type_name() { return ""; }
161
+
215
162
  virtual bool is_false() { return false; }
216
163
  // virtual bool is_true() { return !is_false(); }
164
+ virtual bool operator< (const Expression& rhs) const { return false; }
217
165
  virtual bool operator== (const Expression& rhs) const { return false; }
166
+ inline bool operator>(const Expression& rhs) const { return rhs < *this; }
167
+ inline bool operator!=(const Expression& rhs) const { return !(rhs == *this); }
218
168
  virtual bool eq(const Expression& rhs) const { return *this == rhs; };
219
169
  virtual void set_delayed(bool delayed) { is_delayed(delayed); }
220
170
  virtual bool has_interpolant() const { return is_interpolant(); }
221
171
  virtual bool is_left_interpolant() const { return is_interpolant(); }
222
172
  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
173
  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() { }
174
+ size_t hash() const override { return 0; }
243
175
  };
244
176
 
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
177
  }
261
178
 
262
179
  /////////////////////////////////////////////////////////////////////////////////////
@@ -265,17 +182,17 @@ namespace Sass {
265
182
 
266
183
  namespace std {
267
184
  template<>
268
- struct hash<Sass::Expression_Obj>
185
+ struct hash<Sass::ExpressionObj>
269
186
  {
270
- size_t operator()(Sass::Expression_Obj s) const
187
+ size_t operator()(Sass::ExpressionObj s) const
271
188
  {
272
189
  return s->hash();
273
190
  }
274
191
  };
275
192
  template<>
276
- struct equal_to<Sass::Expression_Obj>
193
+ struct equal_to<Sass::ExpressionObj>
277
194
  {
278
- bool operator()( Sass::Expression_Obj lhs, Sass::Expression_Obj rhs) const
195
+ bool operator()( Sass::ExpressionObj lhs, Sass::ExpressionObj rhs) const
279
196
  {
280
197
  return lhs->hash() == rhs->hash();
281
198
  }
@@ -291,61 +208,143 @@ namespace Sass {
291
208
  /////////////////////////////////////////////////////////////////////////////
292
209
  template <typename T>
293
210
  class Vectorized {
294
- std::vector<T> elements_;
211
+ sass::vector<T> elements_;
295
212
  protected:
296
- size_t hash_;
213
+ mutable size_t hash_;
297
214
  void reset_hash() { hash_ = 0; }
298
215
  virtual void adjust_after_pushing(T element) { }
299
216
  public:
300
- Vectorized(size_t s = 0) : elements_(std::vector<T>()), hash_(0)
217
+ Vectorized(size_t s = 0) : hash_(0)
301
218
  { elements_.reserve(s); }
219
+ Vectorized(sass::vector<T> vec) :
220
+ elements_(std::move(vec)),
221
+ hash_(0)
222
+ {}
302
223
  virtual ~Vectorized() = 0;
303
224
  size_t length() const { return elements_.size(); }
304
225
  bool empty() const { return elements_.empty(); }
305
226
  void clear() { return elements_.clear(); }
306
- T last() const { return elements_.back(); }
307
- T first() const { return elements_.front(); }
227
+ T& last() { return elements_.back(); }
228
+ T& first() { return elements_.front(); }
229
+ const T& last() const { return elements_.back(); }
230
+ const T& first() const { return elements_.front(); }
231
+
232
+ bool operator== (const Vectorized<T>& rhs) const {
233
+ // Abort early if sizes do not match
234
+ if (length() != rhs.length()) return false;
235
+ // Otherwise test each node for object equalicy in order
236
+ return std::equal(begin(), end(), rhs.begin(), ObjEqualityFn<T>);
237
+ }
238
+
239
+ bool operator!= (const Vectorized<T>& rhs) const {
240
+ return !(*this == rhs);
241
+ }
242
+
308
243
  T& operator[](size_t i) { return elements_[i]; }
309
244
  virtual const T& at(size_t i) const { return elements_.at(i); }
310
245
  virtual T& at(size_t i) { return elements_.at(i); }
246
+ const T& get(size_t i) const { return elements_[i]; }
311
247
  const T& operator[](size_t i) const { return elements_[i]; }
312
- virtual void append(T element)
248
+
249
+ // Implicitly get the sass::vector from our object
250
+ // Makes the Vector directly assignable to sass::vector
251
+ // You are responsible to make a copy if needed
252
+ // Note: since this returns the real object, we can't
253
+ // Note: guarantee that the hash will not get out of sync
254
+ operator sass::vector<T>&() { return elements_; }
255
+ operator const sass::vector<T>&() const { return elements_; }
256
+
257
+ // Explicitly request all elements as a real sass::vector
258
+ // You are responsible to make a copy if needed
259
+ // Note: since this returns the real object, we can't
260
+ // Note: guarantee that the hash will not get out of sync
261
+ sass::vector<T>& elements() { return elements_; }
262
+ const sass::vector<T>& elements() const { return elements_; }
263
+
264
+ // Insert all items from compatible vector
265
+ void concat(const sass::vector<T>& v)
266
+ {
267
+ if (!v.empty()) reset_hash();
268
+ elements().insert(end(), v.begin(), v.end());
269
+ }
270
+
271
+ // Syntatic sugar for pointers
272
+ void concat(const Vectorized<T>* v)
313
273
  {
314
- if (element) {
315
- reset_hash();
316
- elements_.push_back(element);
317
- adjust_after_pushing(element);
274
+ if (v != nullptr) {
275
+ return concat(*v);
318
276
  }
319
277
  }
320
- virtual void concat(Vectorized* v)
278
+
279
+ // Insert one item on the front
280
+ void unshift(T element)
321
281
  {
322
- for (size_t i = 0, L = v->length(); i < L; ++i) this->append((*v)[i]);
282
+ reset_hash();
283
+ elements_.insert(begin(), element);
284
+ }
285
+
286
+ // Remove and return item on the front
287
+ // ToDo: handle empty vectors
288
+ T shift() {
289
+ reset_hash();
290
+ T first = get(0);
291
+ elements_.erase(begin());
292
+ return first;
323
293
  }
324
- Vectorized& unshift(T element)
294
+
295
+ // Insert one item on the back
296
+ // ToDo: rename this to push
297
+ void append(T element)
325
298
  {
326
- elements_.insert(elements_.begin(), element);
327
- return *this;
299
+ reset_hash();
300
+ elements_.insert(end(), element);
301
+ // ToDo: Mostly used by parameters and arguments
302
+ // ToDo: Find a more elegant way to support this
303
+ adjust_after_pushing(element);
304
+ }
305
+
306
+ // Check if an item already exists
307
+ // Uses underlying object `operator==`
308
+ // E.g. compares the actual objects
309
+ bool contains(const T& el) const {
310
+ for (const T& rhs : elements_) {
311
+ // Test the underlying objects for equality
312
+ // A std::find checks for pointer equality
313
+ if (ObjEqualityFn(el, rhs)) {
314
+ return true;
315
+ }
316
+ }
317
+ return false;
328
318
  }
329
- std::vector<T>& elements() { return elements_; }
330
- const std::vector<T>& elements() const { return elements_; }
331
- std::vector<T>& elements(std::vector<T>& e) { elements_ = e; return elements_; }
332
319
 
333
- virtual size_t hash()
320
+ // This might be better implemented as `operator=`?
321
+ void elements(sass::vector<T> e) {
322
+ reset_hash();
323
+ elements_ = std::move(e);
324
+ }
325
+
326
+ virtual size_t hash() const
334
327
  {
335
328
  if (hash_ == 0) {
336
- for (T& el : elements_) {
329
+ for (const T& el : elements_) {
337
330
  hash_combine(hash_, el->hash());
338
331
  }
339
332
  }
340
333
  return hash_;
341
334
  }
342
335
 
343
- typename std::vector<T>::iterator end() { return elements_.end(); }
344
- typename std::vector<T>::iterator begin() { return elements_.begin(); }
345
- typename std::vector<T>::const_iterator end() const { return elements_.end(); }
346
- typename std::vector<T>::const_iterator begin() const { return elements_.begin(); }
347
- typename std::vector<T>::iterator erase(typename std::vector<T>::iterator el) { return elements_.erase(el); }
348
- typename std::vector<T>::const_iterator erase(typename std::vector<T>::const_iterator el) { return elements_.erase(el); }
336
+ template <typename P, typename V>
337
+ typename sass::vector<T>::iterator insert(P position, const V& val) {
338
+ reset_hash();
339
+ return elements_.insert(position, val);
340
+ }
341
+
342
+ typename sass::vector<T>::iterator end() { return elements_.end(); }
343
+ typename sass::vector<T>::iterator begin() { return elements_.begin(); }
344
+ typename sass::vector<T>::const_iterator end() const { return elements_.end(); }
345
+ typename sass::vector<T>::const_iterator begin() const { return elements_.begin(); }
346
+ typename sass::vector<T>::iterator erase(typename sass::vector<T>::iterator el) { reset_hash(); return elements_.erase(el); }
347
+ typename sass::vector<T>::const_iterator erase(typename sass::vector<T>::const_iterator el) { reset_hash(); return elements_.erase(el); }
349
348
 
350
349
  };
351
350
  template <typename T>
@@ -353,38 +352,63 @@ namespace Sass {
353
352
 
354
353
  /////////////////////////////////////////////////////////////////////////////
355
354
  // Mixin class for AST nodes that should behave like a hash table. Uses an
356
- // extra <std::vector> internally to maintain insertion order for interation.
355
+ // extra <sass::vector> internally to maintain insertion order for interation.
357
356
  /////////////////////////////////////////////////////////////////////////////
357
+ template <typename K, typename T, typename U>
358
358
  class Hashed {
359
359
  private:
360
- ExpressionMap elements_;
361
- std::vector<Expression_Obj> list_;
360
+ std::unordered_map<
361
+ K, T, ObjHash, ObjEquality
362
+ > elements_;
363
+
364
+ sass::vector<K> _keys;
365
+ sass::vector<T> _values;
362
366
  protected:
363
- size_t hash_;
364
- Expression_Obj duplicate_key_;
367
+ mutable size_t hash_;
368
+ K duplicate_key_;
365
369
  void reset_hash() { hash_ = 0; }
366
- void reset_duplicate_key() { duplicate_key_ = 0; }
367
- virtual void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { }
370
+ void reset_duplicate_key() { duplicate_key_ = {}; }
371
+ virtual void adjust_after_pushing(std::pair<K, T> p) { }
368
372
  public:
369
373
  Hashed(size_t s = 0)
370
- : elements_(ExpressionMap(s)),
371
- list_(std::vector<Expression_Obj>()),
372
- hash_(0), duplicate_key_(NULL)
373
- { elements_.reserve(s); list_.reserve(s); }
374
+ : elements_(),
375
+ _keys(),
376
+ _values(),
377
+ hash_(0), duplicate_key_({})
378
+ {
379
+ _keys.reserve(s);
380
+ _values.reserve(s);
381
+ elements_.reserve(s);
382
+ }
374
383
  virtual ~Hashed();
375
- size_t length() const { return list_.size(); }
376
- bool empty() const { return list_.empty(); }
377
- bool has(Expression_Obj k) const { return elements_.count(k) == 1; }
378
- Expression_Obj at(Expression_Obj k) const;
379
- bool has_duplicate_key() const { return duplicate_key_ != 0; }
380
- Expression_Obj get_duplicate_key() const { return duplicate_key_; }
381
- const ExpressionMap elements() { return elements_; }
382
- Hashed& operator<<(std::pair<Expression_Obj, Expression_Obj> p)
384
+ size_t length() const { return _keys.size(); }
385
+ bool empty() const { return _keys.empty(); }
386
+ bool has(K k) const {
387
+ return elements_.find(k) != elements_.end();
388
+ }
389
+ T at(K k) const {
390
+ if (elements_.count(k))
391
+ {
392
+ return elements_.at(k);
393
+ }
394
+ else { return {}; }
395
+ }
396
+ bool has_duplicate_key() const { return duplicate_key_ != nullptr; }
397
+ K get_duplicate_key() const { return duplicate_key_; }
398
+ const std::unordered_map<
399
+ K, T, ObjHash, ObjEquality
400
+ >& elements() { return elements_; }
401
+ Hashed& operator<<(std::pair<K, T> p)
383
402
  {
384
403
  reset_hash();
385
404
 
386
- if (!has(p.first)) list_.push_back(p.first);
387
- else if (!duplicate_key_) duplicate_key_ = p.first;
405
+ if (!has(p.first)) {
406
+ _keys.push_back(p.first);
407
+ _values.push_back(p.second);
408
+ }
409
+ else if (!duplicate_key_) {
410
+ duplicate_key_ = p.first;
411
+ }
388
412
 
389
413
  elements_[p.first] = p.second;
390
414
 
@@ -395,7 +419,8 @@ namespace Sass {
395
419
  {
396
420
  if (length() == 0) {
397
421
  this->elements_ = h->elements_;
398
- this->list_ = h->list_;
422
+ this->_values = h->_values;
423
+ this->_keys = h->_keys;
399
424
  return *this;
400
425
  }
401
426
 
@@ -406,17 +431,21 @@ namespace Sass {
406
431
  reset_duplicate_key();
407
432
  return *this;
408
433
  }
409
- const ExpressionMap& pairs() const { return elements_; }
410
- const std::vector<Expression_Obj>& keys() const { return list_; }
434
+ const std::unordered_map<
435
+ K, T, ObjHash, ObjEquality
436
+ >& pairs() const { return elements_; }
411
437
 
412
- // std::unordered_map<Expression_Obj, Expression_Obj>::iterator end() { return elements_.end(); }
413
- // std::unordered_map<Expression_Obj, Expression_Obj>::iterator begin() { return elements_.begin(); }
414
- // std::unordered_map<Expression_Obj, Expression_Obj>::const_iterator end() const { return elements_.end(); }
415
- // std::unordered_map<Expression_Obj, Expression_Obj>::const_iterator begin() const { return elements_.begin(); }
438
+ const sass::vector<K>& keys() const { return _keys; }
439
+ const sass::vector<T>& values() const { return _values; }
416
440
 
417
- };
418
- inline Hashed::~Hashed() { }
441
+ // std::unordered_map<ExpressionObj, ExpressionObj>::iterator end() { return elements_.end(); }
442
+ // std::unordered_map<ExpressionObj, ExpressionObj>::iterator begin() { return elements_.begin(); }
443
+ // std::unordered_map<ExpressionObj, ExpressionObj>::const_iterator end() const { return elements_.end(); }
444
+ // std::unordered_map<ExpressionObj, ExpressionObj>::const_iterator begin() const { return elements_.begin(); }
419
445
 
446
+ };
447
+ template <typename K, typename T, typename U>
448
+ inline Hashed<K, T, U>::~Hashed() { }
420
449
 
421
450
  /////////////////////////////////////////////////////////////////////////
422
451
  // Abstract base class for statements. This side of the AST hierarchy
@@ -425,7 +454,7 @@ namespace Sass {
425
454
  /////////////////////////////////////////////////////////////////////////
426
455
  class Statement : public AST_Node {
427
456
  public:
428
- enum Statement_Type {
457
+ enum Type {
429
458
  NONE,
430
459
  RULESET,
431
460
  MEDIA,
@@ -451,505 +480,293 @@ namespace Sass {
451
480
  IF
452
481
  };
453
482
  private:
454
- ADD_PROPERTY(Statement_Type, statement_type)
483
+ ADD_PROPERTY(Type, statement_type)
455
484
  ADD_PROPERTY(size_t, tabs)
456
485
  ADD_PROPERTY(bool, group_end)
457
486
  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;
487
+ Statement(SourceSpan pstate, Type st = NONE, size_t t = 0);
488
+ virtual ~Statement() = 0; // virtual destructor
468
489
  // 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
- }
490
+ virtual bool bubbles();
491
+ virtual bool has_content();
492
+ virtual bool is_invisible() const;
493
+ ATTACH_VIRTUAL_AST_OPERATIONS(Statement)
475
494
  };
476
495
  inline Statement::~Statement() { }
477
496
 
478
497
  ////////////////////////
479
498
  // Blocks of statements.
480
499
  ////////////////////////
481
- class Block : public Statement, public Vectorized<Statement_Obj> {
500
+ class Block final : public Statement, public Vectorized<Statement_Obj> {
482
501
  ADD_PROPERTY(bool, is_root)
483
502
  // needed for properly formatted CSS emission
484
503
  protected:
485
- void adjust_after_pushing(Statement_Obj s)
486
- {
487
- }
504
+ void adjust_after_pushing(Statement_Obj s) override {}
488
505
  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
- }
506
+ Block(SourceSpan pstate, size_t s = 0, bool r = false);
507
+ bool isInvisible() const;
508
+ bool has_content() override;
506
509
  ATTACH_AST_OPERATIONS(Block)
507
- ATTACH_OPERATIONS()
510
+ ATTACH_CRTP_PERFORM_METHODS()
508
511
  };
509
512
 
510
513
  ////////////////////////////////////////////////////////////////////////
511
514
  // Abstract base class for statements that contain blocks of statements.
512
515
  ////////////////////////////////////////////////////////////////////////
513
- class Has_Block : public Statement {
516
+ class ParentStatement : public Statement {
514
517
  ADD_PROPERTY(Block_Obj, block)
515
518
  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;
519
+ ParentStatement(SourceSpan pstate, Block_Obj b);
520
+ ParentStatement(const ParentStatement* ptr); // copy constructor
521
+ virtual ~ParentStatement() = 0; // virtual destructor
522
+ virtual bool has_content() override;
527
523
  };
528
- inline Has_Block::~Has_Block() { }
524
+ inline ParentStatement::~ParentStatement() { }
529
525
 
530
526
  /////////////////////////////////////////////////////////////////////////////
531
527
  // Rulesets (i.e., sets of styles headed by a selector and containing a block
532
528
  // of style declarations.
533
529
  /////////////////////////////////////////////////////////////////////////////
534
- class Ruleset : public Has_Block {
535
- ADD_PROPERTY(Selector_List_Obj, selector)
530
+ class StyleRule final : public ParentStatement {
531
+ ADD_PROPERTY(SelectorListObj, selector)
532
+ ADD_PROPERTY(Selector_Schema_Obj, schema)
536
533
  ADD_PROPERTY(bool, is_root);
537
534
  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;
547
- ATTACH_AST_OPERATIONS(Ruleset)
548
- ATTACH_OPERATIONS()
535
+ StyleRule(SourceSpan pstate, SelectorListObj s = {}, Block_Obj b = {});
536
+ bool is_invisible() const override;
537
+ ATTACH_AST_OPERATIONS(StyleRule)
538
+ ATTACH_CRTP_PERFORM_METHODS()
549
539
  };
550
540
 
551
541
  /////////////////
552
542
  // Bubble.
553
543
  /////////////////
554
- class Bubble : public Statement {
544
+ class Bubble final : public Statement {
555
545
  ADD_PROPERTY(Statement_Obj, node)
556
546
  ADD_PROPERTY(bool, group_end)
557
547
  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; }
548
+ Bubble(SourceSpan pstate, Statement_Obj n, Statement_Obj g = {}, size_t t = 0);
549
+ bool bubbles() override;
567
550
  ATTACH_AST_OPERATIONS(Bubble)
568
- ATTACH_OPERATIONS()
551
+ ATTACH_CRTP_PERFORM_METHODS()
569
552
  };
570
553
 
571
554
  /////////////////
572
555
  // Trace.
573
556
  /////////////////
574
- class Trace : public Has_Block {
557
+ class Trace final : public ParentStatement {
575
558
  ADD_CONSTREF(char, type)
576
- ADD_CONSTREF(std::string, name)
559
+ ADD_CONSTREF(sass::string, name)
577
560
  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
- { }
561
+ Trace(SourceSpan pstate, sass::string n, Block_Obj b = {}, char type = 'm');
586
562
  ATTACH_AST_OPERATIONS(Trace)
587
- ATTACH_OPERATIONS()
588
- };
589
-
590
- /////////////////
591
- // Media queries.
592
- /////////////////
593
- class Media_Block : public Has_Block {
594
- ADD_PROPERTY(List_Obj, media_queries)
595
- 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;
604
- ATTACH_AST_OPERATIONS(Media_Block)
605
- ATTACH_OPERATIONS()
563
+ ATTACH_CRTP_PERFORM_METHODS()
606
564
  };
607
565
 
608
566
  ///////////////////////////////////////////////////////////////////////
609
567
  // At-rules -- arbitrary directives beginning with "@" that may have an
610
568
  // optional statement block.
611
569
  ///////////////////////////////////////////////////////////////////////
612
- class Directive : public Has_Block {
613
- ADD_CONSTREF(std::string, keyword)
614
- ADD_PROPERTY(Selector_List_Obj, selector)
615
- ADD_PROPERTY(Expression_Obj, value)
570
+ class AtRule final : public ParentStatement {
571
+ ADD_CONSTREF(sass::string, keyword)
572
+ ADD_PROPERTY(SelectorListObj, selector)
573
+ ADD_PROPERTY(ExpressionObj, value)
616
574
  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
- }
639
- ATTACH_AST_OPERATIONS(Directive)
640
- ATTACH_OPERATIONS()
575
+ AtRule(SourceSpan pstate, sass::string kwd, SelectorListObj sel = {}, Block_Obj b = {}, ExpressionObj val = {});
576
+ bool bubbles() override;
577
+ bool is_media();
578
+ bool is_keyframes();
579
+ ATTACH_AST_OPERATIONS(AtRule)
580
+ ATTACH_CRTP_PERFORM_METHODS()
641
581
  };
642
582
 
643
583
  ///////////////////////////////////////////////////////////////////////
644
584
  // Keyframe-rules -- the child blocks of "@keyframes" nodes.
645
585
  ///////////////////////////////////////////////////////////////////////
646
- class Keyframe_Rule : public Has_Block {
586
+ class Keyframe_Rule final : public ParentStatement {
647
587
  // according to css spec, this should be <keyframes-name>
648
588
  // <keyframes-name> = <custom-ident> | <string>
649
- ADD_PROPERTY(Selector_List_Obj, name)
589
+ ADD_PROPERTY(SelectorListObj, name)
650
590
  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); }
591
+ Keyframe_Rule(SourceSpan pstate, Block_Obj b);
657
592
  ATTACH_AST_OPERATIONS(Keyframe_Rule)
658
- ATTACH_OPERATIONS()
593
+ ATTACH_CRTP_PERFORM_METHODS()
659
594
  };
660
595
 
661
596
  ////////////////////////////////////////////////////////////////////////
662
597
  // Declarations -- style rules consisting of a property name and values.
663
598
  ////////////////////////////////////////////////////////////////////////
664
- class Declaration : public Has_Block {
599
+ class Declaration final : public ParentStatement {
665
600
  ADD_PROPERTY(String_Obj, property)
666
- ADD_PROPERTY(Expression_Obj, value)
601
+ ADD_PROPERTY(ExpressionObj, value)
667
602
  ADD_PROPERTY(bool, is_important)
668
603
  ADD_PROPERTY(bool, is_custom_property)
669
604
  ADD_PROPERTY(bool, is_indented)
670
605
  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;
606
+ Declaration(SourceSpan pstate, String_Obj prop, ExpressionObj val, bool i = false, bool c = false, Block_Obj b = {});
607
+ bool is_invisible() const override;
684
608
  ATTACH_AST_OPERATIONS(Declaration)
685
- ATTACH_OPERATIONS()
609
+ ATTACH_CRTP_PERFORM_METHODS()
686
610
  };
687
611
 
688
612
  /////////////////////////////////////
689
613
  // Assignments -- variable and value.
690
614
  /////////////////////////////////////
691
- class Assignment : public Statement {
692
- ADD_CONSTREF(std::string, variable)
693
- ADD_PROPERTY(Expression_Obj, value)
615
+ class Assignment final : public Statement {
616
+ ADD_CONSTREF(sass::string, variable)
617
+ ADD_PROPERTY(ExpressionObj, value)
694
618
  ADD_PROPERTY(bool, is_default)
695
619
  ADD_PROPERTY(bool, is_global)
696
620
  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); }
621
+ Assignment(SourceSpan pstate, sass::string var, ExpressionObj val, bool is_default = false, bool is_global = false);
710
622
  ATTACH_AST_OPERATIONS(Assignment)
711
- ATTACH_OPERATIONS()
623
+ ATTACH_CRTP_PERFORM_METHODS()
712
624
  };
713
625
 
714
626
  ////////////////////////////////////////////////////////////////////////////
715
627
  // Import directives. CSS and Sass import lists can be intermingled, so it's
716
628
  // necessary to store a list of each in an Import node.
717
629
  ////////////////////////////////////////////////////////////////////////////
718
- class Import : public Statement {
719
- std::vector<Expression_Obj> urls_;
720
- std::vector<Include> incs_;
630
+ class Import final : public Statement {
631
+ sass::vector<ExpressionObj> urls_;
632
+ sass::vector<Include> incs_;
721
633
  ADD_PROPERTY(List_Obj, import_queries);
722
634
  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_; }
635
+ Import(SourceSpan pstate);
636
+ sass::vector<Include>& incs();
637
+ sass::vector<ExpressionObj>& urls();
737
638
  ATTACH_AST_OPERATIONS(Import)
738
- ATTACH_OPERATIONS()
639
+ ATTACH_CRTP_PERFORM_METHODS()
739
640
  };
740
641
 
741
642
  // not yet resolved single import
742
643
  // so far we only know requested name
743
- class Import_Stub : public Statement {
644
+ class Import_Stub final : public Statement {
744
645
  Include resource_;
745
646
  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); }
647
+ Import_Stub(SourceSpan pstate, Include res);
648
+ Include resource();
649
+ sass::string imp_path();
650
+ sass::string abs_path();
756
651
  ATTACH_AST_OPERATIONS(Import_Stub)
757
- ATTACH_OPERATIONS()
652
+ ATTACH_CRTP_PERFORM_METHODS()
758
653
  };
759
654
 
760
655
  //////////////////////////////
761
656
  // The Sass `@warn` directive.
762
657
  //////////////////////////////
763
- class Warning : public Statement {
764
- ADD_PROPERTY(Expression_Obj, message)
658
+ class WarningRule final : public Statement {
659
+ ADD_PROPERTY(ExpressionObj, message)
765
660
  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); }
772
- ATTACH_AST_OPERATIONS(Warning)
773
- ATTACH_OPERATIONS()
661
+ WarningRule(SourceSpan pstate, ExpressionObj msg);
662
+ ATTACH_AST_OPERATIONS(WarningRule)
663
+ ATTACH_CRTP_PERFORM_METHODS()
774
664
  };
775
665
 
776
666
  ///////////////////////////////
777
667
  // The Sass `@error` directive.
778
668
  ///////////////////////////////
779
- class Error : public Statement {
780
- ADD_PROPERTY(Expression_Obj, message)
669
+ class ErrorRule final : public Statement {
670
+ ADD_PROPERTY(ExpressionObj, message)
781
671
  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); }
788
- ATTACH_AST_OPERATIONS(Error)
789
- ATTACH_OPERATIONS()
672
+ ErrorRule(SourceSpan pstate, ExpressionObj msg);
673
+ ATTACH_AST_OPERATIONS(ErrorRule)
674
+ ATTACH_CRTP_PERFORM_METHODS()
790
675
  };
791
676
 
792
677
  ///////////////////////////////
793
678
  // The Sass `@debug` directive.
794
679
  ///////////////////////////////
795
- class Debug : public Statement {
796
- ADD_PROPERTY(Expression_Obj, value)
680
+ class DebugRule final : public Statement {
681
+ ADD_PROPERTY(ExpressionObj, value)
797
682
  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); }
804
- ATTACH_AST_OPERATIONS(Debug)
805
- ATTACH_OPERATIONS()
683
+ DebugRule(SourceSpan pstate, ExpressionObj val);
684
+ ATTACH_AST_OPERATIONS(DebugRule)
685
+ ATTACH_CRTP_PERFORM_METHODS()
806
686
  };
807
687
 
808
688
  ///////////////////////////////////////////
809
689
  // CSS comments. These may be interpolated.
810
690
  ///////////////////////////////////////////
811
- class Comment : public Statement {
691
+ class Comment final : public Statement {
812
692
  ADD_PROPERTY(String_Obj, text)
813
693
  ADD_PROPERTY(bool, is_important)
814
694
  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; }
695
+ Comment(SourceSpan pstate, String_Obj txt, bool is_important);
696
+ virtual bool is_invisible() const override;
825
697
  ATTACH_AST_OPERATIONS(Comment)
826
- ATTACH_OPERATIONS()
698
+ ATTACH_CRTP_PERFORM_METHODS()
827
699
  };
828
700
 
829
701
  ////////////////////////////////////
830
702
  // The Sass `@if` control directive.
831
703
  ////////////////////////////////////
832
- class If : public Has_Block {
833
- ADD_PROPERTY(Expression_Obj, predicate)
704
+ class If final : public ParentStatement {
705
+ ADD_PROPERTY(ExpressionObj, predicate)
834
706
  ADD_PROPERTY(Block_Obj, alternative)
835
707
  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
- }
708
+ If(SourceSpan pstate, ExpressionObj pred, Block_Obj con, Block_Obj alt = {});
709
+ virtual bool has_content() override;
848
710
  ATTACH_AST_OPERATIONS(If)
849
- ATTACH_OPERATIONS()
711
+ ATTACH_CRTP_PERFORM_METHODS()
850
712
  };
851
713
 
852
714
  /////////////////////////////////////
853
715
  // The Sass `@for` control directive.
854
716
  /////////////////////////////////////
855
- class For : public Has_Block {
856
- ADD_CONSTREF(std::string, variable)
857
- ADD_PROPERTY(Expression_Obj, lower_bound)
858
- ADD_PROPERTY(Expression_Obj, upper_bound)
717
+ class ForRule final : public ParentStatement {
718
+ ADD_CONSTREF(sass::string, variable)
719
+ ADD_PROPERTY(ExpressionObj, lower_bound)
720
+ ADD_PROPERTY(ExpressionObj, upper_bound)
859
721
  ADD_PROPERTY(bool, is_inclusive)
860
722
  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); }
873
- ATTACH_AST_OPERATIONS(For)
874
- ATTACH_OPERATIONS()
723
+ ForRule(SourceSpan pstate, sass::string var, ExpressionObj lo, ExpressionObj hi, Block_Obj b, bool inc);
724
+ ATTACH_AST_OPERATIONS(ForRule)
725
+ ATTACH_CRTP_PERFORM_METHODS()
875
726
  };
876
727
 
877
728
  //////////////////////////////////////
878
729
  // The Sass `@each` control directive.
879
730
  //////////////////////////////////////
880
- class Each : public Has_Block {
881
- ADD_PROPERTY(std::vector<std::string>, variables)
882
- ADD_PROPERTY(Expression_Obj, list)
731
+ class EachRule final : public ParentStatement {
732
+ ADD_PROPERTY(sass::vector<sass::string>, variables)
733
+ ADD_PROPERTY(ExpressionObj, list)
883
734
  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); }
890
- ATTACH_AST_OPERATIONS(Each)
891
- ATTACH_OPERATIONS()
735
+ EachRule(SourceSpan pstate, sass::vector<sass::string> vars, ExpressionObj lst, Block_Obj b);
736
+ ATTACH_AST_OPERATIONS(EachRule)
737
+ ATTACH_CRTP_PERFORM_METHODS()
892
738
  };
893
739
 
894
740
  ///////////////////////////////////////
895
741
  // The Sass `@while` control directive.
896
742
  ///////////////////////////////////////
897
- class While : public Has_Block {
898
- ADD_PROPERTY(Expression_Obj, predicate)
743
+ class WhileRule final : public ParentStatement {
744
+ ADD_PROPERTY(ExpressionObj, predicate)
899
745
  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); }
906
- ATTACH_AST_OPERATIONS(While)
907
- ATTACH_OPERATIONS()
746
+ WhileRule(SourceSpan pstate, ExpressionObj pred, Block_Obj b);
747
+ ATTACH_AST_OPERATIONS(WhileRule)
748
+ ATTACH_CRTP_PERFORM_METHODS()
908
749
  };
909
750
 
910
751
  /////////////////////////////////////////////////////////////
911
752
  // The @return directive for use inside SassScript functions.
912
753
  /////////////////////////////////////////////////////////////
913
- class Return : public Statement {
914
- ADD_PROPERTY(Expression_Obj, value)
754
+ class Return final : public Statement {
755
+ ADD_PROPERTY(ExpressionObj, value)
915
756
  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); }
757
+ Return(SourceSpan pstate, ExpressionObj val);
922
758
  ATTACH_AST_OPERATIONS(Return)
923
- ATTACH_OPERATIONS()
924
- };
925
-
926
- ////////////////////////////////
927
- // The Sass `@extend` directive.
928
- ////////////////////////////////
929
- class Extension : public Statement {
930
- ADD_PROPERTY(Selector_List_Obj, selector)
931
- 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); }
938
- ATTACH_AST_OPERATIONS(Extension)
939
- ATTACH_OPERATIONS()
759
+ ATTACH_CRTP_PERFORM_METHODS()
940
760
  };
941
761
 
942
762
  /////////////////////////////////////////////////////////////////////////////
943
763
  // Definitions for both mixins and functions. The two cases are distinguished
944
764
  // by a type tag.
945
765
  /////////////////////////////////////////////////////////////////////////////
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 {
766
+ class Definition final : public ParentStatement {
950
767
  public:
951
768
  enum Type { MIXIN, FUNCTION };
952
- ADD_CONSTREF(std::string, name)
769
+ ADD_CONSTREF(sass::string, name)
953
770
  ADD_PROPERTY(Parameters_Obj, parameters)
954
771
  ADD_PROPERTY(Env*, environment)
955
772
  ADD_PROPERTY(Type, type)
@@ -959,439 +776,85 @@ namespace Sass {
959
776
  ADD_PROPERTY(bool, is_overload_stub)
960
777
  ADD_PROPERTY(Signature, signature)
961
778
  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
- Definition(ParserState pstate,
976
- std::string n,
779
+ Definition(SourceSpan pstate,
780
+ sass::string n,
977
781
  Parameters_Obj params,
978
782
  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
- { }
991
- Definition(ParserState pstate,
783
+ Type t);
784
+ Definition(SourceSpan pstate,
992
785
  Signature sig,
993
- std::string n,
786
+ sass::string n,
994
787
  Parameters_Obj params,
995
788
  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
- { }
1008
- Definition(ParserState pstate,
789
+ bool overload_stub = false);
790
+ Definition(SourceSpan pstate,
1009
791
  Signature sig,
1010
- std::string n,
792
+ sass::string n,
1011
793
  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
- { }
794
+ Sass_Function_Entry c_func);
1026
795
  ATTACH_AST_OPERATIONS(Definition)
1027
- ATTACH_OPERATIONS()
796
+ ATTACH_CRTP_PERFORM_METHODS()
1028
797
  };
1029
798
 
1030
799
  //////////////////////////////////////
1031
800
  // Mixin calls (i.e., `@include ...`).
1032
801
  //////////////////////////////////////
1033
- class Mixin_Call : public Has_Block {
1034
- ADD_CONSTREF(std::string, name)
802
+ class Mixin_Call final : public ParentStatement {
803
+ ADD_CONSTREF(sass::string, name)
1035
804
  ADD_PROPERTY(Arguments_Obj, arguments)
805
+ ADD_PROPERTY(Parameters_Obj, block_parameters)
1036
806
  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
- { }
807
+ Mixin_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Parameters_Obj b_params = {}, Block_Obj b = {});
1045
808
  ATTACH_AST_OPERATIONS(Mixin_Call)
1046
- ATTACH_OPERATIONS()
809
+ ATTACH_CRTP_PERFORM_METHODS()
1047
810
  };
1048
811
 
1049
812
  ///////////////////////////////////////////////////
1050
813
  // The @content directive for mixin content blocks.
1051
814
  ///////////////////////////////////////////////////
1052
- class Content : public Statement {
1053
- ADD_PROPERTY(Media_Block_Ptr, media_block)
815
+ class Content final : public Statement {
816
+ ADD_PROPERTY(Arguments_Obj, arguments)
1054
817
  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); }
818
+ Content(SourceSpan pstate, Arguments_Obj args);
1063
819
  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()
820
+ ATTACH_CRTP_PERFORM_METHODS()
1280
821
  };
1281
822
 
1282
823
  ////////////////////////////////////////////////////////////////////////////
1283
824
  // Arithmetic negation (logical negation is just an ordinary function call).
1284
825
  ////////////////////////////////////////////////////////////////////////////
1285
- class Unary_Expression : public Expression {
826
+ class Unary_Expression final : public Expression {
1286
827
  public:
1287
828
  enum Type { PLUS, MINUS, NOT, SLASH };
1288
829
  private:
1289
830
  HASH_PROPERTY(Type, optype)
1290
- HASH_PROPERTY(Expression_Obj, operand)
1291
- size_t hash_;
831
+ HASH_PROPERTY(ExpressionObj, operand)
832
+ mutable size_t hash_;
1292
833
  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
- }
834
+ Unary_Expression(SourceSpan pstate, Type t, ExpressionObj o);
835
+ const sass::string type_name();
836
+ virtual bool operator==(const Expression& rhs) const override;
837
+ size_t hash() const override;
1334
838
  ATTACH_AST_OPERATIONS(Unary_Expression)
1335
- ATTACH_OPERATIONS()
839
+ ATTACH_CRTP_PERFORM_METHODS()
1336
840
  };
1337
841
 
1338
842
  ////////////////////////////////////////////////////////////
1339
843
  // Individual argument objects for mixin and function calls.
1340
844
  ////////////////////////////////////////////////////////////
1341
- class Argument : public Expression {
1342
- HASH_PROPERTY(Expression_Obj, value)
1343
- HASH_CONSTREF(std::string, name)
845
+ class Argument final : public Expression {
846
+ HASH_PROPERTY(ExpressionObj, value)
847
+ HASH_CONSTREF(sass::string, name)
1344
848
  ADD_PROPERTY(bool, is_rest_argument)
1345
849
  ADD_PROPERTY(bool, is_keyword_argument)
1346
- size_t hash_;
850
+ mutable size_t hash_;
1347
851
  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
-
852
+ Argument(SourceSpan pstate, ExpressionObj val, sass::string n = "", bool rest = false, bool keyword = false);
853
+ void set_delayed(bool delayed) override;
854
+ bool operator==(const Expression& rhs) const override;
855
+ size_t hash() const override;
1393
856
  ATTACH_AST_OPERATIONS(Argument)
1394
- ATTACH_OPERATIONS()
857
+ ATTACH_CRTP_PERFORM_METHODS()
1395
858
  };
1396
859
 
1397
860
  ////////////////////////////////////////////////////////////////////////
@@ -1399,799 +862,174 @@ namespace Sass {
1399
862
  // error checking (e.g., ensuring that all ordinal arguments precede all
1400
863
  // named arguments).
1401
864
  ////////////////////////////////////////////////////////////////////////
1402
- class Arguments : public Expression, public Vectorized<Argument_Obj> {
865
+ class Arguments final : public Expression, public Vectorized<Argument_Obj> {
1403
866
  ADD_PROPERTY(bool, has_named_arguments)
1404
867
  ADD_PROPERTY(bool, has_rest_argument)
1405
868
  ADD_PROPERTY(bool, has_keyword_argument)
1406
869
  protected:
1407
- void adjust_after_pushing(Argument_Obj a);
870
+ void adjust_after_pushing(Argument_Obj a) override;
1408
871
  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
-
872
+ Arguments(SourceSpan pstate);
873
+ void set_delayed(bool delayed) override;
1426
874
  Argument_Obj get_rest_argument();
1427
875
  Argument_Obj get_keyword_argument();
1428
-
1429
876
  ATTACH_AST_OPERATIONS(Arguments)
1430
- ATTACH_OPERATIONS()
877
+ ATTACH_CRTP_PERFORM_METHODS()
1431
878
  };
1432
879
 
1433
- ////////////////////////////////////////////////////
1434
- // Function reference.
1435
- ////////////////////////////////////////////////////
1436
- class Function : public Value {
1437
- public:
1438
- ADD_PROPERTY(Definition_Obj, definition)
1439
- ADD_PROPERTY(bool, is_css)
1440
- 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
880
 
1459
- virtual bool operator== (const Expression& rhs) const;
881
+ // A Media StyleRule before it has been evaluated
882
+ // Could be already final or an interpolation
883
+ class MediaRule final : public ParentStatement {
884
+ ADD_PROPERTY(List_Obj, schema)
885
+ public:
886
+ MediaRule(SourceSpan pstate, Block_Obj block = {});
1460
887
 
1461
- ATTACH_AST_OPERATIONS(Function)
1462
- ATTACH_OPERATIONS()
888
+ bool bubbles() override { return true; };
889
+ bool is_invisible() const override { return false; };
890
+ ATTACH_AST_OPERATIONS(MediaRule)
891
+ ATTACH_CRTP_PERFORM_METHODS()
1463
892
  };
1464
893
 
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_;
894
+ // A Media StyleRule after it has been evaluated
895
+ // Representing the static or resulting css
896
+ class CssMediaRule final : public ParentStatement,
897
+ public Vectorized<CssMediaQuery_Obj> {
1475
898
  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
- }
899
+ CssMediaRule(SourceSpan pstate, Block_Obj b);
900
+ bool bubbles() override { return true; };
901
+ bool isInvisible() const { return empty(); }
902
+ bool is_invisible() const override { return false; };
1499
903
 
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; }
904
+ public:
905
+ // Hash and equality implemtation from vector
906
+ size_t hash() const override { return Vectorized::hash(); }
907
+ // Check if two instances are considered equal
908
+ bool operator== (const CssMediaRule& rhs) const {
909
+ return Vectorized::operator== (rhs);
1516
910
  }
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_;
911
+ bool operator!=(const CssMediaRule& rhs) const {
912
+ // Invert from equality
913
+ return !(*this == rhs);
1526
914
  }
1527
- ATTACH_AST_OPERATIONS(Function_Call)
1528
- ATTACH_OPERATIONS()
915
+
916
+ ATTACH_AST_OPERATIONS(CssMediaRule)
917
+ ATTACH_CRTP_PERFORM_METHODS()
1529
918
  };
1530
919
 
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)
1537
- 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()
1548
- };
920
+ // Media Queries after they have been evaluated
921
+ // Representing the static or resulting css
922
+ class CssMediaQuery final : public AST_Node {
1549
923
 
1550
- ///////////////////////
1551
- // Variable references.
1552
- ///////////////////////
1553
- class Variable : public PreValue {
1554
- ADD_CONSTREF(std::string, name)
1555
- 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
- }
924
+ // The modifier, probably either "not" or "only".
925
+ // This may be `null` if no modifier is in use.
926
+ ADD_PROPERTY(sass::string, modifier);
1576
927
 
1577
- virtual size_t hash()
1578
- {
1579
- return std::hash<std::string>()(name());
1580
- }
928
+ // The media type, for example "screen" or "print".
929
+ // This may be `null`. If so, [features] will not be empty.
930
+ ADD_PROPERTY(sass::string, type);
1581
931
 
1582
- ATTACH_AST_OPERATIONS(Variable)
1583
- ATTACH_OPERATIONS()
1584
- };
932
+ // Feature queries, including parentheses.
933
+ ADD_PROPERTY(sass::vector<sass::string>, features);
1585
934
 
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_;
1593
935
  public:
1594
- Number(ParserState pstate, double val, std::string u = "", bool zero = true);
936
+ CssMediaQuery(SourceSpan pstate);
1595
937
 
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_;
938
+ // Check if two instances are considered equal
939
+ bool operator== (const CssMediaQuery& rhs) const;
940
+ bool operator!=(const CssMediaQuery& rhs) const {
941
+ // Invert from equality
942
+ return !(*this == rhs);
1620
943
  }
1621
944
 
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()
1627
- };
1628
-
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_;
945
+ // Returns true if this query is empty
946
+ // Meaning it has no type and features
947
+ bool empty() const {
948
+ return type_.empty()
949
+ && modifier_.empty()
950
+ && features_.empty();
1665
951
  }
1666
952
 
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_;
953
+ // Whether this media query matches all media types.
954
+ bool matchesAllTypes() const {
955
+ return type_.empty() || Util::equalsLiteral("all", type_);
1734
956
  }
1735
957
 
1736
- virtual bool operator== (const Expression& rhs) const;
958
+ // Merges this with [other] and adds a query that matches the intersection
959
+ // of both inputs to [result]. Returns false if the result is unrepresentable
960
+ CssMediaQuery_Obj merge(CssMediaQuery_Obj& other);
1737
961
 
1738
- ATTACH_AST_OPERATIONS(Boolean)
1739
- ATTACH_OPERATIONS()
962
+ ATTACH_AST_OPERATIONS(CssMediaQuery)
963
+ ATTACH_CRTP_PERFORM_METHODS()
1740
964
  };
1741
965
 
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> {
966
+ ////////////////////////////////////////////////////
967
+ // Media queries (replaced by MediaRule at al).
968
+ // ToDo: only used for interpolation case
969
+ ////////////////////////////////////////////////////
970
+ class Media_Query final : public Expression,
971
+ public Vectorized<Media_Query_ExpressionObj> {
1898
972
  ADD_PROPERTY(String_Obj, media_type)
1899
973
  ADD_PROPERTY(bool, is_negated)
1900
974
  ADD_PROPERTY(bool, is_restricted)
1901
975
  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
- { }
976
+ Media_Query(SourceSpan pstate, String_Obj t = {}, size_t s = 0, bool n = false, bool r = false);
1914
977
  ATTACH_AST_OPERATIONS(Media_Query)
1915
- ATTACH_OPERATIONS()
978
+ ATTACH_CRTP_PERFORM_METHODS()
1916
979
  };
1917
980
 
1918
981
  ////////////////////////////////////////////////////
1919
982
  // Media expressions (for use inside media queries).
983
+ // ToDo: only used for interpolation case
1920
984
  ////////////////////////////////////////////////////
1921
- class Media_Query_Expression : public Expression {
1922
- ADD_PROPERTY(Expression_Obj, feature)
1923
- ADD_PROPERTY(Expression_Obj, value)
985
+ class Media_Query_Expression final : public Expression {
986
+ ADD_PROPERTY(ExpressionObj, feature)
987
+ ADD_PROPERTY(ExpressionObj, value)
1924
988
  ADD_PROPERTY(bool, is_interpolated)
1925
989
  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
- { }
990
+ Media_Query_Expression(SourceSpan pstate, ExpressionObj f, ExpressionObj v, bool i = false);
1936
991
  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()
992
+ ATTACH_CRTP_PERFORM_METHODS()
2054
993
  };
2055
994
 
2056
995
  /////////////////////////////////////////////////
2057
996
  // At root expressions (for use inside @at-root).
2058
997
  /////////////////////////////////////////////////
2059
- class At_Root_Query : public Expression {
998
+ class At_Root_Query final : public Expression {
2060
999
  private:
2061
- ADD_PROPERTY(Expression_Obj, feature)
2062
- ADD_PROPERTY(Expression_Obj, value)
1000
+ ADD_PROPERTY(ExpressionObj, feature)
1001
+ ADD_PROPERTY(ExpressionObj, value)
2063
1002
  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);
1003
+ At_Root_Query(SourceSpan pstate, ExpressionObj f = {}, ExpressionObj v = {}, bool i = false);
1004
+ bool exclude(sass::string str);
2073
1005
  ATTACH_AST_OPERATIONS(At_Root_Query)
2074
- ATTACH_OPERATIONS()
1006
+ ATTACH_CRTP_PERFORM_METHODS()
2075
1007
  };
2076
1008
 
2077
1009
  ///////////
2078
1010
  // At-root.
2079
1011
  ///////////
2080
- class At_Root_Block : public Has_Block {
1012
+ class AtRootRule final : public ParentStatement {
2081
1013
  ADD_PROPERTY(At_Root_Query_Obj, expression)
2082
1014
  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
- { }
1015
+ AtRootRule(SourceSpan pstate, Block_Obj b = {}, At_Root_Query_Obj e = {});
1016
+ bool bubbles() override;
1017
+ bool exclude_node(Statement_Obj s);
1018
+ ATTACH_AST_OPERATIONS(AtRootRule)
1019
+ ATTACH_CRTP_PERFORM_METHODS()
2161
1020
  };
2162
1021
 
2163
1022
  /////////////////////////////////////////////////////////
2164
1023
  // Individual parameter objects for mixins and functions.
2165
1024
  /////////////////////////////////////////////////////////
2166
- class Parameter : public AST_Node {
2167
- ADD_CONSTREF(std::string, name)
2168
- ADD_PROPERTY(Expression_Obj, default_value)
1025
+ class Parameter final : public AST_Node {
1026
+ ADD_CONSTREF(sass::string, name)
1027
+ ADD_PROPERTY(ExpressionObj, default_value)
2169
1028
  ADD_PROPERTY(bool, is_rest_parameter)
2170
1029
  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
- }
1030
+ Parameter(SourceSpan pstate, sass::string n, ExpressionObj def = {}, bool rest = false);
2193
1031
  ATTACH_AST_OPERATIONS(Parameter)
2194
- ATTACH_OPERATIONS()
1032
+ ATTACH_CRTP_PERFORM_METHODS()
2195
1033
  };
2196
1034
 
2197
1035
  /////////////////////////////////////////////////////////////////////////
@@ -2199,850 +1037,27 @@ namespace Sass {
2199
1037
  // error checking (e.g., ensuring that all optional parameters follow all
2200
1038
  // required parameters).
2201
1039
  /////////////////////////////////////////////////////////////////////////
2202
- class Parameters : public AST_Node, public Vectorized<Parameter_Obj> {
1040
+ class Parameters final : public AST_Node, public Vectorized<Parameter_Obj> {
2203
1041
  ADD_PROPERTY(bool, has_optional_parameters)
2204
1042
  ADD_PROPERTY(bool, has_rest_parameter)
2205
1043
  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
- }
1044
+ void adjust_after_pushing(Parameter_Obj p) override;
2229
1045
  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
- { }
1046
+ Parameters(SourceSpan pstate);
2242
1047
  ATTACH_AST_OPERATIONS(Parameters)
2243
- ATTACH_OPERATIONS()
1048
+ ATTACH_CRTP_PERFORM_METHODS()
2244
1049
  };
2245
1050
 
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
1051
  }
3042
1052
 
1053
+ #include "ast_values.hpp"
1054
+ #include "ast_supports.hpp"
1055
+ #include "ast_selectors.hpp"
1056
+
3043
1057
  #ifdef __clang__
3044
1058
 
3045
- #pragma clang diagnostic pop
1059
+ // #pragma clang diagnostic pop
1060
+ // #pragma clang diagnostic push
3046
1061
 
3047
1062
  #endif
3048
1063