1#ifndef SASS_OPERATION_H
2#define SASS_OPERATION_H
3
4// sass.hpp must go before all system headers to get the
5// __EXTENSIONS__ fix on Solaris.
6#include "sass.hpp"
7
8// base classes to implement curiously recurring template pattern (CRTP)
9// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
10
11#include <typeinfo>
12#include <stdexcept>
13
14#include "ast_fwd_decl.hpp"
15#include "ast_def_macros.hpp"
16
17namespace Sass {
18
19 #define ATTACH_ABSTRACT_CRTP_PERFORM_METHODS()\
20 virtual void perform(Operation<void>* op) = 0; \
21 virtual Value* perform(Operation<Value*>* op) = 0; \
22 virtual sass::string perform(Operation<sass::string>* op) = 0; \
23 virtual AST_Node* perform(Operation<AST_Node*>* op) = 0; \
24 virtual Selector* perform(Operation<Selector*>* op) = 0; \
25 virtual Statement* perform(Operation<Statement*>* op) = 0; \
26 virtual Expression* perform(Operation<Expression*>* op) = 0; \
27 virtual union Sass_Value* perform(Operation<union Sass_Value*>* op) = 0; \
28 virtual SupportsCondition* perform(Operation<SupportsCondition*>* op) = 0; \
29
30 // you must add operators to every class
31 // ensures `this` of actual instance type
32 // we therefore call the specific operator
33 // they are virtual so most specific is used
34 #define ATTACH_CRTP_PERFORM_METHODS()\
35 virtual void perform(Operation<void>* op) override { return (*op)(this); } \
36 virtual Value* perform(Operation<Value*>* op) override { return (*op)(this); } \
37 virtual sass::string perform(Operation<sass::string>* op) override { return (*op)(this); } \
38 virtual AST_Node* perform(Operation<AST_Node*>* op) override { return (*op)(this); } \
39 virtual Selector* perform(Operation<Selector*>* op) override { return (*op)(this); } \
40 virtual Statement* perform(Operation<Statement*>* op) override { return (*op)(this); } \
41 virtual Expression* perform(Operation<Expression*>* op) override { return (*op)(this); } \
42 virtual union Sass_Value* perform(Operation<union Sass_Value*>* op) override { return (*op)(this); } \
43 virtual SupportsCondition* perform(Operation<SupportsCondition*>* op) override { return (*op)(this); } \
44
45 template<typename T>
46 class Operation {
47 public:
48 virtual T operator()(AST_Node* x) = 0;
49 // statements
50 virtual T operator()(Block* x) = 0;
51 virtual T operator()(StyleRule* x) = 0;
52 virtual T operator()(Bubble* x) = 0;
53 virtual T operator()(Trace* x) = 0;
54 virtual T operator()(SupportsRule* x) = 0;
55 virtual T operator()(MediaRule* x) = 0;
56 virtual T operator()(CssMediaRule* x) = 0;
57 virtual T operator()(CssMediaQuery* x) = 0;
58 virtual T operator()(AtRootRule* x) = 0;
59 virtual T operator()(AtRule* x) = 0;
60 virtual T operator()(Keyframe_Rule* x) = 0;
61 virtual T operator()(Declaration* x) = 0;
62 virtual T operator()(Assignment* x) = 0;
63 virtual T operator()(Import* x) = 0;
64 virtual T operator()(Import_Stub* x) = 0;
65 virtual T operator()(WarningRule* x) = 0;
66 virtual T operator()(ErrorRule* x) = 0;
67 virtual T operator()(DebugRule* x) = 0;
68 virtual T operator()(Comment* x) = 0;
69 virtual T operator()(If* x) = 0;
70 virtual T operator()(ForRule* x) = 0;
71 virtual T operator()(EachRule* x) = 0;
72 virtual T operator()(WhileRule* x) = 0;
73 virtual T operator()(Return* x) = 0;
74 virtual T operator()(Content* x) = 0;
75 virtual T operator()(ExtendRule* x) = 0;
76 virtual T operator()(Definition* x) = 0;
77 virtual T operator()(Mixin_Call* x) = 0;
78 // expressions
79 virtual T operator()(Null* x) = 0;
80 virtual T operator()(List* x) = 0;
81 virtual T operator()(Map* x) = 0;
82 virtual T operator()(Function* x) = 0;
83 virtual T operator()(Binary_Expression* x) = 0;
84 virtual T operator()(Unary_Expression* x) = 0;
85 virtual T operator()(Function_Call* x) = 0;
86 virtual T operator()(Custom_Warning* x) = 0;
87 virtual T operator()(Custom_Error* x) = 0;
88 virtual T operator()(Variable* x) = 0;
89 virtual T operator()(Number* x) = 0;
90 virtual T operator()(Color* x) = 0;
91 virtual T operator()(Color_RGBA* x) = 0;
92 virtual T operator()(Color_HSLA* x) = 0;
93 virtual T operator()(Boolean* x) = 0;
94 virtual T operator()(String_Schema* x) = 0;
95 virtual T operator()(String_Quoted* x) = 0;
96 virtual T operator()(String_Constant* x) = 0;
97 virtual T operator()(SupportsCondition* x) = 0;
98 virtual T operator()(SupportsOperation* x) = 0;
99 virtual T operator()(SupportsNegation* x) = 0;
100 virtual T operator()(SupportsDeclaration* x) = 0;
101 virtual T operator()(Supports_Interpolation* x) = 0;
102 virtual T operator()(Media_Query* x) = 0;
103 virtual T operator()(Media_Query_Expression* x) = 0;
104 virtual T operator()(At_Root_Query* x) = 0;
105 virtual T operator()(Parent_Reference* x) = 0;
106 // parameters and arguments
107 virtual T operator()(Parameter* x) = 0;
108 virtual T operator()(Parameters* x) = 0;
109 virtual T operator()(Argument* x) = 0;
110 virtual T operator()(Arguments* x) = 0;
111 // selectors
112 virtual T operator()(Selector_Schema* x) = 0;
113 virtual T operator()(PlaceholderSelector* x) = 0;
114 virtual T operator()(TypeSelector* x) = 0;
115 virtual T operator()(ClassSelector* x) = 0;
116 virtual T operator()(IDSelector* x) = 0;
117 virtual T operator()(AttributeSelector* x) = 0;
118 virtual T operator()(PseudoSelector* x) = 0;
119 virtual T operator()(SelectorComponent* x) = 0;
120 virtual T operator()(SelectorCombinator* x) = 0;
121 virtual T operator()(CompoundSelector* x) = 0;
122 virtual T operator()(ComplexSelector* x) = 0;
123 virtual T operator()(SelectorList* x) = 0;
124
125 };
126
127 // example: Operation_CRTP<Expression*, Eval>
128 // T is the base return type of all visitors
129 // D is the class derived visitor class
130 // normally you want to implement all operators
131 template <typename T, typename D>
132 class Operation_CRTP : public Operation<T> {
133 public:
134 T operator()(AST_Node* x) { return static_cast<D*>(this)->fallback(x); }
135 // statements
136 T operator()(Block* x) { return static_cast<D*>(this)->fallback(x); }
137 T operator()(StyleRule* x) { return static_cast<D*>(this)->fallback(x); }
138 T operator()(Bubble* x) { return static_cast<D*>(this)->fallback(x); }
139 T operator()(Trace* x) { return static_cast<D*>(this)->fallback(x); }
140 T operator()(SupportsRule* x) { return static_cast<D*>(this)->fallback(x); }
141 T operator()(MediaRule* x) { return static_cast<D*>(this)->fallback(x); }
142 T operator()(CssMediaRule* x) { return static_cast<D*>(this)->fallback(x); }
143 T operator()(CssMediaQuery* x) { return static_cast<D*>(this)->fallback(x); }
144 T operator()(AtRootRule* x) { return static_cast<D*>(this)->fallback(x); }
145 T operator()(AtRule* x) { return static_cast<D*>(this)->fallback(x); }
146 T operator()(Keyframe_Rule* x) { return static_cast<D*>(this)->fallback(x); }
147 T operator()(Declaration* x) { return static_cast<D*>(this)->fallback(x); }
148 T operator()(Assignment* x) { return static_cast<D*>(this)->fallback(x); }
149 T operator()(Import* x) { return static_cast<D*>(this)->fallback(x); }
150 T operator()(Import_Stub* x) { return static_cast<D*>(this)->fallback(x); }
151 T operator()(WarningRule* x) { return static_cast<D*>(this)->fallback(x); }
152 T operator()(ErrorRule* x) { return static_cast<D*>(this)->fallback(x); }
153 T operator()(DebugRule* x) { return static_cast<D*>(this)->fallback(x); }
154 T operator()(Comment* x) { return static_cast<D*>(this)->fallback(x); }
155 T operator()(If* x) { return static_cast<D*>(this)->fallback(x); }
156 T operator()(ForRule* x) { return static_cast<D*>(this)->fallback(x); }
157 T operator()(EachRule* x) { return static_cast<D*>(this)->fallback(x); }
158 T operator()(WhileRule* x) { return static_cast<D*>(this)->fallback(x); }
159 T operator()(Return* x) { return static_cast<D*>(this)->fallback(x); }
160 T operator()(Content* x) { return static_cast<D*>(this)->fallback(x); }
161 T operator()(ExtendRule* x) { return static_cast<D*>(this)->fallback(x); }
162 T operator()(Definition* x) { return static_cast<D*>(this)->fallback(x); }
163 T operator()(Mixin_Call* x) { return static_cast<D*>(this)->fallback(x); }
164 // expressions
165 T operator()(Null* x) { return static_cast<D*>(this)->fallback(x); }
166 T operator()(List* x) { return static_cast<D*>(this)->fallback(x); }
167 T operator()(Map* x) { return static_cast<D*>(this)->fallback(x); }
168 T operator()(Function* x) { return static_cast<D*>(this)->fallback(x); }
169 T operator()(Binary_Expression* x) { return static_cast<D*>(this)->fallback(x); }
170 T operator()(Unary_Expression* x) { return static_cast<D*>(this)->fallback(x); }
171 T operator()(Function_Call* x) { return static_cast<D*>(this)->fallback(x); }
172 T operator()(Custom_Warning* x) { return static_cast<D*>(this)->fallback(x); }
173 T operator()(Custom_Error* x) { return static_cast<D*>(this)->fallback(x); }
174 T operator()(Variable* x) { return static_cast<D*>(this)->fallback(x); }
175 T operator()(Number* x) { return static_cast<D*>(this)->fallback(x); }
176 T operator()(Color* x) { return static_cast<D*>(this)->fallback(x); }
177 T operator()(Color_RGBA* x) { return static_cast<D*>(this)->fallback(x); }
178 T operator()(Color_HSLA* x) { return static_cast<D*>(this)->fallback(x); }
179 T operator()(Boolean* x) { return static_cast<D*>(this)->fallback(x); }
180 T operator()(String_Schema* x) { return static_cast<D*>(this)->fallback(x); }
181 T operator()(String_Constant* x) { return static_cast<D*>(this)->fallback(x); }
182 T operator()(String_Quoted* x) { return static_cast<D*>(this)->fallback(x); }
183 T operator()(SupportsCondition* x) { return static_cast<D*>(this)->fallback(x); }
184 T operator()(SupportsOperation* x) { return static_cast<D*>(this)->fallback(x); }
185 T operator()(SupportsNegation* x) { return static_cast<D*>(this)->fallback(x); }
186 T operator()(SupportsDeclaration* x) { return static_cast<D*>(this)->fallback(x); }
187 T operator()(Supports_Interpolation* x) { return static_cast<D*>(this)->fallback(x); }
188 T operator()(Media_Query* x) { return static_cast<D*>(this)->fallback(x); }
189 T operator()(Media_Query_Expression* x) { return static_cast<D*>(this)->fallback(x); }
190 T operator()(At_Root_Query* x) { return static_cast<D*>(this)->fallback(x); }
191 T operator()(Parent_Reference* x) { return static_cast<D*>(this)->fallback(x); }
192 // parameters and arguments
193 T operator()(Parameter* x) { return static_cast<D*>(this)->fallback(x); }
194 T operator()(Parameters* x) { return static_cast<D*>(this)->fallback(x); }
195 T operator()(Argument* x) { return static_cast<D*>(this)->fallback(x); }
196 T operator()(Arguments* x) { return static_cast<D*>(this)->fallback(x); }
197 // selectors
198 T operator()(Selector_Schema* x) { return static_cast<D*>(this)->fallback(x); }
199 T operator()(PlaceholderSelector* x) { return static_cast<D*>(this)->fallback(x); }
200 T operator()(TypeSelector* x) { return static_cast<D*>(this)->fallback(x); }
201 T operator()(ClassSelector* x) { return static_cast<D*>(this)->fallback(x); }
202 T operator()(IDSelector* x) { return static_cast<D*>(this)->fallback(x); }
203 T operator()(AttributeSelector* x) { return static_cast<D*>(this)->fallback(x); }
204 T operator()(PseudoSelector* x) { return static_cast<D*>(this)->fallback(x); }
205 T operator()(SelectorComponent* x) { return static_cast<D*>(this)->fallback(x); }
206 T operator()(SelectorCombinator* x) { return static_cast<D*>(this)->fallback(x); }
207 T operator()(CompoundSelector* x) { return static_cast<D*>(this)->fallback(x); }
208 T operator()(ComplexSelector* x) { return static_cast<D*>(this)->fallback(x); }
209 T operator()(SelectorList* x) { return static_cast<D*>(this)->fallback(x); }
210
211 // fallback with specific type U
212 // will be called if not overloaded
213 template <typename U> inline T fallback(U x)
214 {
215 throw std::runtime_error(
216 std::string(typeid(*this).name()) + ": CRTP not implemented for " + typeid(x).name());
217 }
218
219 };
220
221}
222
223#endif
224

source code of gtk/subprojects/libsass/src/operation.hpp