sassc 2.0.0 → 2.4.0

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