sassc4 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.gitmodules +3 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +97 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +51 -0
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/contrib/plugin.cpp +60 -0
- data/ext/libsass/include/sass/base.h +97 -0
- data/ext/libsass/include/sass/context.h +174 -0
- data/ext/libsass/include/sass/functions.h +139 -0
- data/ext/libsass/include/sass/values.h +145 -0
- data/ext/libsass/include/sass/version.h +12 -0
- data/ext/libsass/include/sass.h +15 -0
- data/ext/libsass/include/sass2scss.h +120 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +953 -0
- data/ext/libsass/src/ast.hpp +1064 -0
- data/ext/libsass/src/ast2c.cpp +80 -0
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +140 -0
- data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
- data/ext/libsass/src/ast_helpers.hpp +316 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +275 -0
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +1070 -0
- data/ext/libsass/src/ast_selectors.hpp +523 -0
- data/ext/libsass/src/ast_supports.cpp +114 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +1154 -0
- data/ext/libsass/src/ast_values.hpp +498 -0
- data/ext/libsass/src/b64/cencode.h +32 -0
- data/ext/libsass/src/b64/encode.h +79 -0
- data/ext/libsass/src/backtrace.cpp +50 -0
- data/ext/libsass/src/backtrace.hpp +29 -0
- data/ext/libsass/src/base64vlq.cpp +47 -0
- data/ext/libsass/src/base64vlq.hpp +30 -0
- data/ext/libsass/src/bind.cpp +312 -0
- data/ext/libsass/src/bind.hpp +15 -0
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/c99func.c +54 -0
- data/ext/libsass/src/cencode.c +106 -0
- data/ext/libsass/src/check_nesting.cpp +393 -0
- data/ext/libsass/src/check_nesting.hpp +70 -0
- data/ext/libsass/src/color_maps.cpp +652 -0
- data/ext/libsass/src/color_maps.hpp +323 -0
- data/ext/libsass/src/color_spaces.cpp +241 -0
- data/ext/libsass/src/color_spaces.hpp +227 -0
- data/ext/libsass/src/constants.cpp +199 -0
- data/ext/libsass/src/constants.hpp +200 -0
- data/ext/libsass/src/context.cpp +870 -0
- data/ext/libsass/src/context.hpp +140 -0
- data/ext/libsass/src/cssize.cpp +521 -0
- data/ext/libsass/src/cssize.hpp +71 -0
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debug.hpp +43 -0
- data/ext/libsass/src/debugger.hpp +964 -0
- data/ext/libsass/src/emitter.cpp +297 -0
- data/ext/libsass/src/emitter.hpp +101 -0
- data/ext/libsass/src/environment.cpp +260 -0
- data/ext/libsass/src/environment.hpp +124 -0
- data/ext/libsass/src/error_handling.cpp +239 -0
- data/ext/libsass/src/error_handling.hpp +248 -0
- data/ext/libsass/src/eval.cpp +1543 -0
- data/ext/libsass/src/eval.hpp +110 -0
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +875 -0
- data/ext/libsass/src/expand.hpp +98 -0
- data/ext/libsass/src/extender.cpp +1226 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +531 -0
- data/ext/libsass/src/file.hpp +124 -0
- data/ext/libsass/src/fn_colors.cpp +836 -0
- data/ext/libsass/src/fn_colors.hpp +99 -0
- data/ext/libsass/src/fn_lists.cpp +285 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +248 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +246 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +205 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +268 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +159 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +1126 -0
- data/ext/libsass/src/inspect.hpp +101 -0
- data/ext/libsass/src/json.cpp +1436 -0
- data/ext/libsass/src/json.hpp +117 -0
- data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
- data/ext/libsass/src/lexer.cpp +122 -0
- data/ext/libsass/src/lexer.hpp +304 -0
- data/ext/libsass/src/listize.cpp +70 -0
- data/ext/libsass/src/listize.hpp +37 -0
- data/ext/libsass/src/mapping.hpp +19 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
- data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +223 -0
- data/ext/libsass/src/operators.cpp +267 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +320 -0
- data/ext/libsass/src/output.hpp +47 -0
- data/ext/libsass/src/parser.cpp +3059 -0
- data/ext/libsass/src/parser.hpp +395 -0
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +188 -0
- data/ext/libsass/src/plugins.hpp +57 -0
- data/ext/libsass/src/position.cpp +163 -0
- data/ext/libsass/src/position.hpp +147 -0
- data/ext/libsass/src/prelexer.cpp +1780 -0
- data/ext/libsass/src/prelexer.hpp +484 -0
- data/ext/libsass/src/remove_placeholders.cpp +86 -0
- data/ext/libsass/src/remove_placeholders.hpp +37 -0
- data/ext/libsass/src/sass.cpp +156 -0
- data/ext/libsass/src/sass.hpp +147 -0
- data/ext/libsass/src/sass2scss.cpp +895 -0
- data/ext/libsass/src/sass_context.cpp +742 -0
- data/ext/libsass/src/sass_context.hpp +129 -0
- data/ext/libsass/src/sass_functions.cpp +210 -0
- data/ext/libsass/src/sass_functions.hpp +50 -0
- data/ext/libsass/src/sass_values.cpp +362 -0
- data/ext/libsass/src/sass_values.hpp +82 -0
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +202 -0
- data/ext/libsass/src/source_map.hpp +65 -0
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +114 -0
- data/ext/libsass/src/to_value.hpp +46 -0
- data/ext/libsass/src/units.cpp +507 -0
- data/ext/libsass/src/units.hpp +110 -0
- data/ext/libsass/src/utf8/checked.h +336 -0
- data/ext/libsass/src/utf8/core.h +332 -0
- data/ext/libsass/src/utf8/unchecked.h +235 -0
- data/ext/libsass/src/utf8.h +34 -0
- data/ext/libsass/src/utf8_string.cpp +104 -0
- data/ext/libsass/src/utf8_string.hpp +38 -0
- data/ext/libsass/src/util.cpp +723 -0
- data/ext/libsass/src/util.hpp +105 -0
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +140 -0
- data/ext/libsass/src/values.hpp +12 -0
- data/lib/sassc/dependency.rb +17 -0
- data/lib/sassc/engine.rb +141 -0
- data/lib/sassc/error.rb +37 -0
- data/lib/sassc/functions_handler.rb +73 -0
- data/lib/sassc/import_handler.rb +50 -0
- data/lib/sassc/importer.rb +31 -0
- data/lib/sassc/native/native_context_api.rb +147 -0
- data/lib/sassc/native/native_functions_api.rb +159 -0
- data/lib/sassc/native/sass2scss_api.rb +10 -0
- data/lib/sassc/native/sass_input_style.rb +13 -0
- data/lib/sassc/native/sass_output_style.rb +12 -0
- data/lib/sassc/native/sass_value.rb +97 -0
- data/lib/sassc/native/string_list.rb +10 -0
- data/lib/sassc/native.rb +64 -0
- data/lib/sassc/sass_2_scss.rb +9 -0
- data/lib/sassc/script/functions.rb +8 -0
- data/lib/sassc/script/value/bool.rb +32 -0
- data/lib/sassc/script/value/color.rb +95 -0
- data/lib/sassc/script/value/list.rb +136 -0
- data/lib/sassc/script/value/map.rb +69 -0
- data/lib/sassc/script/value/number.rb +389 -0
- data/lib/sassc/script/value/string.rb +96 -0
- data/lib/sassc/script/value.rb +137 -0
- data/lib/sassc/script/value_conversion/base.rb +13 -0
- data/lib/sassc/script/value_conversion/bool.rb +13 -0
- data/lib/sassc/script/value_conversion/color.rb +18 -0
- data/lib/sassc/script/value_conversion/list.rb +25 -0
- data/lib/sassc/script/value_conversion/map.rb +21 -0
- data/lib/sassc/script/value_conversion/number.rb +13 -0
- data/lib/sassc/script/value_conversion/string.rb +17 -0
- data/lib/sassc/script/value_conversion.rb +69 -0
- data/lib/sassc/script.rb +17 -0
- data/lib/sassc/util/normalized_map.rb +117 -0
- data/lib/sassc/util.rb +231 -0
- data/lib/sassc/version.rb +5 -0
- data/lib/sassc.rb +57 -0
- data/sassc.gemspec +69 -0
- data/test/css_color_level4_test.rb +168 -0
- data/test/custom_importer_test.rb +127 -0
- data/test/engine_test.rb +314 -0
- data/test/error_test.rb +29 -0
- data/test/fixtures/paths.scss +10 -0
- data/test/functions_test.rb +340 -0
- data/test/native_test.rb +213 -0
- data/test/output_style_test.rb +107 -0
- data/test/sass_2_scss_test.rb +14 -0
- data/test/test_helper.rb +45 -0
- metadata +396 -0
|
@@ -0,0 +1,1064 @@
|
|
|
1
|
+
#ifndef SASS_AST_H
|
|
2
|
+
#define SASS_AST_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
|
+
#include <typeinfo>
|
|
9
|
+
#include <unordered_map>
|
|
10
|
+
|
|
11
|
+
#include "sass/base.h"
|
|
12
|
+
#include "ast_helpers.hpp"
|
|
13
|
+
#include "ast_fwd_decl.hpp"
|
|
14
|
+
#include "ast_def_macros.hpp"
|
|
15
|
+
|
|
16
|
+
#include "file.hpp"
|
|
17
|
+
#include "position.hpp"
|
|
18
|
+
#include "operation.hpp"
|
|
19
|
+
#include "environment.hpp"
|
|
20
|
+
#include "fn_utils.hpp"
|
|
21
|
+
|
|
22
|
+
namespace Sass {
|
|
23
|
+
|
|
24
|
+
// ToDo: where does this fit best?
|
|
25
|
+
// We don't share this with C-API?
|
|
26
|
+
class Operand {
|
|
27
|
+
public:
|
|
28
|
+
Operand(Sass_OP operand, bool ws_before = false, bool ws_after = false)
|
|
29
|
+
: operand(operand), ws_before(ws_before), ws_after(ws_after)
|
|
30
|
+
{ }
|
|
31
|
+
public:
|
|
32
|
+
enum Sass_OP operand;
|
|
33
|
+
bool ws_before;
|
|
34
|
+
bool ws_after;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
//////////////////////////////////////////////////////////
|
|
38
|
+
// `hash_combine` comes from boost (functional/hash):
|
|
39
|
+
// http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html
|
|
40
|
+
// Boost Software License - Version 1.0
|
|
41
|
+
// http://www.boost.org/users/license.html
|
|
42
|
+
template <typename T>
|
|
43
|
+
void hash_combine (std::size_t& seed, const T& val)
|
|
44
|
+
{
|
|
45
|
+
seed ^= std::hash<T>()(val) + 0x9e3779b9
|
|
46
|
+
+ (seed<<6) + (seed>>2);
|
|
47
|
+
}
|
|
48
|
+
//////////////////////////////////////////////////////////
|
|
49
|
+
|
|
50
|
+
const char* sass_op_to_name(enum Sass_OP op);
|
|
51
|
+
|
|
52
|
+
const char* sass_op_separator(enum Sass_OP op);
|
|
53
|
+
|
|
54
|
+
//////////////////////////////////////////////////////////
|
|
55
|
+
// Abstract base class for all abstract syntax tree nodes.
|
|
56
|
+
//////////////////////////////////////////////////////////
|
|
57
|
+
class AST_Node : public SharedObj {
|
|
58
|
+
ADD_PROPERTY(SourceSpan, pstate)
|
|
59
|
+
public:
|
|
60
|
+
AST_Node(SourceSpan pstate)
|
|
61
|
+
: pstate_(pstate)
|
|
62
|
+
{ }
|
|
63
|
+
AST_Node(const AST_Node* ptr)
|
|
64
|
+
: pstate_(ptr->pstate_)
|
|
65
|
+
{ }
|
|
66
|
+
|
|
67
|
+
// allow implicit conversion to string
|
|
68
|
+
// needed for by SharedPtr implementation
|
|
69
|
+
operator sass::string() {
|
|
70
|
+
return to_string();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// AST_Node(AST_Node& ptr) = delete;
|
|
74
|
+
|
|
75
|
+
virtual ~AST_Node() = 0;
|
|
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;
|
|
82
|
+
virtual void cloneChildren() {};
|
|
83
|
+
// generic find function (not fully implemented yet)
|
|
84
|
+
// ToDo: add specific implementations to all children
|
|
85
|
+
virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };
|
|
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()
|
|
103
|
+
};
|
|
104
|
+
inline AST_Node::~AST_Node() { }
|
|
105
|
+
|
|
106
|
+
//////////////////////////////////////////////////////////////////////
|
|
107
|
+
// define cast template now (need complete type)
|
|
108
|
+
//////////////////////////////////////////////////////////////////////
|
|
109
|
+
|
|
110
|
+
template<class T>
|
|
111
|
+
T* Cast(AST_Node* ptr) {
|
|
112
|
+
return ptr && typeid(T) == typeid(*ptr) ?
|
|
113
|
+
static_cast<T*>(ptr) : NULL;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
template<class T>
|
|
117
|
+
const T* Cast(const AST_Node* ptr) {
|
|
118
|
+
return ptr && typeid(T) == typeid(*ptr) ?
|
|
119
|
+
static_cast<const T*>(ptr) : NULL;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
//////////////////////////////////////////////////////////////////////
|
|
123
|
+
// Abstract base class for expressions. This side of the AST hierarchy
|
|
124
|
+
// represents elements in value contexts, which exist primarily to be
|
|
125
|
+
// evaluated and returned.
|
|
126
|
+
//////////////////////////////////////////////////////////////////////
|
|
127
|
+
class Expression : public AST_Node {
|
|
128
|
+
public:
|
|
129
|
+
enum Type {
|
|
130
|
+
NONE,
|
|
131
|
+
BOOLEAN,
|
|
132
|
+
NUMBER,
|
|
133
|
+
COLOR,
|
|
134
|
+
STRING,
|
|
135
|
+
LIST,
|
|
136
|
+
MAP,
|
|
137
|
+
SELECTOR,
|
|
138
|
+
NULL_VAL,
|
|
139
|
+
FUNCTION_VAL,
|
|
140
|
+
C_WARNING,
|
|
141
|
+
C_ERROR,
|
|
142
|
+
FUNCTION,
|
|
143
|
+
VARIABLE,
|
|
144
|
+
PARENT,
|
|
145
|
+
NUM_TYPES
|
|
146
|
+
};
|
|
147
|
+
private:
|
|
148
|
+
// expressions in some contexts shouldn't be evaluated
|
|
149
|
+
ADD_PROPERTY(bool, is_delayed)
|
|
150
|
+
ADD_PROPERTY(bool, is_expanded)
|
|
151
|
+
ADD_PROPERTY(bool, is_interpolant)
|
|
152
|
+
ADD_PROPERTY(Type, concrete_type)
|
|
153
|
+
public:
|
|
154
|
+
Expression(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);
|
|
155
|
+
virtual operator bool() { return true; }
|
|
156
|
+
virtual ~Expression() { }
|
|
157
|
+
virtual bool is_invisible() const { return false; }
|
|
158
|
+
|
|
159
|
+
virtual sass::string type() const { return ""; }
|
|
160
|
+
static sass::string type_name() { return ""; }
|
|
161
|
+
|
|
162
|
+
virtual bool is_false() { return false; }
|
|
163
|
+
// virtual bool is_true() { return !is_false(); }
|
|
164
|
+
virtual bool operator< (const Expression& rhs) const { return false; }
|
|
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); }
|
|
168
|
+
virtual bool eq(const Expression& rhs) const { return *this == rhs; };
|
|
169
|
+
virtual void set_delayed(bool delayed) { is_delayed(delayed); }
|
|
170
|
+
virtual bool has_interpolant() const { return is_interpolant(); }
|
|
171
|
+
virtual bool is_left_interpolant() const { return is_interpolant(); }
|
|
172
|
+
virtual bool is_right_interpolant() const { return is_interpolant(); }
|
|
173
|
+
ATTACH_VIRTUAL_AST_OPERATIONS(Expression);
|
|
174
|
+
size_t hash() const override { return 0; }
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/////////////////////////////////////////////////////////////////////////////////////
|
|
180
|
+
// Hash method specializations for std::unordered_map to work with Sass::Expression
|
|
181
|
+
/////////////////////////////////////////////////////////////////////////////////////
|
|
182
|
+
|
|
183
|
+
namespace std {
|
|
184
|
+
template<>
|
|
185
|
+
struct hash<Sass::ExpressionObj>
|
|
186
|
+
{
|
|
187
|
+
size_t operator()(Sass::ExpressionObj s) const
|
|
188
|
+
{
|
|
189
|
+
return s->hash();
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
template<>
|
|
193
|
+
struct equal_to<Sass::ExpressionObj>
|
|
194
|
+
{
|
|
195
|
+
bool operator()( Sass::ExpressionObj lhs, Sass::ExpressionObj rhs) const
|
|
196
|
+
{
|
|
197
|
+
return lhs->hash() == rhs->hash();
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
namespace Sass {
|
|
203
|
+
|
|
204
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
205
|
+
// Mixin class for AST nodes that should behave like vectors. Uses the
|
|
206
|
+
// "Template Method" design pattern to allow subclasses to adjust their flags
|
|
207
|
+
// when certain objects are pushed.
|
|
208
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
209
|
+
template <typename T>
|
|
210
|
+
class Vectorized {
|
|
211
|
+
sass::vector<T> elements_;
|
|
212
|
+
protected:
|
|
213
|
+
mutable size_t hash_;
|
|
214
|
+
void reset_hash() { hash_ = 0; }
|
|
215
|
+
virtual void adjust_after_pushing(T element) { }
|
|
216
|
+
public:
|
|
217
|
+
Vectorized(size_t s = 0) : hash_(0)
|
|
218
|
+
{ elements_.reserve(s); }
|
|
219
|
+
Vectorized(sass::vector<T> vec) :
|
|
220
|
+
elements_(std::move(vec)),
|
|
221
|
+
hash_(0)
|
|
222
|
+
{}
|
|
223
|
+
virtual ~Vectorized() = 0;
|
|
224
|
+
size_t length() const { return elements_.size(); }
|
|
225
|
+
bool empty() const { return elements_.empty(); }
|
|
226
|
+
void clear() { return elements_.clear(); }
|
|
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
|
+
|
|
243
|
+
T& operator[](size_t i) { return elements_[i]; }
|
|
244
|
+
virtual const T& at(size_t i) const { return elements_.at(i); }
|
|
245
|
+
virtual T& at(size_t i) { return elements_.at(i); }
|
|
246
|
+
const T& get(size_t i) const { return elements_[i]; }
|
|
247
|
+
const T& operator[](size_t i) const { return elements_[i]; }
|
|
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)
|
|
273
|
+
{
|
|
274
|
+
if (v != nullptr) {
|
|
275
|
+
return concat(*v);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Insert one item on the front
|
|
280
|
+
void unshift(T element)
|
|
281
|
+
{
|
|
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;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Insert one item on the back
|
|
296
|
+
// ToDo: rename this to push
|
|
297
|
+
void append(T element)
|
|
298
|
+
{
|
|
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;
|
|
318
|
+
}
|
|
319
|
+
|
|
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
|
|
327
|
+
{
|
|
328
|
+
if (hash_ == 0) {
|
|
329
|
+
for (const T& el : elements_) {
|
|
330
|
+
hash_combine(hash_, el->hash());
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return hash_;
|
|
334
|
+
}
|
|
335
|
+
|
|
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); }
|
|
348
|
+
|
|
349
|
+
};
|
|
350
|
+
template <typename T>
|
|
351
|
+
inline Vectorized<T>::~Vectorized() { }
|
|
352
|
+
|
|
353
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
354
|
+
// Mixin class for AST nodes that should behave like a hash table. Uses an
|
|
355
|
+
// extra <sass::vector> internally to maintain insertion order for interation.
|
|
356
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
357
|
+
template <typename K, typename T, typename U>
|
|
358
|
+
class Hashed {
|
|
359
|
+
private:
|
|
360
|
+
std::unordered_map<
|
|
361
|
+
K, T, ObjHash, ObjHashEquality
|
|
362
|
+
> elements_;
|
|
363
|
+
|
|
364
|
+
sass::vector<K> _keys;
|
|
365
|
+
sass::vector<T> _values;
|
|
366
|
+
protected:
|
|
367
|
+
mutable size_t hash_;
|
|
368
|
+
K duplicate_key_;
|
|
369
|
+
void reset_hash() { hash_ = 0; }
|
|
370
|
+
void reset_duplicate_key() { duplicate_key_ = {}; }
|
|
371
|
+
virtual void adjust_after_pushing(std::pair<K, T> p) { }
|
|
372
|
+
public:
|
|
373
|
+
Hashed(size_t s = 0)
|
|
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
|
+
}
|
|
383
|
+
virtual ~Hashed();
|
|
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, ObjHashEquality
|
|
400
|
+
>& elements() { return elements_; }
|
|
401
|
+
Hashed& operator<<(std::pair<K, T> p)
|
|
402
|
+
{
|
|
403
|
+
reset_hash();
|
|
404
|
+
|
|
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
|
+
}
|
|
412
|
+
|
|
413
|
+
elements_[p.first] = p.second;
|
|
414
|
+
|
|
415
|
+
adjust_after_pushing(p);
|
|
416
|
+
return *this;
|
|
417
|
+
}
|
|
418
|
+
Hashed& operator+=(Hashed* h)
|
|
419
|
+
{
|
|
420
|
+
if (length() == 0) {
|
|
421
|
+
this->elements_ = h->elements_;
|
|
422
|
+
this->_values = h->_values;
|
|
423
|
+
this->_keys = h->_keys;
|
|
424
|
+
return *this;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
for (auto key : h->keys()) {
|
|
428
|
+
*this << std::make_pair(key, h->at(key));
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
reset_duplicate_key();
|
|
432
|
+
return *this;
|
|
433
|
+
}
|
|
434
|
+
const std::unordered_map<
|
|
435
|
+
K, T, ObjHash, ObjHashEquality
|
|
436
|
+
>& pairs() const { return elements_; }
|
|
437
|
+
|
|
438
|
+
const sass::vector<K>& keys() const { return _keys; }
|
|
439
|
+
const sass::vector<T>& values() const { return _values; }
|
|
440
|
+
|
|
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(); }
|
|
445
|
+
|
|
446
|
+
};
|
|
447
|
+
template <typename K, typename T, typename U>
|
|
448
|
+
inline Hashed<K, T, U>::~Hashed() { }
|
|
449
|
+
|
|
450
|
+
/////////////////////////////////////////////////////////////////////////
|
|
451
|
+
// Abstract base class for statements. This side of the AST hierarchy
|
|
452
|
+
// represents elements in expansion contexts, which exist primarily to be
|
|
453
|
+
// rewritten and macro-expanded.
|
|
454
|
+
/////////////////////////////////////////////////////////////////////////
|
|
455
|
+
class Statement : public AST_Node {
|
|
456
|
+
public:
|
|
457
|
+
enum Type {
|
|
458
|
+
NONE,
|
|
459
|
+
RULESET,
|
|
460
|
+
MEDIA,
|
|
461
|
+
DIRECTIVE,
|
|
462
|
+
SUPPORTS,
|
|
463
|
+
ATROOT,
|
|
464
|
+
BUBBLE,
|
|
465
|
+
CONTENT,
|
|
466
|
+
KEYFRAMERULE,
|
|
467
|
+
DECLARATION,
|
|
468
|
+
ASSIGNMENT,
|
|
469
|
+
IMPORT_STUB,
|
|
470
|
+
IMPORT,
|
|
471
|
+
COMMENT,
|
|
472
|
+
WARNING,
|
|
473
|
+
RETURN,
|
|
474
|
+
EXTEND,
|
|
475
|
+
ERROR,
|
|
476
|
+
DEBUGSTMT,
|
|
477
|
+
WHILE,
|
|
478
|
+
EACH,
|
|
479
|
+
FOR,
|
|
480
|
+
IF
|
|
481
|
+
};
|
|
482
|
+
private:
|
|
483
|
+
ADD_PROPERTY(Type, statement_type)
|
|
484
|
+
ADD_PROPERTY(size_t, tabs)
|
|
485
|
+
ADD_PROPERTY(bool, group_end)
|
|
486
|
+
public:
|
|
487
|
+
Statement(SourceSpan pstate, Type st = NONE, size_t t = 0);
|
|
488
|
+
virtual ~Statement() = 0; // virtual destructor
|
|
489
|
+
// needed for rearranging nested rulesets during CSS emission
|
|
490
|
+
virtual bool bubbles();
|
|
491
|
+
virtual bool has_content();
|
|
492
|
+
virtual bool is_invisible() const;
|
|
493
|
+
ATTACH_VIRTUAL_AST_OPERATIONS(Statement)
|
|
494
|
+
};
|
|
495
|
+
inline Statement::~Statement() { }
|
|
496
|
+
|
|
497
|
+
////////////////////////
|
|
498
|
+
// Blocks of statements.
|
|
499
|
+
////////////////////////
|
|
500
|
+
class Block final : public Statement, public Vectorized<Statement_Obj> {
|
|
501
|
+
ADD_PROPERTY(bool, is_root)
|
|
502
|
+
// needed for properly formatted CSS emission
|
|
503
|
+
protected:
|
|
504
|
+
void adjust_after_pushing(Statement_Obj s) override {}
|
|
505
|
+
public:
|
|
506
|
+
Block(SourceSpan pstate, size_t s = 0, bool r = false);
|
|
507
|
+
bool isInvisible() const;
|
|
508
|
+
bool has_content() override;
|
|
509
|
+
ATTACH_AST_OPERATIONS(Block)
|
|
510
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
////////////////////////////////////////////////////////////////////////
|
|
514
|
+
// Abstract base class for statements that contain blocks of statements.
|
|
515
|
+
////////////////////////////////////////////////////////////////////////
|
|
516
|
+
class ParentStatement : public Statement {
|
|
517
|
+
ADD_PROPERTY(Block_Obj, block)
|
|
518
|
+
public:
|
|
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;
|
|
523
|
+
};
|
|
524
|
+
inline ParentStatement::~ParentStatement() { }
|
|
525
|
+
|
|
526
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
527
|
+
// Rulesets (i.e., sets of styles headed by a selector and containing a block
|
|
528
|
+
// of style declarations.
|
|
529
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
530
|
+
class StyleRule final : public ParentStatement {
|
|
531
|
+
ADD_PROPERTY(SelectorListObj, selector)
|
|
532
|
+
ADD_PROPERTY(Selector_Schema_Obj, schema)
|
|
533
|
+
ADD_PROPERTY(bool, is_root);
|
|
534
|
+
public:
|
|
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()
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
/////////////////
|
|
542
|
+
// Bubble.
|
|
543
|
+
/////////////////
|
|
544
|
+
class Bubble final : public Statement {
|
|
545
|
+
ADD_PROPERTY(Statement_Obj, node)
|
|
546
|
+
ADD_PROPERTY(bool, group_end)
|
|
547
|
+
public:
|
|
548
|
+
Bubble(SourceSpan pstate, Statement_Obj n, Statement_Obj g = {}, size_t t = 0);
|
|
549
|
+
bool bubbles() override;
|
|
550
|
+
ATTACH_AST_OPERATIONS(Bubble)
|
|
551
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
/////////////////
|
|
555
|
+
// Trace.
|
|
556
|
+
/////////////////
|
|
557
|
+
class Trace final : public ParentStatement {
|
|
558
|
+
ADD_CONSTREF(char, type)
|
|
559
|
+
ADD_CONSTREF(sass::string, name)
|
|
560
|
+
public:
|
|
561
|
+
Trace(SourceSpan pstate, sass::string n, Block_Obj b = {}, char type = 'm');
|
|
562
|
+
ATTACH_AST_OPERATIONS(Trace)
|
|
563
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
///////////////////////////////////////////////////////////////////////
|
|
567
|
+
// At-rules -- arbitrary directives beginning with "@" that may have an
|
|
568
|
+
// optional statement block.
|
|
569
|
+
///////////////////////////////////////////////////////////////////////
|
|
570
|
+
class AtRule final : public ParentStatement {
|
|
571
|
+
ADD_CONSTREF(sass::string, keyword)
|
|
572
|
+
ADD_PROPERTY(SelectorListObj, selector)
|
|
573
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
574
|
+
public:
|
|
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()
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
///////////////////////////////////////////////////////////////////////
|
|
584
|
+
// Keyframe-rules -- the child blocks of "@keyframes" nodes.
|
|
585
|
+
///////////////////////////////////////////////////////////////////////
|
|
586
|
+
class Keyframe_Rule final : public ParentStatement {
|
|
587
|
+
// according to css spec, this should be <keyframes-name>
|
|
588
|
+
// <keyframes-name> = <custom-ident> | <string>
|
|
589
|
+
ADD_PROPERTY(SelectorListObj, name)
|
|
590
|
+
public:
|
|
591
|
+
Keyframe_Rule(SourceSpan pstate, Block_Obj b);
|
|
592
|
+
ATTACH_AST_OPERATIONS(Keyframe_Rule)
|
|
593
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
////////////////////////////////////////////////////////////////////////
|
|
597
|
+
// Declarations -- style rules consisting of a property name and values.
|
|
598
|
+
////////////////////////////////////////////////////////////////////////
|
|
599
|
+
class Declaration final : public ParentStatement {
|
|
600
|
+
ADD_PROPERTY(String_Obj, property)
|
|
601
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
602
|
+
ADD_PROPERTY(bool, is_important)
|
|
603
|
+
ADD_PROPERTY(bool, is_custom_property)
|
|
604
|
+
ADD_PROPERTY(bool, is_indented)
|
|
605
|
+
public:
|
|
606
|
+
Declaration(SourceSpan pstate, String_Obj prop, ExpressionObj val, bool i = false, bool c = false, Block_Obj b = {});
|
|
607
|
+
bool is_invisible() const override;
|
|
608
|
+
ATTACH_AST_OPERATIONS(Declaration)
|
|
609
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
/////////////////////////////////////
|
|
613
|
+
// Assignments -- variable and value.
|
|
614
|
+
/////////////////////////////////////
|
|
615
|
+
class Assignment final : public Statement {
|
|
616
|
+
ADD_CONSTREF(sass::string, variable)
|
|
617
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
618
|
+
ADD_PROPERTY(bool, is_default)
|
|
619
|
+
ADD_PROPERTY(bool, is_global)
|
|
620
|
+
public:
|
|
621
|
+
Assignment(SourceSpan pstate, sass::string var, ExpressionObj val, bool is_default = false, bool is_global = false);
|
|
622
|
+
ATTACH_AST_OPERATIONS(Assignment)
|
|
623
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
////////////////////////////////////////////////////////////////////////////
|
|
627
|
+
// Import directives. CSS and Sass import lists can be intermingled, so it's
|
|
628
|
+
// necessary to store a list of each in an Import node.
|
|
629
|
+
////////////////////////////////////////////////////////////////////////////
|
|
630
|
+
class Import final : public Statement {
|
|
631
|
+
sass::vector<ExpressionObj> urls_;
|
|
632
|
+
sass::vector<Include> incs_;
|
|
633
|
+
ADD_PROPERTY(List_Obj, import_queries);
|
|
634
|
+
public:
|
|
635
|
+
Import(SourceSpan pstate);
|
|
636
|
+
sass::vector<Include>& incs();
|
|
637
|
+
sass::vector<ExpressionObj>& urls();
|
|
638
|
+
ATTACH_AST_OPERATIONS(Import)
|
|
639
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
// not yet resolved single import
|
|
643
|
+
// so far we only know requested name
|
|
644
|
+
class Import_Stub final : public Statement {
|
|
645
|
+
Include resource_;
|
|
646
|
+
public:
|
|
647
|
+
Import_Stub(SourceSpan pstate, Include res);
|
|
648
|
+
Include resource();
|
|
649
|
+
sass::string imp_path();
|
|
650
|
+
sass::string abs_path();
|
|
651
|
+
ATTACH_AST_OPERATIONS(Import_Stub)
|
|
652
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
//////////////////////////////
|
|
656
|
+
// The Sass `@warn` directive.
|
|
657
|
+
//////////////////////////////
|
|
658
|
+
class WarningRule final : public Statement {
|
|
659
|
+
ADD_PROPERTY(ExpressionObj, message)
|
|
660
|
+
public:
|
|
661
|
+
WarningRule(SourceSpan pstate, ExpressionObj msg);
|
|
662
|
+
ATTACH_AST_OPERATIONS(WarningRule)
|
|
663
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
///////////////////////////////
|
|
667
|
+
// The Sass `@error` directive.
|
|
668
|
+
///////////////////////////////
|
|
669
|
+
class ErrorRule final : public Statement {
|
|
670
|
+
ADD_PROPERTY(ExpressionObj, message)
|
|
671
|
+
public:
|
|
672
|
+
ErrorRule(SourceSpan pstate, ExpressionObj msg);
|
|
673
|
+
ATTACH_AST_OPERATIONS(ErrorRule)
|
|
674
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
///////////////////////////////
|
|
678
|
+
// The Sass `@debug` directive.
|
|
679
|
+
///////////////////////////////
|
|
680
|
+
class DebugRule final : public Statement {
|
|
681
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
682
|
+
public:
|
|
683
|
+
DebugRule(SourceSpan pstate, ExpressionObj val);
|
|
684
|
+
ATTACH_AST_OPERATIONS(DebugRule)
|
|
685
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
///////////////////////////////////////////
|
|
689
|
+
// CSS comments. These may be interpolated.
|
|
690
|
+
///////////////////////////////////////////
|
|
691
|
+
class Comment final : public Statement {
|
|
692
|
+
ADD_PROPERTY(String_Obj, text)
|
|
693
|
+
ADD_PROPERTY(bool, is_important)
|
|
694
|
+
public:
|
|
695
|
+
Comment(SourceSpan pstate, String_Obj txt, bool is_important);
|
|
696
|
+
virtual bool is_invisible() const override;
|
|
697
|
+
ATTACH_AST_OPERATIONS(Comment)
|
|
698
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
////////////////////////////////////
|
|
702
|
+
// The Sass `@if` control directive.
|
|
703
|
+
////////////////////////////////////
|
|
704
|
+
class If final : public ParentStatement {
|
|
705
|
+
ADD_PROPERTY(ExpressionObj, predicate)
|
|
706
|
+
ADD_PROPERTY(Block_Obj, alternative)
|
|
707
|
+
public:
|
|
708
|
+
If(SourceSpan pstate, ExpressionObj pred, Block_Obj con, Block_Obj alt = {});
|
|
709
|
+
virtual bool has_content() override;
|
|
710
|
+
ATTACH_AST_OPERATIONS(If)
|
|
711
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
/////////////////////////////////////
|
|
715
|
+
// The Sass `@for` control directive.
|
|
716
|
+
/////////////////////////////////////
|
|
717
|
+
class ForRule final : public ParentStatement {
|
|
718
|
+
ADD_CONSTREF(sass::string, variable)
|
|
719
|
+
ADD_PROPERTY(ExpressionObj, lower_bound)
|
|
720
|
+
ADD_PROPERTY(ExpressionObj, upper_bound)
|
|
721
|
+
ADD_PROPERTY(bool, is_inclusive)
|
|
722
|
+
public:
|
|
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()
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
//////////////////////////////////////
|
|
729
|
+
// The Sass `@each` control directive.
|
|
730
|
+
//////////////////////////////////////
|
|
731
|
+
class EachRule final : public ParentStatement {
|
|
732
|
+
ADD_PROPERTY(sass::vector<sass::string>, variables)
|
|
733
|
+
ADD_PROPERTY(ExpressionObj, list)
|
|
734
|
+
public:
|
|
735
|
+
EachRule(SourceSpan pstate, sass::vector<sass::string> vars, ExpressionObj lst, Block_Obj b);
|
|
736
|
+
ATTACH_AST_OPERATIONS(EachRule)
|
|
737
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
///////////////////////////////////////
|
|
741
|
+
// The Sass `@while` control directive.
|
|
742
|
+
///////////////////////////////////////
|
|
743
|
+
class WhileRule final : public ParentStatement {
|
|
744
|
+
ADD_PROPERTY(ExpressionObj, predicate)
|
|
745
|
+
public:
|
|
746
|
+
WhileRule(SourceSpan pstate, ExpressionObj pred, Block_Obj b);
|
|
747
|
+
ATTACH_AST_OPERATIONS(WhileRule)
|
|
748
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
/////////////////////////////////////////////////////////////
|
|
752
|
+
// The @return directive for use inside SassScript functions.
|
|
753
|
+
/////////////////////////////////////////////////////////////
|
|
754
|
+
class Return final : public Statement {
|
|
755
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
756
|
+
public:
|
|
757
|
+
Return(SourceSpan pstate, ExpressionObj val);
|
|
758
|
+
ATTACH_AST_OPERATIONS(Return)
|
|
759
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
763
|
+
// Definitions for both mixins and functions. The two cases are distinguished
|
|
764
|
+
// by a type tag.
|
|
765
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
766
|
+
class Definition final : public ParentStatement {
|
|
767
|
+
public:
|
|
768
|
+
enum Type { MIXIN, FUNCTION };
|
|
769
|
+
ADD_CONSTREF(sass::string, name)
|
|
770
|
+
ADD_PROPERTY(Parameters_Obj, parameters)
|
|
771
|
+
ADD_PROPERTY(Env*, environment)
|
|
772
|
+
ADD_PROPERTY(Type, type)
|
|
773
|
+
ADD_PROPERTY(Native_Function, native_function)
|
|
774
|
+
ADD_PROPERTY(Sass_Function_Entry, c_function)
|
|
775
|
+
ADD_PROPERTY(void*, cookie)
|
|
776
|
+
ADD_PROPERTY(bool, is_overload_stub)
|
|
777
|
+
ADD_PROPERTY(Signature, signature)
|
|
778
|
+
public:
|
|
779
|
+
Definition(SourceSpan pstate,
|
|
780
|
+
sass::string n,
|
|
781
|
+
Parameters_Obj params,
|
|
782
|
+
Block_Obj b,
|
|
783
|
+
Type t);
|
|
784
|
+
Definition(SourceSpan pstate,
|
|
785
|
+
Signature sig,
|
|
786
|
+
sass::string n,
|
|
787
|
+
Parameters_Obj params,
|
|
788
|
+
Native_Function func_ptr,
|
|
789
|
+
bool overload_stub = false);
|
|
790
|
+
Definition(SourceSpan pstate,
|
|
791
|
+
Signature sig,
|
|
792
|
+
sass::string n,
|
|
793
|
+
Parameters_Obj params,
|
|
794
|
+
Sass_Function_Entry c_func);
|
|
795
|
+
ATTACH_AST_OPERATIONS(Definition)
|
|
796
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
//////////////////////////////////////
|
|
800
|
+
// Mixin calls (i.e., `@include ...`).
|
|
801
|
+
//////////////////////////////////////
|
|
802
|
+
class Mixin_Call final : public ParentStatement {
|
|
803
|
+
ADD_CONSTREF(sass::string, name)
|
|
804
|
+
ADD_PROPERTY(Arguments_Obj, arguments)
|
|
805
|
+
ADD_PROPERTY(Parameters_Obj, block_parameters)
|
|
806
|
+
public:
|
|
807
|
+
Mixin_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Parameters_Obj b_params = {}, Block_Obj b = {});
|
|
808
|
+
ATTACH_AST_OPERATIONS(Mixin_Call)
|
|
809
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
///////////////////////////////////////////////////
|
|
813
|
+
// The @content directive for mixin content blocks.
|
|
814
|
+
///////////////////////////////////////////////////
|
|
815
|
+
class Content final : public Statement {
|
|
816
|
+
ADD_PROPERTY(Arguments_Obj, arguments)
|
|
817
|
+
public:
|
|
818
|
+
Content(SourceSpan pstate, Arguments_Obj args);
|
|
819
|
+
ATTACH_AST_OPERATIONS(Content)
|
|
820
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
////////////////////////////////////////////////////////////////////////////
|
|
824
|
+
// Arithmetic negation (logical negation is just an ordinary function call).
|
|
825
|
+
////////////////////////////////////////////////////////////////////////////
|
|
826
|
+
class Unary_Expression final : public Expression {
|
|
827
|
+
public:
|
|
828
|
+
enum Type { PLUS, MINUS, NOT, SLASH };
|
|
829
|
+
private:
|
|
830
|
+
HASH_PROPERTY(Type, optype)
|
|
831
|
+
HASH_PROPERTY(ExpressionObj, operand)
|
|
832
|
+
mutable size_t hash_;
|
|
833
|
+
public:
|
|
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;
|
|
838
|
+
ATTACH_AST_OPERATIONS(Unary_Expression)
|
|
839
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
840
|
+
};
|
|
841
|
+
|
|
842
|
+
////////////////////////////////////////////////////////////
|
|
843
|
+
// Individual argument objects for mixin and function calls.
|
|
844
|
+
////////////////////////////////////////////////////////////
|
|
845
|
+
class Argument final : public Expression {
|
|
846
|
+
HASH_PROPERTY(ExpressionObj, value)
|
|
847
|
+
HASH_CONSTREF(sass::string, name)
|
|
848
|
+
ADD_PROPERTY(bool, is_rest_argument)
|
|
849
|
+
ADD_PROPERTY(bool, is_keyword_argument)
|
|
850
|
+
mutable size_t hash_;
|
|
851
|
+
public:
|
|
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;
|
|
856
|
+
ATTACH_AST_OPERATIONS(Argument)
|
|
857
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
////////////////////////////////////////////////////////////////////////
|
|
861
|
+
// Argument lists -- in their own class to facilitate context-sensitive
|
|
862
|
+
// error checking (e.g., ensuring that all ordinal arguments precede all
|
|
863
|
+
// named arguments).
|
|
864
|
+
////////////////////////////////////////////////////////////////////////
|
|
865
|
+
class Arguments final : public Expression, public Vectorized<Argument_Obj> {
|
|
866
|
+
ADD_PROPERTY(bool, has_named_arguments)
|
|
867
|
+
ADD_PROPERTY(bool, has_rest_argument)
|
|
868
|
+
ADD_PROPERTY(bool, has_keyword_argument)
|
|
869
|
+
protected:
|
|
870
|
+
void adjust_after_pushing(Argument_Obj a) override;
|
|
871
|
+
public:
|
|
872
|
+
Arguments(SourceSpan pstate);
|
|
873
|
+
void set_delayed(bool delayed) override;
|
|
874
|
+
Argument_Obj get_rest_argument();
|
|
875
|
+
Argument_Obj get_keyword_argument();
|
|
876
|
+
ATTACH_AST_OPERATIONS(Arguments)
|
|
877
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
878
|
+
};
|
|
879
|
+
|
|
880
|
+
|
|
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 = {});
|
|
887
|
+
|
|
888
|
+
bool bubbles() override { return true; };
|
|
889
|
+
bool is_invisible() const override { return false; };
|
|
890
|
+
ATTACH_AST_OPERATIONS(MediaRule)
|
|
891
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
892
|
+
};
|
|
893
|
+
|
|
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> {
|
|
898
|
+
public:
|
|
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; };
|
|
903
|
+
|
|
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);
|
|
910
|
+
}
|
|
911
|
+
bool operator!=(const CssMediaRule& rhs) const {
|
|
912
|
+
// Invert from equality
|
|
913
|
+
return !(*this == rhs);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
ATTACH_AST_OPERATIONS(CssMediaRule)
|
|
917
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
// Media Queries after they have been evaluated
|
|
921
|
+
// Representing the static or resulting css
|
|
922
|
+
class CssMediaQuery final : public AST_Node {
|
|
923
|
+
|
|
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);
|
|
927
|
+
|
|
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);
|
|
931
|
+
|
|
932
|
+
// Feature queries, including parentheses.
|
|
933
|
+
ADD_PROPERTY(sass::vector<sass::string>, features);
|
|
934
|
+
|
|
935
|
+
public:
|
|
936
|
+
CssMediaQuery(SourceSpan pstate);
|
|
937
|
+
|
|
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);
|
|
943
|
+
}
|
|
944
|
+
|
|
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();
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// Whether this media query matches all media types.
|
|
954
|
+
bool matchesAllTypes() const {
|
|
955
|
+
return type_.empty() || Util::equalsLiteral("all", type_);
|
|
956
|
+
}
|
|
957
|
+
|
|
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);
|
|
961
|
+
|
|
962
|
+
ATTACH_AST_OPERATIONS(CssMediaQuery)
|
|
963
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
964
|
+
};
|
|
965
|
+
|
|
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> {
|
|
972
|
+
ADD_PROPERTY(String_Obj, media_type)
|
|
973
|
+
ADD_PROPERTY(bool, is_negated)
|
|
974
|
+
ADD_PROPERTY(bool, is_restricted)
|
|
975
|
+
public:
|
|
976
|
+
Media_Query(SourceSpan pstate, String_Obj t = {}, size_t s = 0, bool n = false, bool r = false);
|
|
977
|
+
ATTACH_AST_OPERATIONS(Media_Query)
|
|
978
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
979
|
+
};
|
|
980
|
+
|
|
981
|
+
////////////////////////////////////////////////////
|
|
982
|
+
// Media expressions (for use inside media queries).
|
|
983
|
+
// ToDo: only used for interpolation case
|
|
984
|
+
////////////////////////////////////////////////////
|
|
985
|
+
class Media_Query_Expression final : public Expression {
|
|
986
|
+
ADD_PROPERTY(ExpressionObj, feature)
|
|
987
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
988
|
+
ADD_PROPERTY(bool, is_interpolated)
|
|
989
|
+
public:
|
|
990
|
+
Media_Query_Expression(SourceSpan pstate, ExpressionObj f, ExpressionObj v, bool i = false);
|
|
991
|
+
ATTACH_AST_OPERATIONS(Media_Query_Expression)
|
|
992
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
993
|
+
};
|
|
994
|
+
|
|
995
|
+
/////////////////////////////////////////////////
|
|
996
|
+
// At root expressions (for use inside @at-root).
|
|
997
|
+
/////////////////////////////////////////////////
|
|
998
|
+
class At_Root_Query final : public Expression {
|
|
999
|
+
private:
|
|
1000
|
+
ADD_PROPERTY(ExpressionObj, feature)
|
|
1001
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
1002
|
+
public:
|
|
1003
|
+
At_Root_Query(SourceSpan pstate, ExpressionObj f = {}, ExpressionObj v = {}, bool i = false);
|
|
1004
|
+
bool exclude(sass::string str);
|
|
1005
|
+
ATTACH_AST_OPERATIONS(At_Root_Query)
|
|
1006
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
///////////
|
|
1010
|
+
// At-root.
|
|
1011
|
+
///////////
|
|
1012
|
+
class AtRootRule final : public ParentStatement {
|
|
1013
|
+
ADD_PROPERTY(At_Root_Query_Obj, expression)
|
|
1014
|
+
public:
|
|
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()
|
|
1020
|
+
};
|
|
1021
|
+
|
|
1022
|
+
/////////////////////////////////////////////////////////
|
|
1023
|
+
// Individual parameter objects for mixins and functions.
|
|
1024
|
+
/////////////////////////////////////////////////////////
|
|
1025
|
+
class Parameter final : public AST_Node {
|
|
1026
|
+
ADD_CONSTREF(sass::string, name)
|
|
1027
|
+
ADD_PROPERTY(ExpressionObj, default_value)
|
|
1028
|
+
ADD_PROPERTY(bool, is_rest_parameter)
|
|
1029
|
+
public:
|
|
1030
|
+
Parameter(SourceSpan pstate, sass::string n, ExpressionObj def = {}, bool rest = false);
|
|
1031
|
+
ATTACH_AST_OPERATIONS(Parameter)
|
|
1032
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
1033
|
+
};
|
|
1034
|
+
|
|
1035
|
+
/////////////////////////////////////////////////////////////////////////
|
|
1036
|
+
// Parameter lists -- in their own class to facilitate context-sensitive
|
|
1037
|
+
// error checking (e.g., ensuring that all optional parameters follow all
|
|
1038
|
+
// required parameters).
|
|
1039
|
+
/////////////////////////////////////////////////////////////////////////
|
|
1040
|
+
class Parameters final : public AST_Node, public Vectorized<Parameter_Obj> {
|
|
1041
|
+
ADD_PROPERTY(bool, has_optional_parameters)
|
|
1042
|
+
ADD_PROPERTY(bool, has_rest_parameter)
|
|
1043
|
+
protected:
|
|
1044
|
+
void adjust_after_pushing(Parameter_Obj p) override;
|
|
1045
|
+
public:
|
|
1046
|
+
Parameters(SourceSpan pstate);
|
|
1047
|
+
ATTACH_AST_OPERATIONS(Parameters)
|
|
1048
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
1049
|
+
};
|
|
1050
|
+
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
#include "ast_values.hpp"
|
|
1054
|
+
#include "ast_supports.hpp"
|
|
1055
|
+
#include "ast_selectors.hpp"
|
|
1056
|
+
|
|
1057
|
+
#ifdef __clang__
|
|
1058
|
+
|
|
1059
|
+
// #pragma clang diagnostic pop
|
|
1060
|
+
// #pragma clang diagnostic push
|
|
1061
|
+
|
|
1062
|
+
#endif
|
|
1063
|
+
|
|
1064
|
+
#endif
|