sassc 2.0.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.gitmodules +1 -1
- data/.travis.yml +9 -3
- data/CHANGELOG.md +36 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +1 -1
- data/Rakefile +43 -7
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/include/sass/base.h +9 -1
- data/ext/libsass/include/sass/context.h +5 -1
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +755 -2028
- data/ext/libsass/src/ast.hpp +492 -2477
- data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +70 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
- data/ext/libsass/src/ast_helpers.hpp +292 -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 +1043 -0
- data/ext/libsass/src/ast_selectors.hpp +522 -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/backtrace.cpp +11 -7
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +5 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +35 -34
- data/ext/libsass/src/bind.hpp +3 -1
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +83 -88
- data/ext/libsass/src/check_nesting.hpp +39 -34
- data/ext/libsass/src/color_maps.cpp +168 -164
- data/ext/libsass/src/color_maps.hpp +152 -160
- data/ext/libsass/src/constants.cpp +20 -0
- data/ext/libsass/src/constants.hpp +19 -0
- data/ext/libsass/src/context.cpp +104 -121
- data/ext/libsass/src/context.hpp +43 -55
- data/ext/libsass/src/cssize.cpp +103 -188
- data/ext/libsass/src/cssize.hpp +45 -51
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +524 -361
- data/ext/libsass/src/emitter.cpp +26 -26
- data/ext/libsass/src/emitter.hpp +20 -18
- data/ext/libsass/src/environment.cpp +41 -27
- data/ext/libsass/src/environment.hpp +33 -22
- data/ext/libsass/src/error_handling.cpp +92 -94
- data/ext/libsass/src/error_handling.hpp +73 -50
- data/ext/libsass/src/eval.cpp +380 -515
- data/ext/libsass/src/eval.hpp +64 -57
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +322 -263
- data/ext/libsass/src/expand.hpp +55 -39
- data/ext/libsass/src/extender.cpp +1188 -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 +134 -88
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +596 -0
- data/ext/libsass/src/fn_colors.hpp +85 -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 +244 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +227 -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 +158 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +253 -266
- data/ext/libsass/src/inspect.hpp +72 -74
- data/ext/libsass/src/json.cpp +2 -2
- data/ext/libsass/src/lexer.cpp +25 -84
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +27 -43
- data/ext/libsass/src/listize.hpp +14 -11
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory.hpp +12 -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/operation.hpp +193 -143
- data/ext/libsass/src/operators.cpp +56 -29
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +59 -75
- data/ext/libsass/src/output.hpp +15 -22
- data/ext/libsass/src/parser.cpp +662 -818
- data/ext/libsass/src/parser.hpp +96 -100
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +12 -8
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +10 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +14 -8
- data/ext/libsass/src/prelexer.hpp +9 -9
- data/ext/libsass/src/remove_placeholders.cpp +59 -57
- data/ext/libsass/src/remove_placeholders.hpp +20 -18
- data/ext/libsass/src/sass.cpp +25 -18
- data/ext/libsass/src/sass.hpp +22 -14
- data/ext/libsass/src/sass2scss.cpp +49 -18
- data/ext/libsass/src/sass_context.cpp +104 -132
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +7 -4
- data/ext/libsass/src/sass_functions.hpp +1 -1
- data/ext/libsass/src/sass_values.cpp +26 -21
- 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 +27 -20
- data/ext/libsass/src/source_map.hpp +14 -11
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +24 -22
- data/ext/libsass/src/to_value.hpp +18 -22
- data/ext/libsass/src/units.cpp +28 -22
- data/ext/libsass/src/units.hpp +9 -8
- data/ext/libsass/src/utf8/checked.h +12 -10
- data/ext/libsass/src/utf8/core.h +3 -0
- data/ext/libsass/src/utf8_string.cpp +12 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +97 -107
- data/ext/libsass/src/util.hpp +74 -30
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +33 -24
- data/ext/libsass/src/values.hpp +2 -2
- data/lib/sassc.rb +24 -0
- data/lib/sassc/engine.rb +7 -5
- data/lib/sassc/functions_handler.rb +11 -13
- data/lib/sassc/native.rb +10 -9
- data/lib/sassc/native/native_functions_api.rb +0 -5
- data/lib/sassc/script.rb +4 -6
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +32 -12
- data/test/engine_test.rb +32 -2
- data/test/functions_test.rb +38 -1
- data/test/native_test.rb +4 -4
- metadata +95 -109
- data/ext/Rakefile +0 -3
- data/ext/libsass/.editorconfig +0 -15
- data/ext/libsass/.gitattributes +0 -2
- data/ext/libsass/.github/CONTRIBUTING.md +0 -65
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
- data/ext/libsass/.gitignore +0 -85
- data/ext/libsass/.travis.yml +0 -64
- data/ext/libsass/COPYING +0 -25
- data/ext/libsass/GNUmakefile.am +0 -88
- data/ext/libsass/INSTALL +0 -1
- data/ext/libsass/LICENSE +0 -25
- data/ext/libsass/Makefile +0 -351
- data/ext/libsass/Makefile.conf +0 -55
- data/ext/libsass/Readme.md +0 -104
- data/ext/libsass/SECURITY.md +0 -10
- data/ext/libsass/appveyor.yml +0 -91
- data/ext/libsass/configure.ac +0 -138
- data/ext/libsass/contrib/libsass.spec +0 -66
- data/ext/libsass/docs/README.md +0 -20
- data/ext/libsass/docs/api-context-example.md +0 -45
- data/ext/libsass/docs/api-context-internal.md +0 -163
- data/ext/libsass/docs/api-context.md +0 -295
- data/ext/libsass/docs/api-doc.md +0 -215
- data/ext/libsass/docs/api-function-example.md +0 -67
- data/ext/libsass/docs/api-function-internal.md +0 -8
- data/ext/libsass/docs/api-function.md +0 -74
- data/ext/libsass/docs/api-importer-example.md +0 -112
- data/ext/libsass/docs/api-importer-internal.md +0 -20
- data/ext/libsass/docs/api-importer.md +0 -86
- data/ext/libsass/docs/api-value-example.md +0 -55
- data/ext/libsass/docs/api-value-internal.md +0 -76
- data/ext/libsass/docs/api-value.md +0 -154
- data/ext/libsass/docs/build-on-darwin.md +0 -27
- data/ext/libsass/docs/build-on-gentoo.md +0 -55
- data/ext/libsass/docs/build-on-windows.md +0 -139
- data/ext/libsass/docs/build-shared-library.md +0 -35
- data/ext/libsass/docs/build-with-autotools.md +0 -78
- data/ext/libsass/docs/build-with-makefiles.md +0 -68
- data/ext/libsass/docs/build-with-mingw.md +0 -107
- data/ext/libsass/docs/build-with-visual-studio.md +0 -90
- data/ext/libsass/docs/build.md +0 -97
- data/ext/libsass/docs/compatibility-plan.md +0 -48
- data/ext/libsass/docs/contributing.md +0 -17
- data/ext/libsass/docs/custom-functions-internal.md +0 -122
- data/ext/libsass/docs/dev-ast-memory.md +0 -223
- data/ext/libsass/docs/implementations.md +0 -56
- data/ext/libsass/docs/plugins.md +0 -47
- data/ext/libsass/docs/setup-environment.md +0 -68
- data/ext/libsass/docs/source-map-internals.md +0 -51
- data/ext/libsass/docs/trace.md +0 -26
- data/ext/libsass/docs/triage.md +0 -17
- data/ext/libsass/docs/unicode.md +0 -39
- data/ext/libsass/extconf.rb +0 -6
- data/ext/libsass/include/sass/version.h.in +0 -12
- data/ext/libsass/m4/.gitkeep +0 -0
- data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
- data/ext/libsass/res/resource.rc +0 -35
- data/ext/libsass/script/bootstrap +0 -13
- data/ext/libsass/script/branding +0 -10
- data/ext/libsass/script/ci-build-libsass +0 -134
- data/ext/libsass/script/ci-build-plugin +0 -62
- data/ext/libsass/script/ci-install-compiler +0 -6
- data/ext/libsass/script/ci-install-deps +0 -20
- data/ext/libsass/script/ci-report-coverage +0 -42
- data/ext/libsass/script/spec +0 -5
- data/ext/libsass/script/tap-driver +0 -652
- data/ext/libsass/script/tap-runner +0 -1
- data/ext/libsass/script/test-leaks.pl +0 -103
- data/ext/libsass/src/GNUmakefile.am +0 -54
- data/ext/libsass/src/extend.cpp +0 -2130
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/functions.cpp +0 -2234
- data/ext/libsass/src/functions.hpp +0 -198
- data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
- data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
- data/ext/libsass/src/node.cpp +0 -319
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -149
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -55
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/ext/libsass/src/support/libsass.pc.in +0 -11
- data/ext/libsass/src/to_c.hpp +0 -39
- data/ext/libsass/test/test_node.cpp +0 -94
- data/ext/libsass/test/test_paths.cpp +0 -28
- data/ext/libsass/test/test_selector_difference.cpp +0 -25
- data/ext/libsass/test/test_specificity.cpp +0 -25
- data/ext/libsass/test/test_subset_map.cpp +0 -472
- data/ext/libsass/test/test_superselector.cpp +0 -69
- data/ext/libsass/test/test_unification.cpp +0 -31
- data/ext/libsass/version.sh +0 -10
- data/ext/libsass/win/libsass.sln +0 -39
- data/ext/libsass/win/libsass.sln.DotSettings +0 -9
- data/ext/libsass/win/libsass.targets +0 -118
- data/ext/libsass/win/libsass.vcxproj +0 -188
- data/ext/libsass/win/libsass.vcxproj.filters +0 -357
- data/lib/sassc/native/lib_c.rb +0 -21
- data/lib/tasks/libsass.rb +0 -33
data/ext/libsass/src/ast.hpp
CHANGED
|
@@ -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
|
-
|
|
6
|
-
#include <deque>
|
|
7
|
-
#include <vector>
|
|
8
|
-
#include <string>
|
|
9
|
-
#include <sstream>
|
|
10
|
-
#include <iostream>
|
|
7
|
+
|
|
11
8
|
#include <typeinfo>
|
|
12
|
-
#include <
|
|
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
|
-
#
|
|
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 "
|
|
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(
|
|
58
|
+
ADD_PROPERTY(SourceSpan, pstate)
|
|
112
59
|
public:
|
|
113
|
-
AST_Node(
|
|
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
|
-
|
|
125
|
-
virtual
|
|
126
|
-
virtual
|
|
127
|
-
virtual
|
|
128
|
-
virtual
|
|
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
|
|
84
|
+
// ToDo: add specific implementations to all children
|
|
132
85
|
virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
|
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(
|
|
152
|
+
ADD_PROPERTY(Type, concrete_type)
|
|
194
153
|
public:
|
|
195
|
-
Expression(
|
|
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
|
-
|
|
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
|
-
|
|
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::
|
|
185
|
+
struct hash<Sass::ExpressionObj>
|
|
269
186
|
{
|
|
270
|
-
size_t operator()(Sass::
|
|
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::
|
|
193
|
+
struct equal_to<Sass::ExpressionObj>
|
|
277
194
|
{
|
|
278
|
-
bool operator()( Sass::
|
|
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
|
-
|
|
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) :
|
|
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()
|
|
307
|
-
T first()
|
|
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
|
-
|
|
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 (
|
|
315
|
-
|
|
316
|
-
elements_.push_back(element);
|
|
317
|
-
adjust_after_pushing(element);
|
|
274
|
+
if (v != nullptr) {
|
|
275
|
+
return concat(*v);
|
|
318
276
|
}
|
|
319
277
|
}
|
|
320
|
-
|
|
278
|
+
|
|
279
|
+
// Insert one item on the front
|
|
280
|
+
void unshift(T element)
|
|
321
281
|
{
|
|
322
|
-
|
|
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
|
-
|
|
294
|
+
|
|
295
|
+
// Insert one item on the back
|
|
296
|
+
// ToDo: rename this to push
|
|
297
|
+
void append(T element)
|
|
325
298
|
{
|
|
326
|
-
|
|
327
|
-
|
|
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
|
-
|
|
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
|
-
|
|
344
|
-
typename
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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 <
|
|
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
|
-
|
|
361
|
-
|
|
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
|
-
|
|
367
|
+
mutable size_t hash_;
|
|
368
|
+
K duplicate_key_;
|
|
365
369
|
void reset_hash() { hash_ = 0; }
|
|
366
|
-
void reset_duplicate_key() { duplicate_key_ =
|
|
367
|
-
virtual void adjust_after_pushing(std::pair<
|
|
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_(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
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
|
|
376
|
-
bool empty() const { return
|
|
377
|
-
bool has(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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))
|
|
387
|
-
|
|
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->
|
|
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
|
|
410
|
-
|
|
434
|
+
const std::unordered_map<
|
|
435
|
+
K, T, ObjHash, ObjEquality
|
|
436
|
+
>& pairs() const { return elements_; }
|
|
411
437
|
|
|
412
|
-
|
|
413
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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(
|
|
459
|
-
|
|
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
|
|
470
|
-
virtual bool
|
|
471
|
-
virtual bool
|
|
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(
|
|
490
|
-
|
|
491
|
-
|
|
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
|
-
|
|
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
|
|
516
|
+
class ParentStatement : public Statement {
|
|
514
517
|
ADD_PROPERTY(Block_Obj, block)
|
|
515
518
|
public:
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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
|
|
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
|
|
535
|
-
ADD_PROPERTY(
|
|
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
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
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(
|
|
559
|
-
|
|
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
|
-
|
|
551
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
569
552
|
};
|
|
570
553
|
|
|
571
554
|
/////////////////
|
|
572
555
|
// Trace.
|
|
573
556
|
/////////////////
|
|
574
|
-
class Trace : public
|
|
557
|
+
class Trace final : public ParentStatement {
|
|
575
558
|
ADD_CONSTREF(char, type)
|
|
576
|
-
ADD_CONSTREF(
|
|
559
|
+
ADD_CONSTREF(sass::string, name)
|
|
577
560
|
public:
|
|
578
|
-
Trace(
|
|
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
|
-
|
|
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
|
|
613
|
-
ADD_CONSTREF(
|
|
614
|
-
ADD_PROPERTY(
|
|
615
|
-
ADD_PROPERTY(
|
|
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
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
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
|
|
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(
|
|
589
|
+
ADD_PROPERTY(SelectorListObj, name)
|
|
650
590
|
public:
|
|
651
|
-
Keyframe_Rule(
|
|
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
|
-
|
|
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
|
|
599
|
+
class Declaration final : public ParentStatement {
|
|
665
600
|
ADD_PROPERTY(String_Obj, property)
|
|
666
|
-
ADD_PROPERTY(
|
|
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(
|
|
672
|
-
|
|
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
|
-
|
|
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(
|
|
693
|
-
ADD_PROPERTY(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
720
|
-
|
|
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(
|
|
724
|
-
|
|
725
|
-
|
|
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
|
-
|
|
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
|
-
|
|
747
|
-
|
|
748
|
-
|
|
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
|
-
|
|
652
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
758
653
|
};
|
|
759
654
|
|
|
760
655
|
//////////////////////////////
|
|
761
656
|
// The Sass `@warn` directive.
|
|
762
657
|
//////////////////////////////
|
|
763
|
-
class
|
|
764
|
-
ADD_PROPERTY(
|
|
658
|
+
class WarningRule final : public Statement {
|
|
659
|
+
ADD_PROPERTY(ExpressionObj, message)
|
|
765
660
|
public:
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
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
|
|
780
|
-
ADD_PROPERTY(
|
|
669
|
+
class ErrorRule final : public Statement {
|
|
670
|
+
ADD_PROPERTY(ExpressionObj, message)
|
|
781
671
|
public:
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
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
|
|
796
|
-
ADD_PROPERTY(
|
|
680
|
+
class DebugRule final : public Statement {
|
|
681
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
797
682
|
public:
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
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(
|
|
816
|
-
|
|
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
|
-
|
|
698
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
827
699
|
};
|
|
828
700
|
|
|
829
701
|
////////////////////////////////////
|
|
830
702
|
// The Sass `@if` control directive.
|
|
831
703
|
////////////////////////////////////
|
|
832
|
-
class If : public
|
|
833
|
-
ADD_PROPERTY(
|
|
704
|
+
class If final : public ParentStatement {
|
|
705
|
+
ADD_PROPERTY(ExpressionObj, predicate)
|
|
834
706
|
ADD_PROPERTY(Block_Obj, alternative)
|
|
835
707
|
public:
|
|
836
|
-
If(
|
|
837
|
-
|
|
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
|
-
|
|
711
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
850
712
|
};
|
|
851
713
|
|
|
852
714
|
/////////////////////////////////////
|
|
853
715
|
// The Sass `@for` control directive.
|
|
854
716
|
/////////////////////////////////////
|
|
855
|
-
class
|
|
856
|
-
ADD_CONSTREF(
|
|
857
|
-
ADD_PROPERTY(
|
|
858
|
-
ADD_PROPERTY(
|
|
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
|
-
|
|
862
|
-
|
|
863
|
-
|
|
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
|
|
881
|
-
ADD_PROPERTY(
|
|
882
|
-
ADD_PROPERTY(
|
|
731
|
+
class EachRule final : public ParentStatement {
|
|
732
|
+
ADD_PROPERTY(sass::vector<sass::string>, variables)
|
|
733
|
+
ADD_PROPERTY(ExpressionObj, list)
|
|
883
734
|
public:
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
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
|
|
898
|
-
ADD_PROPERTY(
|
|
743
|
+
class WhileRule final : public ParentStatement {
|
|
744
|
+
ADD_PROPERTY(ExpressionObj, predicate)
|
|
899
745
|
public:
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
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(
|
|
754
|
+
class Return final : public Statement {
|
|
755
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
915
756
|
public:
|
|
916
|
-
Return(
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
963
|
-
|
|
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
|
-
|
|
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
|
-
|
|
786
|
+
sass::string n,
|
|
994
787
|
Parameters_Obj params,
|
|
995
788
|
Native_Function func_ptr,
|
|
996
|
-
bool overload_stub = false)
|
|
997
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1034
|
-
ADD_CONSTREF(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
815
|
+
class Content final : public Statement {
|
|
816
|
+
ADD_PROPERTY(Arguments_Obj, arguments)
|
|
1054
817
|
public:
|
|
1055
|
-
Content(
|
|
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
|
-
|
|
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(
|
|
1291
|
-
size_t hash_;
|
|
831
|
+
HASH_PROPERTY(ExpressionObj, operand)
|
|
832
|
+
mutable size_t hash_;
|
|
1292
833
|
public:
|
|
1293
|
-
Unary_Expression(
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
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
|
-
|
|
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(
|
|
1343
|
-
HASH_CONSTREF(
|
|
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(
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
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
|
-
|
|
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(
|
|
1410
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1462
|
-
|
|
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
|
-
//
|
|
1467
|
-
|
|
1468
|
-
|
|
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
|
-
|
|
1477
|
-
|
|
1478
|
-
{
|
|
1479
|
-
|
|
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
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1528
|
-
|
|
915
|
+
|
|
916
|
+
ATTACH_AST_OPERATIONS(CssMediaRule)
|
|
917
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
1529
918
|
};
|
|
1530
919
|
|
|
1531
|
-
|
|
1532
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
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
|
-
|
|
1583
|
-
|
|
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
|
-
|
|
936
|
+
CssMediaQuery(SourceSpan pstate);
|
|
1595
937
|
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
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
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
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
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
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
|
-
|
|
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(
|
|
1739
|
-
|
|
962
|
+
ATTACH_AST_OPERATIONS(CssMediaQuery)
|
|
963
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
1740
964
|
};
|
|
1741
965
|
|
|
1742
|
-
|
|
1743
|
-
//
|
|
1744
|
-
//
|
|
1745
|
-
|
|
1746
|
-
class
|
|
1747
|
-
|
|
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_, "e_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(
|
|
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
|
-
|
|
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(
|
|
1923
|
-
ADD_PROPERTY(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
2062
|
-
ADD_PROPERTY(
|
|
1000
|
+
ADD_PROPERTY(ExpressionObj, feature)
|
|
1001
|
+
ADD_PROPERTY(ExpressionObj, value)
|
|
2063
1002
|
public:
|
|
2064
|
-
At_Root_Query(
|
|
2065
|
-
|
|
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
|
-
|
|
1006
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
|
2075
1007
|
};
|
|
2076
1008
|
|
|
2077
1009
|
///////////
|
|
2078
1010
|
// At-root.
|
|
2079
1011
|
///////////
|
|
2080
|
-
class
|
|
1012
|
+
class AtRootRule final : public ParentStatement {
|
|
2081
1013
|
ADD_PROPERTY(At_Root_Query_Obj, expression)
|
|
2082
1014
|
public:
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
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(
|
|
2168
|
-
ADD_PROPERTY(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|