sassc 2.0.1 → 2.1.0.pre1
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 +1 -0
- data/.gitmodules +1 -1
- data/.travis.yml +7 -3
- data/CHANGELOG.md +3 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +1 -1
- data/Rakefile +23 -8
- data/ext/extconf.rb +39 -0
- data/ext/libsass/.gitignore +1 -0
- data/ext/libsass/GNUmakefile.am +23 -39
- data/ext/libsass/Makefile +56 -91
- data/ext/libsass/Makefile.conf +16 -2
- data/ext/libsass/configure.ac +8 -12
- data/ext/libsass/include/sass/base.h +1 -0
- data/ext/libsass/include/sass/context.h +1 -1
- data/ext/libsass/src/GNUmakefile.am +1 -5
- data/ext/libsass/src/ast.cpp +747 -2010
- data/ext/libsass/src/ast.hpp +239 -2383
- 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 +62 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
- data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
- data/ext/libsass/src/ast_sel_unify.cpp +280 -0
- data/ext/libsass/src/ast_selectors.cpp +1475 -0
- data/ext/libsass/src/ast_selectors.hpp +568 -0
- data/ext/libsass/src/ast_supports.cpp +130 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +967 -0
- data/ext/libsass/src/ast_values.hpp +489 -0
- data/ext/libsass/src/backtrace.cpp +4 -0
- data/ext/libsass/src/base64vlq.cpp +3 -0
- data/ext/libsass/src/bind.cpp +18 -17
- 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 +2 -2
- data/ext/libsass/src/check_nesting.cpp +52 -56
- data/ext/libsass/src/check_nesting.hpp +35 -34
- data/ext/libsass/src/color_maps.cpp +156 -153
- data/ext/libsass/src/color_maps.hpp +152 -152
- data/ext/libsass/src/constants.cpp +15 -0
- data/ext/libsass/src/constants.hpp +13 -0
- data/ext/libsass/src/context.cpp +24 -14
- data/ext/libsass/src/context.hpp +6 -6
- data/ext/libsass/src/cssize.cpp +69 -71
- data/ext/libsass/src/cssize.hpp +50 -50
- data/ext/libsass/src/debugger.hpp +117 -110
- data/ext/libsass/src/emitter.cpp +13 -12
- data/ext/libsass/src/emitter.hpp +13 -9
- data/ext/libsass/src/environment.cpp +15 -1
- data/ext/libsass/src/environment.hpp +6 -0
- data/ext/libsass/src/error_handling.cpp +36 -59
- data/ext/libsass/src/error_handling.hpp +29 -16
- data/ext/libsass/src/eval.cpp +302 -323
- data/ext/libsass/src/eval.hpp +64 -55
- data/ext/libsass/src/expand.cpp +94 -88
- data/ext/libsass/src/expand.hpp +33 -37
- data/ext/libsass/src/extend.cpp +38 -36
- data/ext/libsass/src/extend.hpp +15 -15
- data/ext/libsass/src/file.cpp +34 -2
- data/ext/libsass/src/fn_colors.cpp +594 -0
- data/ext/libsass/src/fn_colors.hpp +85 -0
- data/ext/libsass/src/fn_lists.cpp +284 -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 +256 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +220 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +235 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +254 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +156 -0
- data/ext/libsass/src/fn_utils.hpp +56 -0
- data/ext/libsass/src/inspect.cpp +101 -152
- data/ext/libsass/src/inspect.hpp +69 -73
- data/ext/libsass/src/json.cpp +2 -2
- data/ext/libsass/src/lexer.cpp +6 -3
- data/ext/libsass/src/listize.cpp +9 -11
- data/ext/libsass/src/listize.hpp +11 -7
- data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
- data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
- data/ext/libsass/src/node.cpp +13 -10
- data/ext/libsass/src/node.hpp +3 -3
- data/ext/libsass/src/operation.hpp +184 -144
- data/ext/libsass/src/operators.cpp +43 -17
- data/ext/libsass/src/operators.hpp +5 -5
- data/ext/libsass/src/output.cpp +21 -18
- data/ext/libsass/src/output.hpp +14 -21
- data/ext/libsass/src/parser.cpp +215 -183
- data/ext/libsass/src/parser.hpp +28 -24
- data/ext/libsass/src/plugins.cpp +5 -1
- data/ext/libsass/src/position.cpp +3 -0
- data/ext/libsass/src/prelexer.cpp +9 -3
- data/ext/libsass/src/prelexer.hpp +9 -9
- data/ext/libsass/src/remove_placeholders.cpp +14 -11
- data/ext/libsass/src/remove_placeholders.hpp +8 -9
- data/ext/libsass/src/sass.cpp +9 -3
- data/ext/libsass/src/sass.hpp +12 -9
- data/ext/libsass/src/sass2scss.cpp +45 -14
- data/ext/libsass/src/sass_context.cpp +18 -15
- data/ext/libsass/src/sass_functions.cpp +6 -3
- data/ext/libsass/src/sass_functions.hpp +1 -1
- data/ext/libsass/src/sass_util.cpp +3 -0
- data/ext/libsass/src/sass_values.cpp +21 -13
- data/ext/libsass/src/source_map.cpp +5 -2
- data/ext/libsass/src/source_map.hpp +2 -2
- data/ext/libsass/src/subset_map.cpp +4 -1
- data/ext/libsass/src/to_value.cpp +23 -21
- data/ext/libsass/src/to_value.hpp +18 -22
- data/ext/libsass/src/units.cpp +4 -0
- data/ext/libsass/src/units.hpp +1 -0
- 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 +3 -0
- data/ext/libsass/src/util.cpp +67 -75
- data/ext/libsass/src/util.hpp +64 -19
- data/ext/libsass/src/util_string.cpp +75 -0
- data/ext/libsass/src/util_string.hpp +19 -0
- data/ext/libsass/src/values.cpp +22 -13
- data/ext/libsass/src/values.hpp +2 -2
- data/ext/libsass/win/libsass.targets +30 -4
- data/ext/libsass/win/libsass.vcxproj.filters +82 -4
- data/lib/sassc.rb +24 -0
- data/lib/sassc/engine.rb +2 -2
- data/lib/sassc/native.rb +8 -1
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +19 -11
- data/test/engine_test.rb +26 -1
- data/test/native_test.rb +1 -1
- metadata +66 -72
- data/ext/Rakefile +0 -3
- data/ext/libsass/.github/CONTRIBUTING.md +0 -65
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
- data/ext/libsass/.travis.yml +0 -64
- data/ext/libsass/Readme.md +0 -104
- data/ext/libsass/SECURITY.md +0 -10
- data/ext/libsass/appveyor.yml +0 -91
- 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/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/functions.cpp +0 -2234
- data/ext/libsass/src/functions.hpp +0 -198
- 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/lib/tasks/libsass.rb +0 -33
data/ext/libsass/Makefile.conf
CHANGED
@@ -7,16 +7,29 @@
|
|
7
7
|
|
8
8
|
SOURCES = \
|
9
9
|
ast.cpp \
|
10
|
+
ast_values.cpp \
|
11
|
+
ast_supports.cpp \
|
12
|
+
ast_sel_cmp.cpp \
|
13
|
+
ast_sel_unify.cpp \
|
14
|
+
ast_selectors.cpp \
|
10
15
|
node.cpp \
|
11
16
|
context.cpp \
|
12
17
|
constants.cpp \
|
13
|
-
|
18
|
+
fn_utils.cpp \
|
19
|
+
fn_miscs.cpp \
|
20
|
+
fn_maps.cpp \
|
21
|
+
fn_lists.cpp \
|
22
|
+
fn_colors.cpp \
|
23
|
+
fn_numbers.cpp \
|
24
|
+
fn_strings.cpp \
|
25
|
+
fn_selectors.cpp \
|
14
26
|
color_maps.cpp \
|
15
27
|
environment.cpp \
|
16
28
|
ast_fwd_decl.cpp \
|
17
29
|
bind.cpp \
|
18
30
|
file.cpp \
|
19
31
|
util.cpp \
|
32
|
+
util_string.cpp \
|
20
33
|
json.cpp \
|
21
34
|
units.cpp \
|
22
35
|
values.cpp \
|
@@ -43,7 +56,8 @@ SOURCES = \
|
|
43
56
|
sass2scss.cpp \
|
44
57
|
backtrace.cpp \
|
45
58
|
operators.cpp \
|
46
|
-
|
59
|
+
ast2c.cpp \
|
60
|
+
c2ast.cpp \
|
47
61
|
to_value.cpp \
|
48
62
|
source_map.cpp \
|
49
63
|
subset_map.cpp \
|
data/ext/libsass/configure.ac
CHANGED
@@ -9,6 +9,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
|
9
9
|
AC_CONFIG_HEADERS([src/config.h])
|
10
10
|
AC_CONFIG_FILES([include/sass/version.h])
|
11
11
|
AC_CONFIG_AUX_DIR([script])
|
12
|
+
|
12
13
|
# These are flags passed to automake
|
13
14
|
# Though they look like gcc flags!
|
14
15
|
AM_INIT_AUTOMAKE([foreign parallel-tests -Wall])
|
@@ -93,21 +94,16 @@ the --with-sass-spec-dir=<dir> argument.
|
|
93
94
|
;;
|
94
95
|
esac
|
95
96
|
AC_SUBST(SASS_SPEC_PATH)
|
96
|
-
|
97
|
-
#
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
use_tap=no
|
104
|
-
fi
|
105
|
-
AC_MSG_RESULT([$use_tap])
|
106
|
-
|
97
|
+
else
|
98
|
+
# we do not really need these paths for non test build
|
99
|
+
# but automake may error if we do not define them here
|
100
|
+
SASS_SPEC_PATH=sass-spec
|
101
|
+
SASS_SASSC_PATH=sassc
|
102
|
+
AC_SUBST(SASS_SPEC_PATH)
|
103
|
+
AC_SUBST(SASS_SASSC_PATH)
|
107
104
|
fi
|
108
105
|
|
109
106
|
AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "xyes")
|
110
|
-
AM_CONDITIONAL(USE_TAP, test "x$use_tap" = "xyes")
|
111
107
|
|
112
108
|
AC_ARG_ENABLE([coverage],
|
113
109
|
[AS_HELP_STRING([--enable-coverage],
|
@@ -43,7 +43,7 @@ ADDAPI struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_C
|
|
43
43
|
ADDAPI struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx);
|
44
44
|
|
45
45
|
// Execute the different compilation steps individually
|
46
|
-
//
|
46
|
+
// Useful if you only want to query the included files
|
47
47
|
ADDAPI int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler);
|
48
48
|
ADDAPI int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler);
|
49
49
|
|
@@ -13,11 +13,7 @@ AM_CFLAGS = $(AM_COPT)
|
|
13
13
|
AM_CXXFLAGS = $(AM_COPT)
|
14
14
|
AM_LDFLAGS = $(AM_COPT) $(AM_COVLDFLAGS)
|
15
15
|
|
16
|
-
|
17
|
-
AM_CXXFLAGS += -std=gnu++0x
|
18
|
-
else
|
19
|
-
AM_CXXFLAGS += -std=c++0x
|
20
|
-
endif
|
16
|
+
AM_CXXFLAGS += -std=c++11
|
21
17
|
|
22
18
|
EXTRA_DIST = \
|
23
19
|
COPYING \
|
data/ext/libsass/src/ast.cpp
CHANGED
@@ -19,1725 +19,678 @@ namespace Sass {
|
|
19
19
|
|
20
20
|
static Null sass_null(ParserState("null"));
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
{
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
}
|
67
|
-
|
68
|
-
bool Supports_Negation::needs_parens(Supports_Condition_Obj cond) const {
|
69
|
-
return Cast<Supports_Negation>(cond) ||
|
70
|
-
Cast<Supports_Operator>(cond);
|
71
|
-
}
|
72
|
-
|
73
|
-
void str_rtrim(std::string& str, const std::string& delimiters = " \f\n\r\t\v")
|
74
|
-
{
|
75
|
-
str.erase( str.find_last_not_of( delimiters ) + 1 );
|
76
|
-
}
|
77
|
-
|
78
|
-
void String_Constant::rtrim()
|
79
|
-
{
|
80
|
-
str_rtrim(value_);
|
81
|
-
}
|
82
|
-
|
83
|
-
void String_Schema::rtrim()
|
84
|
-
{
|
85
|
-
if (!empty()) {
|
86
|
-
if (String_Ptr str = Cast<String>(last())) str->rtrim();
|
87
|
-
}
|
88
|
-
}
|
89
|
-
|
90
|
-
void Argument::set_delayed(bool delayed)
|
91
|
-
{
|
92
|
-
if (value_) value_->set_delayed(delayed);
|
93
|
-
is_delayed(delayed);
|
94
|
-
}
|
95
|
-
|
96
|
-
void Arguments::set_delayed(bool delayed)
|
97
|
-
{
|
98
|
-
for (Argument_Obj arg : elements()) {
|
99
|
-
if (arg) arg->set_delayed(delayed);
|
100
|
-
}
|
101
|
-
is_delayed(delayed);
|
102
|
-
}
|
103
|
-
|
104
|
-
|
105
|
-
bool At_Root_Query::exclude(std::string str)
|
106
|
-
{
|
107
|
-
bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
|
108
|
-
List_Ptr l = static_cast<List_Ptr>(value().ptr());
|
109
|
-
std::string v;
|
110
|
-
|
111
|
-
if (with)
|
112
|
-
{
|
113
|
-
if (!l || l->length() == 0) return str.compare("rule") != 0;
|
114
|
-
for (size_t i = 0, L = l->length(); i < L; ++i)
|
115
|
-
{
|
116
|
-
v = unquote((*l)[i]->to_string());
|
117
|
-
if (v.compare("all") == 0 || v == str) return false;
|
118
|
-
}
|
119
|
-
return true;
|
120
|
-
}
|
121
|
-
else
|
122
|
-
{
|
123
|
-
if (!l || !l->length()) return str.compare("rule") == 0;
|
124
|
-
for (size_t i = 0, L = l->length(); i < L; ++i)
|
125
|
-
{
|
126
|
-
v = unquote((*l)[i]->to_string());
|
127
|
-
if (v.compare("all") == 0 || v == str) return true;
|
128
|
-
}
|
129
|
-
return false;
|
130
|
-
}
|
131
|
-
}
|
22
|
+
const char* sass_op_to_name(enum Sass_OP op) {
|
23
|
+
switch (op) {
|
24
|
+
case AND: return "and";
|
25
|
+
case OR: return "or";
|
26
|
+
case EQ: return "eq";
|
27
|
+
case NEQ: return "neq";
|
28
|
+
case GT: return "gt";
|
29
|
+
case GTE: return "gte";
|
30
|
+
case LT: return "lt";
|
31
|
+
case LTE: return "lte";
|
32
|
+
case ADD: return "plus";
|
33
|
+
case SUB: return "minus";
|
34
|
+
case MUL: return "times";
|
35
|
+
case DIV: return "div";
|
36
|
+
case MOD: return "mod";
|
37
|
+
// this is only used internally!
|
38
|
+
case NUM_OPS: return "[OPS]";
|
39
|
+
default: return "invalid";
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
const char* sass_op_separator(enum Sass_OP op) {
|
44
|
+
switch (op) {
|
45
|
+
case AND: return "&&";
|
46
|
+
case OR: return "||";
|
47
|
+
case EQ: return "==";
|
48
|
+
case NEQ: return "!=";
|
49
|
+
case GT: return ">";
|
50
|
+
case GTE: return ">=";
|
51
|
+
case LT: return "<";
|
52
|
+
case LTE: return "<=";
|
53
|
+
case ADD: return "+";
|
54
|
+
case SUB: return "-";
|
55
|
+
case MUL: return "*";
|
56
|
+
case DIV: return "/";
|
57
|
+
case MOD: return "%";
|
58
|
+
// this is only used internally!
|
59
|
+
case NUM_OPS: return "[OPS]";
|
60
|
+
default: return "invalid";
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
/////////////////////////////////////////////////////////////////////////
|
65
|
+
/////////////////////////////////////////////////////////////////////////
|
132
66
|
|
133
67
|
void AST_Node::update_pstate(const ParserState& pstate)
|
134
68
|
{
|
135
69
|
pstate_.offset += pstate - pstate_ + pstate.offset;
|
136
70
|
}
|
137
71
|
|
138
|
-
|
139
|
-
{
|
140
|
-
// https://github.com/sass/sass/issues/2229
|
141
|
-
if ((has_ns_ == r.has_ns_) ||
|
142
|
-
(has_ns_ && ns_.empty()) ||
|
143
|
-
(r.has_ns_ && r.ns_.empty())
|
144
|
-
) {
|
145
|
-
if (ns_.empty() && r.ns() == "*") return false;
|
146
|
-
else if (r.ns().empty() && ns() == "*") return false;
|
147
|
-
else return ns() == r.ns();
|
148
|
-
}
|
149
|
-
return false;
|
150
|
-
}
|
151
|
-
|
152
|
-
bool Compound_Selector::operator< (const Compound_Selector& rhs) const
|
153
|
-
{
|
154
|
-
size_t L = std::min(length(), rhs.length());
|
155
|
-
for (size_t i = 0; i < L; ++i)
|
156
|
-
{
|
157
|
-
Simple_Selector_Obj l = (*this)[i];
|
158
|
-
Simple_Selector_Obj r = rhs[i];
|
159
|
-
if (!l && !r) return false;
|
160
|
-
else if (!r) return false;
|
161
|
-
else if (!l) return true;
|
162
|
-
else if (*l != *r)
|
163
|
-
{ return *l < *r; }
|
164
|
-
}
|
165
|
-
// just compare the length now
|
166
|
-
return length() < rhs.length();
|
167
|
-
}
|
168
|
-
|
169
|
-
bool Compound_Selector::has_parent_ref() const
|
170
|
-
{
|
171
|
-
for (Simple_Selector_Obj s : *this) {
|
172
|
-
if (s && s->has_parent_ref()) return true;
|
173
|
-
}
|
174
|
-
return false;
|
175
|
-
}
|
176
|
-
|
177
|
-
bool Compound_Selector::has_real_parent_ref() const
|
178
|
-
{
|
179
|
-
for (Simple_Selector_Obj s : *this) {
|
180
|
-
if (s && s->has_real_parent_ref()) return true;
|
181
|
-
}
|
182
|
-
return false;
|
183
|
-
}
|
184
|
-
|
185
|
-
bool Complex_Selector::has_parent_ref() const
|
186
|
-
{
|
187
|
-
return (head() && head()->has_parent_ref()) ||
|
188
|
-
(tail() && tail()->has_parent_ref());
|
189
|
-
}
|
190
|
-
|
191
|
-
bool Complex_Selector::has_real_parent_ref() const
|
192
|
-
{
|
193
|
-
return (head() && head()->has_real_parent_ref()) ||
|
194
|
-
(tail() && tail()->has_real_parent_ref());
|
195
|
-
}
|
196
|
-
|
197
|
-
bool Complex_Selector::operator< (const Complex_Selector& rhs) const
|
198
|
-
{
|
199
|
-
// const iterators for tails
|
200
|
-
Complex_Selector_Ptr_Const l = this;
|
201
|
-
Complex_Selector_Ptr_Const r = &rhs;
|
202
|
-
Compound_Selector_Ptr l_h = NULL;
|
203
|
-
Compound_Selector_Ptr r_h = NULL;
|
204
|
-
if (l) l_h = l->head();
|
205
|
-
if (r) r_h = r->head();
|
206
|
-
// process all tails
|
207
|
-
while (true)
|
208
|
-
{
|
209
|
-
#ifdef DEBUG
|
210
|
-
// skip empty ancestor first
|
211
|
-
if (l && l->is_empty_ancestor())
|
212
|
-
{
|
213
|
-
l_h = NULL;
|
214
|
-
l = l->tail();
|
215
|
-
if(l) l_h = l->head();
|
216
|
-
continue;
|
217
|
-
}
|
218
|
-
// skip empty ancestor first
|
219
|
-
if (r && r->is_empty_ancestor())
|
220
|
-
{
|
221
|
-
r_h = NULL;
|
222
|
-
r = r->tail();
|
223
|
-
if (r) r_h = r->head();
|
224
|
-
continue;
|
225
|
-
}
|
226
|
-
#endif
|
227
|
-
// check for valid selectors
|
228
|
-
if (!l) return !!r;
|
229
|
-
if (!r) return false;
|
230
|
-
// both are null
|
231
|
-
else if (!l_h && !r_h)
|
232
|
-
{
|
233
|
-
// check combinator after heads
|
234
|
-
if (l->combinator() != r->combinator())
|
235
|
-
{ return l->combinator() < r->combinator(); }
|
236
|
-
// advance to next tails
|
237
|
-
l = l->tail();
|
238
|
-
r = r->tail();
|
239
|
-
// fetch the next headers
|
240
|
-
l_h = NULL; r_h = NULL;
|
241
|
-
if (l) l_h = l->head();
|
242
|
-
if (r) r_h = r->head();
|
243
|
-
}
|
244
|
-
// one side is null
|
245
|
-
else if (!r_h) return true;
|
246
|
-
else if (!l_h) return false;
|
247
|
-
// heads ok and equal
|
248
|
-
else if (*l_h == *r_h)
|
249
|
-
{
|
250
|
-
// check combinator after heads
|
251
|
-
if (l->combinator() != r->combinator())
|
252
|
-
{ return l->combinator() < r->combinator(); }
|
253
|
-
// advance to next tails
|
254
|
-
l = l->tail();
|
255
|
-
r = r->tail();
|
256
|
-
// fetch the next headers
|
257
|
-
l_h = NULL; r_h = NULL;
|
258
|
-
if (l) l_h = l->head();
|
259
|
-
if (r) r_h = r->head();
|
260
|
-
}
|
261
|
-
// heads are not equal
|
262
|
-
else return *l_h < *r_h;
|
263
|
-
}
|
264
|
-
}
|
265
|
-
|
266
|
-
bool Complex_Selector::operator== (const Complex_Selector& rhs) const
|
267
|
-
{
|
268
|
-
// const iterators for tails
|
269
|
-
Complex_Selector_Ptr_Const l = this;
|
270
|
-
Complex_Selector_Ptr_Const r = &rhs;
|
271
|
-
Compound_Selector_Ptr l_h = NULL;
|
272
|
-
Compound_Selector_Ptr r_h = NULL;
|
273
|
-
if (l) l_h = l->head();
|
274
|
-
if (r) r_h = r->head();
|
275
|
-
// process all tails
|
276
|
-
while (true)
|
277
|
-
{
|
278
|
-
#ifdef DEBUG
|
279
|
-
// skip empty ancestor first
|
280
|
-
if (l && l->is_empty_ancestor())
|
281
|
-
{
|
282
|
-
l_h = NULL;
|
283
|
-
l = l->tail();
|
284
|
-
if (l) l_h = l->head();
|
285
|
-
continue;
|
286
|
-
}
|
287
|
-
// skip empty ancestor first
|
288
|
-
if (r && r->is_empty_ancestor())
|
289
|
-
{
|
290
|
-
r_h = NULL;
|
291
|
-
r = r->tail();
|
292
|
-
if (r) r_h = r->head();
|
293
|
-
continue;
|
294
|
-
}
|
295
|
-
#endif
|
296
|
-
// check the pointers
|
297
|
-
if (!r) return !l;
|
298
|
-
if (!l) return !r;
|
299
|
-
// both are null
|
300
|
-
if (!l_h && !r_h)
|
301
|
-
{
|
302
|
-
// check combinator after heads
|
303
|
-
if (l->combinator() != r->combinator())
|
304
|
-
{ return l->combinator() < r->combinator(); }
|
305
|
-
// advance to next tails
|
306
|
-
l = l->tail();
|
307
|
-
r = r->tail();
|
308
|
-
// fetch the next heads
|
309
|
-
l_h = NULL; r_h = NULL;
|
310
|
-
if (l) l_h = l->head();
|
311
|
-
if (r) r_h = r->head();
|
312
|
-
}
|
313
|
-
// equals if other head is empty
|
314
|
-
else if ((!l_h && !r_h) ||
|
315
|
-
(!l_h && r_h->empty()) ||
|
316
|
-
(!r_h && l_h->empty()) ||
|
317
|
-
(l_h && r_h && *l_h == *r_h))
|
318
|
-
{
|
319
|
-
// check combinator after heads
|
320
|
-
if (l->combinator() != r->combinator())
|
321
|
-
{ return l->combinator() == r->combinator(); }
|
322
|
-
// advance to next tails
|
323
|
-
l = l->tail();
|
324
|
-
r = r->tail();
|
325
|
-
// fetch the next heads
|
326
|
-
l_h = NULL; r_h = NULL;
|
327
|
-
if (l) l_h = l->head();
|
328
|
-
if (r) r_h = r->head();
|
329
|
-
}
|
330
|
-
// abort
|
331
|
-
else break;
|
332
|
-
}
|
333
|
-
// unreachable
|
334
|
-
return false;
|
335
|
-
}
|
336
|
-
|
337
|
-
Compound_Selector_Ptr Compound_Selector::unify_with(Compound_Selector_Ptr rhs)
|
338
|
-
{
|
339
|
-
if (empty()) return rhs;
|
340
|
-
Compound_Selector_Obj unified = SASS_MEMORY_COPY(rhs);
|
341
|
-
for (size_t i = 0, L = length(); i < L; ++i)
|
342
|
-
{
|
343
|
-
if (unified.isNull()) break;
|
344
|
-
unified = at(i)->unify_with(unified);
|
345
|
-
}
|
346
|
-
return unified.detach();
|
347
|
-
}
|
348
|
-
|
349
|
-
bool Complex_Selector::operator== (const Selector& rhs) const
|
350
|
-
{
|
351
|
-
if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this == *sl;
|
352
|
-
if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this == *sp;
|
353
|
-
if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
|
354
|
-
if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
|
355
|
-
throw std::runtime_error("invalid selector base classes to compare");
|
356
|
-
}
|
357
|
-
|
358
|
-
|
359
|
-
bool Complex_Selector::operator< (const Selector& rhs) const
|
360
|
-
{
|
361
|
-
if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this < *sl;
|
362
|
-
if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this < *sp;
|
363
|
-
if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
|
364
|
-
if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
|
365
|
-
throw std::runtime_error("invalid selector base classes to compare");
|
366
|
-
}
|
367
|
-
|
368
|
-
bool Compound_Selector::operator== (const Selector& rhs) const
|
369
|
-
{
|
370
|
-
if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this == *sl;
|
371
|
-
if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this == *sp;
|
372
|
-
if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
|
373
|
-
if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
|
374
|
-
throw std::runtime_error("invalid selector base classes to compare");
|
375
|
-
}
|
376
|
-
|
377
|
-
bool Compound_Selector::operator< (const Selector& rhs) const
|
378
|
-
{
|
379
|
-
if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this < *sl;
|
380
|
-
if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this < *sp;
|
381
|
-
if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
|
382
|
-
if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
|
383
|
-
throw std::runtime_error("invalid selector base classes to compare");
|
384
|
-
}
|
385
|
-
|
386
|
-
bool Selector_Schema::operator== (const Selector& rhs) const
|
387
|
-
{
|
388
|
-
if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this == *sl;
|
389
|
-
if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this == *sp;
|
390
|
-
if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
|
391
|
-
if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
|
392
|
-
throw std::runtime_error("invalid selector base classes to compare");
|
393
|
-
}
|
394
|
-
|
395
|
-
bool Selector_Schema::operator< (const Selector& rhs) const
|
396
|
-
{
|
397
|
-
if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this < *sl;
|
398
|
-
if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this < *sp;
|
399
|
-
if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
|
400
|
-
if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
|
401
|
-
throw std::runtime_error("invalid selector base classes to compare");
|
402
|
-
}
|
403
|
-
|
404
|
-
bool Simple_Selector::operator== (const Selector& rhs) const
|
405
|
-
{
|
406
|
-
if (Simple_Selector_Ptr_Const sp = Cast<Simple_Selector>(&rhs)) return *this == *sp;
|
407
|
-
return false;
|
408
|
-
}
|
409
|
-
|
410
|
-
bool Simple_Selector::operator< (const Selector& rhs) const
|
411
|
-
{
|
412
|
-
if (Simple_Selector_Ptr_Const sp = Cast<Simple_Selector>(&rhs)) return *this < *sp;
|
413
|
-
return false;
|
414
|
-
}
|
415
|
-
|
416
|
-
bool Simple_Selector::operator== (const Simple_Selector& rhs) const
|
417
|
-
{
|
418
|
-
// solve the double dispatch problem by using RTTI information via dynamic cast
|
419
|
-
if (const Pseudo_Selector* lhs = Cast<Pseudo_Selector>(this)) {return *lhs == rhs; }
|
420
|
-
else if (const Wrapped_Selector* lhs = Cast<Wrapped_Selector>(this)) {return *lhs == rhs; }
|
421
|
-
else if (const Element_Selector* lhs = Cast<Element_Selector>(this)) {return *lhs == rhs; }
|
422
|
-
else if (const Attribute_Selector* lhs = Cast<Attribute_Selector>(this)) {return *lhs == rhs; }
|
423
|
-
else if (name_ == rhs.name_)
|
424
|
-
{ return is_ns_eq(rhs); }
|
425
|
-
else return false;
|
426
|
-
}
|
427
|
-
|
428
|
-
bool Simple_Selector::operator< (const Simple_Selector& rhs) const
|
429
|
-
{
|
430
|
-
// solve the double dispatch problem by using RTTI information via dynamic cast
|
431
|
-
if (const Pseudo_Selector* lhs = Cast<Pseudo_Selector>(this)) {return *lhs < rhs; }
|
432
|
-
else if (const Wrapped_Selector* lhs = Cast<Wrapped_Selector>(this)) {return *lhs < rhs; }
|
433
|
-
else if (const Element_Selector* lhs = Cast<Element_Selector>(this)) {return *lhs < rhs; }
|
434
|
-
else if (const Attribute_Selector* lhs = Cast<Attribute_Selector>(this)) {return *lhs < rhs; }
|
435
|
-
if (is_ns_eq(rhs))
|
436
|
-
{ return name_ < rhs.name_; }
|
437
|
-
return ns_ < rhs.ns_;
|
438
|
-
}
|
439
|
-
|
440
|
-
bool Selector_List::operator== (const Selector& rhs) const
|
441
|
-
{
|
442
|
-
// solve the double dispatch problem by using RTTI information via dynamic cast
|
443
|
-
if (Selector_List_Ptr_Const sl = Cast<Selector_List>(&rhs)) { return *this == *sl; }
|
444
|
-
else if (Complex_Selector_Ptr_Const cpx = Cast<Complex_Selector>(&rhs)) { return *this == *cpx; }
|
445
|
-
else if (Compound_Selector_Ptr_Const cpd = Cast<Compound_Selector>(&rhs)) { return *this == *cpd; }
|
446
|
-
// no compare method
|
447
|
-
return this == &rhs;
|
448
|
-
}
|
449
|
-
|
450
|
-
// Selector lists can be compared to comma lists
|
451
|
-
bool Selector_List::operator== (const Expression& rhs) const
|
452
|
-
{
|
453
|
-
// solve the double dispatch problem by using RTTI information via dynamic cast
|
454
|
-
if (List_Ptr_Const ls = Cast<List>(&rhs)) { return *ls == *this; }
|
455
|
-
if (Selector_Ptr_Const ls = Cast<Selector>(&rhs)) { return *this == *ls; }
|
456
|
-
// compare invalid (maybe we should error?)
|
457
|
-
return false;
|
458
|
-
}
|
459
|
-
|
460
|
-
bool Selector_List::operator== (const Selector_List& rhs) const
|
461
|
-
{
|
462
|
-
// for array access
|
463
|
-
size_t i = 0, n = 0;
|
464
|
-
size_t iL = length();
|
465
|
-
size_t nL = rhs.length();
|
466
|
-
// create temporary vectors and sort them
|
467
|
-
std::vector<Complex_Selector_Obj> l_lst = this->elements();
|
468
|
-
std::vector<Complex_Selector_Obj> r_lst = rhs.elements();
|
469
|
-
std::sort(l_lst.begin(), l_lst.end(), OrderNodes());
|
470
|
-
std::sort(r_lst.begin(), r_lst.end(), OrderNodes());
|
471
|
-
// process loop
|
472
|
-
while (true)
|
473
|
-
{
|
474
|
-
// first check for valid index
|
475
|
-
if (i == iL) return iL == nL;
|
476
|
-
else if (n == nL) return iL == nL;
|
477
|
-
// the access the vector items
|
478
|
-
Complex_Selector_Obj l = l_lst[i];
|
479
|
-
Complex_Selector_Obj r = r_lst[n];
|
480
|
-
// skip nulls
|
481
|
-
if (!l) ++i;
|
482
|
-
else if (!r) ++n;
|
483
|
-
// do the check
|
484
|
-
else if (*l != *r)
|
485
|
-
{ return false; }
|
486
|
-
// advance
|
487
|
-
++i; ++n;
|
488
|
-
}
|
489
|
-
// there is no break?!
|
490
|
-
}
|
491
|
-
|
492
|
-
bool Selector_List::operator< (const Selector& rhs) const
|
493
|
-
{
|
494
|
-
if (Selector_List_Ptr_Const sp = Cast<Selector_List>(&rhs)) return *this < *sp;
|
495
|
-
return false;
|
496
|
-
}
|
497
|
-
|
498
|
-
bool Selector_List::operator< (const Selector_List& rhs) const
|
499
|
-
{
|
500
|
-
size_t l = rhs.length();
|
501
|
-
if (length() < l) l = length();
|
502
|
-
for (size_t i = 0; i < l; i ++) {
|
503
|
-
if (*at(i) < *rhs.at(i)) return true;
|
504
|
-
}
|
505
|
-
return false;
|
506
|
-
}
|
507
|
-
|
508
|
-
Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs)
|
509
|
-
{
|
510
|
-
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
511
|
-
{ if (to_string() == rhs->at(i)->to_string()) return rhs; }
|
512
|
-
|
513
|
-
// check for pseudo elements because they are always last
|
514
|
-
size_t i, L;
|
515
|
-
bool found = false;
|
516
|
-
if (typeid(*this) == typeid(Pseudo_Selector) || typeid(*this) == typeid(Wrapped_Selector) || typeid(*this) == typeid(Attribute_Selector))
|
517
|
-
{
|
518
|
-
for (i = 0, L = rhs->length(); i < L; ++i)
|
519
|
-
{
|
520
|
-
if ((Cast<Pseudo_Selector>((*rhs)[i]) || Cast<Wrapped_Selector>((*rhs)[i]) || Cast<Attribute_Selector>((*rhs)[i])) && (*rhs)[L-1]->is_pseudo_element())
|
521
|
-
{ found = true; break; }
|
522
|
-
}
|
523
|
-
}
|
524
|
-
else
|
525
|
-
{
|
526
|
-
for (i = 0, L = rhs->length(); i < L; ++i)
|
527
|
-
{
|
528
|
-
if (Cast<Pseudo_Selector>((*rhs)[i]) || Cast<Wrapped_Selector>((*rhs)[i]) || Cast<Attribute_Selector>((*rhs)[i]))
|
529
|
-
{ found = true; break; }
|
530
|
-
}
|
531
|
-
}
|
532
|
-
if (!found)
|
533
|
-
{
|
534
|
-
rhs->append(this);
|
535
|
-
} else {
|
536
|
-
rhs->elements().insert(rhs->elements().begin() + i, this);
|
537
|
-
}
|
538
|
-
return rhs;
|
539
|
-
}
|
540
|
-
|
541
|
-
Simple_Selector_Ptr Element_Selector::unify_with(Simple_Selector_Ptr rhs)
|
542
|
-
{
|
543
|
-
// check if ns can be extended
|
544
|
-
// true for no ns or universal
|
545
|
-
if (has_universal_ns())
|
546
|
-
{
|
547
|
-
// but dont extend with universal
|
548
|
-
// true for valid ns and universal
|
549
|
-
if (!rhs->is_universal_ns())
|
550
|
-
{
|
551
|
-
// overwrite the name if star is given as name
|
552
|
-
if (this->name() == "*") { this->name(rhs->name()); }
|
553
|
-
// now overwrite the namespace name and flag
|
554
|
-
this->ns(rhs->ns()); this->has_ns(rhs->has_ns());
|
555
|
-
// return copy
|
556
|
-
return this;
|
557
|
-
}
|
558
|
-
}
|
559
|
-
// namespace may changed, check the name now
|
560
|
-
// overwrite star (but not with another star)
|
561
|
-
if (name() == "*" && rhs->name() != "*")
|
562
|
-
{
|
563
|
-
// simply set the new name
|
564
|
-
this->name(rhs->name());
|
565
|
-
// return copy
|
566
|
-
return this;
|
567
|
-
}
|
568
|
-
// return original
|
569
|
-
return this;
|
570
|
-
}
|
571
|
-
|
572
|
-
Compound_Selector_Ptr Element_Selector::unify_with(Compound_Selector_Ptr rhs)
|
573
|
-
{
|
574
|
-
// TODO: handle namespaces
|
575
|
-
|
576
|
-
// if the rhs is empty, just return a copy of this
|
577
|
-
if (rhs->length() == 0) {
|
578
|
-
rhs->append(this);
|
579
|
-
return rhs;
|
580
|
-
}
|
581
|
-
|
582
|
-
Simple_Selector_Ptr rhs_0 = rhs->at(0);
|
583
|
-
// otherwise, this is a tag name
|
584
|
-
if (name() == "*")
|
585
|
-
{
|
586
|
-
if (typeid(*rhs_0) == typeid(Element_Selector))
|
587
|
-
{
|
588
|
-
// if rhs is universal, just return this tagname + rhs's qualifiers
|
589
|
-
Element_Selector_Ptr ts = Cast<Element_Selector>(rhs_0);
|
590
|
-
rhs->at(0) = this->unify_with(ts);
|
591
|
-
return rhs;
|
592
|
-
}
|
593
|
-
else if (Cast<Class_Selector>(rhs_0) || Cast<Id_Selector>(rhs_0)) {
|
594
|
-
// qualifier is `.class`, so we can prefix with `ns|*.class`
|
595
|
-
if (has_ns() && !rhs_0->has_ns()) {
|
596
|
-
if (ns() != "*") rhs->elements().insert(rhs->begin(), this);
|
597
|
-
}
|
598
|
-
return rhs;
|
599
|
-
}
|
600
|
-
|
601
|
-
|
602
|
-
return rhs;
|
603
|
-
}
|
604
|
-
|
605
|
-
if (typeid(*rhs_0) == typeid(Element_Selector))
|
606
|
-
{
|
607
|
-
// if rhs is universal, just return this tagname + rhs's qualifiers
|
608
|
-
if (rhs_0->name() != "*" && rhs_0->ns() != "*" && rhs_0->name() != name()) return 0;
|
609
|
-
// otherwise create new compound and unify first simple selector
|
610
|
-
rhs->at(0) = this->unify_with(rhs_0);
|
611
|
-
return rhs;
|
612
|
-
|
613
|
-
}
|
614
|
-
// else it's a tag name and a bunch of qualifiers -- just append them
|
615
|
-
if (name() != "*") rhs->elements().insert(rhs->begin(), this);
|
616
|
-
return rhs;
|
617
|
-
}
|
618
|
-
|
619
|
-
Compound_Selector_Ptr Class_Selector::unify_with(Compound_Selector_Ptr rhs)
|
620
|
-
{
|
621
|
-
rhs->has_line_break(has_line_break());
|
622
|
-
return Simple_Selector::unify_with(rhs);
|
623
|
-
}
|
624
|
-
|
625
|
-
Compound_Selector_Ptr Id_Selector::unify_with(Compound_Selector_Ptr rhs)
|
626
|
-
{
|
627
|
-
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
628
|
-
{
|
629
|
-
if (Id_Selector_Ptr sel = Cast<Id_Selector>(rhs->at(i))) {
|
630
|
-
if (sel->name() != name()) return 0;
|
631
|
-
}
|
632
|
-
}
|
633
|
-
rhs->has_line_break(has_line_break());
|
634
|
-
return Simple_Selector::unify_with(rhs);
|
635
|
-
}
|
636
|
-
|
637
|
-
Compound_Selector_Ptr Pseudo_Selector::unify_with(Compound_Selector_Ptr rhs)
|
638
|
-
{
|
639
|
-
if (is_pseudo_element())
|
640
|
-
{
|
641
|
-
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
642
|
-
{
|
643
|
-
if (Pseudo_Selector_Ptr sel = Cast<Pseudo_Selector>(rhs->at(i))) {
|
644
|
-
if (sel->is_pseudo_element() && sel->name() != name()) return 0;
|
645
|
-
}
|
646
|
-
}
|
647
|
-
}
|
648
|
-
return Simple_Selector::unify_with(rhs);
|
649
|
-
}
|
650
|
-
|
651
|
-
bool Attribute_Selector::operator< (const Attribute_Selector& rhs) const
|
652
|
-
{
|
653
|
-
if (is_ns_eq(rhs)) {
|
654
|
-
if (name() == rhs.name()) {
|
655
|
-
if (matcher() == rhs.matcher()) {
|
656
|
-
bool no_lhs_val = value().isNull();
|
657
|
-
bool no_rhs_val = rhs.value().isNull();
|
658
|
-
if (no_lhs_val && no_rhs_val) return false; // equal
|
659
|
-
else if (no_lhs_val) return true; // lhs is null
|
660
|
-
else if (no_rhs_val) return false; // rhs is null
|
661
|
-
return *value() < *rhs.value(); // both are given
|
662
|
-
} else { return matcher() < rhs.matcher(); }
|
663
|
-
} else { return name() < rhs.name(); }
|
664
|
-
} else { return ns() < rhs.ns(); }
|
665
|
-
}
|
666
|
-
|
667
|
-
bool Attribute_Selector::operator< (const Simple_Selector& rhs) const
|
668
|
-
{
|
669
|
-
if (Attribute_Selector_Ptr_Const w = Cast<Attribute_Selector>(&rhs))
|
670
|
-
{
|
671
|
-
return *this < *w;
|
672
|
-
}
|
673
|
-
if (is_ns_eq(rhs))
|
674
|
-
{ return name() < rhs.name(); }
|
675
|
-
return ns() < rhs.ns();
|
676
|
-
}
|
677
|
-
|
678
|
-
bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const
|
679
|
-
{
|
680
|
-
// get optional value state
|
681
|
-
bool no_lhs_val = value().isNull();
|
682
|
-
bool no_rhs_val = rhs.value().isNull();
|
683
|
-
// both are null, therefore equal
|
684
|
-
if (no_lhs_val && no_rhs_val) {
|
685
|
-
return (name() == rhs.name())
|
686
|
-
&& (matcher() == rhs.matcher())
|
687
|
-
&& (is_ns_eq(rhs));
|
688
|
-
}
|
689
|
-
// both are defined, evaluate
|
690
|
-
if (no_lhs_val == no_rhs_val) {
|
691
|
-
return (name() == rhs.name())
|
692
|
-
&& (matcher() == rhs.matcher())
|
693
|
-
&& (is_ns_eq(rhs))
|
694
|
-
&& (*value() == *rhs.value());
|
695
|
-
}
|
696
|
-
// not equal
|
697
|
-
return false;
|
698
|
-
|
699
|
-
}
|
700
|
-
|
701
|
-
bool Attribute_Selector::operator== (const Simple_Selector& rhs) const
|
702
|
-
{
|
703
|
-
if (Attribute_Selector_Ptr_Const w = Cast<Attribute_Selector>(&rhs))
|
704
|
-
{
|
705
|
-
return is_ns_eq(rhs) &&
|
706
|
-
name() == rhs.name() &&
|
707
|
-
*this == *w;
|
708
|
-
}
|
709
|
-
return false;
|
710
|
-
}
|
711
|
-
|
712
|
-
bool Element_Selector::operator< (const Element_Selector& rhs) const
|
713
|
-
{
|
714
|
-
if (is_ns_eq(rhs))
|
715
|
-
{ return name() < rhs.name(); }
|
716
|
-
return ns() < rhs.ns();
|
717
|
-
}
|
718
|
-
|
719
|
-
bool Element_Selector::operator< (const Simple_Selector& rhs) const
|
720
|
-
{
|
721
|
-
if (Element_Selector_Ptr_Const w = Cast<Element_Selector>(&rhs))
|
722
|
-
{
|
723
|
-
return *this < *w;
|
724
|
-
}
|
725
|
-
if (is_ns_eq(rhs))
|
726
|
-
{ return name() < rhs.name(); }
|
727
|
-
return ns() < rhs.ns();
|
728
|
-
}
|
729
|
-
|
730
|
-
bool Element_Selector::operator== (const Element_Selector& rhs) const
|
731
|
-
{
|
732
|
-
return is_ns_eq(rhs) &&
|
733
|
-
name() == rhs.name();
|
734
|
-
}
|
735
|
-
|
736
|
-
bool Element_Selector::operator== (const Simple_Selector& rhs) const
|
737
|
-
{
|
738
|
-
if (Element_Selector_Ptr_Const w = Cast<Element_Selector>(&rhs))
|
739
|
-
{
|
740
|
-
return is_ns_eq(rhs) &&
|
741
|
-
name() == rhs.name() &&
|
742
|
-
*this == *w;
|
743
|
-
}
|
744
|
-
return false;
|
745
|
-
}
|
746
|
-
|
747
|
-
bool Pseudo_Selector::operator== (const Pseudo_Selector& rhs) const
|
748
|
-
{
|
749
|
-
if (is_ns_eq(rhs) && name() == rhs.name())
|
750
|
-
{
|
751
|
-
String_Obj lhs_ex = expression();
|
752
|
-
String_Obj rhs_ex = rhs.expression();
|
753
|
-
if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex;
|
754
|
-
else return lhs_ex.ptr() == rhs_ex.ptr();
|
755
|
-
}
|
756
|
-
else return false;
|
757
|
-
}
|
758
|
-
|
759
|
-
bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const
|
760
|
-
{
|
761
|
-
if (Pseudo_Selector_Ptr_Const w = Cast<Pseudo_Selector>(&rhs))
|
762
|
-
{
|
763
|
-
return *this == *w;
|
764
|
-
}
|
765
|
-
return is_ns_eq(rhs) &&
|
766
|
-
name() == rhs.name();
|
767
|
-
}
|
768
|
-
|
769
|
-
bool Pseudo_Selector::operator< (const Pseudo_Selector& rhs) const
|
770
|
-
{
|
771
|
-
if (is_ns_eq(rhs) && name() == rhs.name())
|
772
|
-
{
|
773
|
-
String_Obj lhs_ex = expression();
|
774
|
-
String_Obj rhs_ex = rhs.expression();
|
775
|
-
if (rhs_ex && lhs_ex) return *lhs_ex < *rhs_ex;
|
776
|
-
else return lhs_ex.ptr() < rhs_ex.ptr();
|
777
|
-
}
|
778
|
-
if (is_ns_eq(rhs))
|
779
|
-
{ return name() < rhs.name(); }
|
780
|
-
return ns() < rhs.ns();
|
781
|
-
}
|
782
|
-
|
783
|
-
bool Pseudo_Selector::operator< (const Simple_Selector& rhs) const
|
784
|
-
{
|
785
|
-
if (Pseudo_Selector_Ptr_Const w = Cast<Pseudo_Selector>(&rhs))
|
786
|
-
{
|
787
|
-
return *this < *w;
|
788
|
-
}
|
789
|
-
if (is_ns_eq(rhs))
|
790
|
-
{ return name() < rhs.name(); }
|
791
|
-
return ns() < rhs.ns();
|
792
|
-
}
|
793
|
-
|
794
|
-
bool Wrapped_Selector::operator== (const Wrapped_Selector& rhs) const
|
795
|
-
{
|
796
|
-
if (is_ns_eq(rhs) && name() == rhs.name())
|
797
|
-
{ return *(selector()) == *(rhs.selector()); }
|
798
|
-
else return false;
|
799
|
-
}
|
800
|
-
|
801
|
-
bool Wrapped_Selector::operator== (const Simple_Selector& rhs) const
|
802
|
-
{
|
803
|
-
if (Wrapped_Selector_Ptr_Const w = Cast<Wrapped_Selector>(&rhs))
|
804
|
-
{
|
805
|
-
return *this == *w;
|
806
|
-
}
|
807
|
-
return is_ns_eq(rhs) &&
|
808
|
-
name() == rhs.name();
|
809
|
-
}
|
810
|
-
|
811
|
-
bool Wrapped_Selector::operator< (const Wrapped_Selector& rhs) const
|
812
|
-
{
|
813
|
-
if (is_ns_eq(rhs) && name() == rhs.name())
|
814
|
-
{ return *(selector()) < *(rhs.selector()); }
|
815
|
-
if (is_ns_eq(rhs))
|
816
|
-
{ return name() < rhs.name(); }
|
817
|
-
return ns() < rhs.ns();
|
818
|
-
}
|
819
|
-
|
820
|
-
bool Wrapped_Selector::operator< (const Simple_Selector& rhs) const
|
821
|
-
{
|
822
|
-
if (Wrapped_Selector_Ptr_Const w = Cast<Wrapped_Selector>(&rhs))
|
823
|
-
{
|
824
|
-
return *this < *w;
|
825
|
-
}
|
826
|
-
if (is_ns_eq(rhs))
|
827
|
-
{ return name() < rhs.name(); }
|
828
|
-
return ns() < rhs.ns();
|
829
|
-
}
|
830
|
-
|
831
|
-
bool Wrapped_Selector::is_superselector_of(Wrapped_Selector_Obj sub)
|
832
|
-
{
|
833
|
-
if (this->name() != sub->name()) return false;
|
834
|
-
if (this->name() == ":current") return false;
|
835
|
-
if (Selector_List_Obj rhs_list = Cast<Selector_List>(sub->selector())) {
|
836
|
-
if (Selector_List_Obj lhs_list = Cast<Selector_List>(selector())) {
|
837
|
-
return lhs_list->is_superselector_of(rhs_list);
|
838
|
-
}
|
839
|
-
}
|
840
|
-
coreError("is_superselector expected a Selector_List", sub->pstate());
|
841
|
-
return false;
|
842
|
-
}
|
843
|
-
|
844
|
-
bool Compound_Selector::is_superselector_of(Selector_List_Obj rhs, std::string wrapped)
|
845
|
-
{
|
846
|
-
for (Complex_Selector_Obj item : rhs->elements()) {
|
847
|
-
if (is_superselector_of(item, wrapped)) return true;
|
848
|
-
}
|
849
|
-
return false;
|
850
|
-
}
|
851
|
-
|
852
|
-
bool Compound_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapped)
|
853
|
-
{
|
854
|
-
if (rhs->head()) return is_superselector_of(rhs->head(), wrapped);
|
855
|
-
return false;
|
856
|
-
}
|
857
|
-
|
858
|
-
bool Compound_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping)
|
859
|
-
{
|
860
|
-
Compound_Selector_Ptr lhs = this;
|
861
|
-
Simple_Selector_Ptr lbase = lhs->base();
|
862
|
-
Simple_Selector_Ptr rbase = rhs->base();
|
863
|
-
|
864
|
-
// Check if pseudo-elements are the same between the selectors
|
865
|
-
|
866
|
-
std::set<std::string> lpsuedoset, rpsuedoset;
|
867
|
-
for (size_t i = 0, L = length(); i < L; ++i)
|
868
|
-
{
|
869
|
-
if ((*this)[i]->is_pseudo_element()) {
|
870
|
-
std::string pseudo((*this)[i]->to_string());
|
871
|
-
pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
|
872
|
-
lpsuedoset.insert(pseudo);
|
873
|
-
}
|
874
|
-
}
|
875
|
-
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
876
|
-
{
|
877
|
-
if ((*rhs)[i]->is_pseudo_element()) {
|
878
|
-
std::string pseudo((*rhs)[i]->to_string());
|
879
|
-
pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
|
880
|
-
rpsuedoset.insert(pseudo);
|
881
|
-
}
|
882
|
-
}
|
883
|
-
if (lpsuedoset != rpsuedoset) {
|
884
|
-
return false;
|
885
|
-
}
|
886
|
-
|
887
|
-
// would like to replace this without stringification
|
888
|
-
// https://github.com/sass/sass/issues/2229
|
889
|
-
// SimpleSelectorSet lset, rset;
|
890
|
-
std::set<std::string> lset, rset;
|
891
|
-
|
892
|
-
if (lbase && rbase)
|
893
|
-
{
|
894
|
-
if (lbase->to_string() == rbase->to_string()) {
|
895
|
-
for (size_t i = 1, L = length(); i < L; ++i)
|
896
|
-
{ lset.insert((*this)[i]->to_string()); }
|
897
|
-
for (size_t i = 1, L = rhs->length(); i < L; ++i)
|
898
|
-
{ rset.insert((*rhs)[i]->to_string()); }
|
899
|
-
return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
|
900
|
-
}
|
901
|
-
return false;
|
902
|
-
}
|
903
|
-
|
904
|
-
for (size_t i = 0, iL = length(); i < iL; ++i)
|
905
|
-
{
|
906
|
-
Selector_Obj wlhs = (*this)[i];
|
907
|
-
// very special case for wrapped matches selector
|
908
|
-
if (Wrapped_Selector_Obj wrapped = Cast<Wrapped_Selector>(wlhs)) {
|
909
|
-
if (wrapped->name() == ":not") {
|
910
|
-
if (Selector_List_Obj not_list = Cast<Selector_List>(wrapped->selector())) {
|
911
|
-
if (not_list->is_superselector_of(rhs, wrapped->name())) return false;
|
912
|
-
} else {
|
913
|
-
throw std::runtime_error("wrapped not selector is not a list");
|
914
|
-
}
|
915
|
-
}
|
916
|
-
if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
|
917
|
-
wlhs = wrapped->selector();
|
918
|
-
if (Selector_List_Obj list = Cast<Selector_List>(wrapped->selector())) {
|
919
|
-
if (Compound_Selector_Obj comp = Cast<Compound_Selector>(rhs)) {
|
920
|
-
if (!wrapping.empty() && wrapping != wrapped->name()) return false;
|
921
|
-
if (wrapping.empty() || wrapping != wrapped->name()) {;
|
922
|
-
if (list->is_superselector_of(comp, wrapped->name())) return true;
|
923
|
-
}
|
924
|
-
}
|
925
|
-
}
|
926
|
-
}
|
927
|
-
Simple_Selector_Ptr rhs_sel = NULL;
|
928
|
-
if (rhs->elements().size() > i) rhs_sel = (*rhs)[i];
|
929
|
-
if (Wrapped_Selector_Ptr wrapped_r = Cast<Wrapped_Selector>(rhs_sel)) {
|
930
|
-
if (wrapped->name() == wrapped_r->name()) {
|
931
|
-
if (wrapped->is_superselector_of(wrapped_r)) {
|
932
|
-
continue;
|
933
|
-
}}
|
934
|
-
}
|
935
|
-
}
|
936
|
-
// match from here on as strings
|
937
|
-
lset.insert(wlhs->to_string());
|
938
|
-
}
|
939
|
-
|
940
|
-
for (size_t n = 0, nL = rhs->length(); n < nL; ++n)
|
941
|
-
{
|
942
|
-
Selector_Obj r = (*rhs)[n];
|
943
|
-
if (Wrapped_Selector_Obj wrapped = Cast<Wrapped_Selector>(r)) {
|
944
|
-
if (wrapped->name() == ":not") {
|
945
|
-
if (Selector_List_Obj ls = Cast<Selector_List>(wrapped->selector())) {
|
946
|
-
ls->remove_parent_selectors();
|
947
|
-
if (is_superselector_of(ls, wrapped->name())) return false;
|
948
|
-
}
|
949
|
-
}
|
950
|
-
if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
|
951
|
-
if (!wrapping.empty()) {
|
952
|
-
if (wrapping != wrapped->name()) return false;
|
953
|
-
}
|
954
|
-
if (Selector_List_Obj ls = Cast<Selector_List>(wrapped->selector())) {
|
955
|
-
ls->remove_parent_selectors();
|
956
|
-
return (is_superselector_of(ls, wrapped->name()));
|
957
|
-
}
|
958
|
-
}
|
959
|
-
}
|
960
|
-
rset.insert(r->to_string());
|
961
|
-
}
|
962
|
-
|
963
|
-
//for (auto l : lset) { cerr << "l: " << l << endl; }
|
964
|
-
//for (auto r : rset) { cerr << "r: " << r << endl; }
|
965
|
-
|
966
|
-
if (lset.empty()) return true;
|
967
|
-
// return true if rset contains all the elements of lset
|
968
|
-
return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
|
969
|
-
|
970
|
-
}
|
971
|
-
|
972
|
-
// create complex selector (ancestor of) from compound selector
|
973
|
-
Complex_Selector_Obj Compound_Selector::to_complex()
|
974
|
-
{
|
975
|
-
// create an intermediate complex selector
|
976
|
-
return SASS_MEMORY_NEW(Complex_Selector,
|
977
|
-
pstate(),
|
978
|
-
Complex_Selector::ANCESTOR_OF,
|
979
|
-
this,
|
980
|
-
0);
|
981
|
-
}
|
982
|
-
|
983
|
-
Selector_List_Ptr Complex_Selector::unify_with(Complex_Selector_Ptr other)
|
984
|
-
{
|
985
|
-
|
986
|
-
// get last tails (on the right side)
|
987
|
-
Complex_Selector_Obj l_last = this->last();
|
988
|
-
Complex_Selector_Obj r_last = other->last();
|
989
|
-
|
990
|
-
// check valid pointers (assertion)
|
991
|
-
SASS_ASSERT(l_last, "lhs is null");
|
992
|
-
SASS_ASSERT(r_last, "rhs is null");
|
993
|
-
|
994
|
-
// Not sure about this check, but closest way I could check
|
995
|
-
// was to see if this is a ruby 'SimpleSequence' equivalent.
|
996
|
-
// It seems to do the job correctly as some specs react to this
|
997
|
-
if (l_last->combinator() != Combinator::ANCESTOR_OF) return 0;
|
998
|
-
if (r_last->combinator() != Combinator::ANCESTOR_OF ) return 0;
|
999
|
-
|
1000
|
-
// get the headers for the last tails
|
1001
|
-
Compound_Selector_Obj l_last_head = l_last->head();
|
1002
|
-
Compound_Selector_Obj r_last_head = r_last->head();
|
1003
|
-
|
1004
|
-
// check valid head pointers (assertion)
|
1005
|
-
SASS_ASSERT(l_last_head, "lhs head is null");
|
1006
|
-
SASS_ASSERT(r_last_head, "rhs head is null");
|
1007
|
-
|
1008
|
-
// get the unification of the last compound selectors
|
1009
|
-
Compound_Selector_Obj unified = r_last_head->unify_with(l_last_head);
|
1010
|
-
|
1011
|
-
// abort if we could not unify heads
|
1012
|
-
if (unified == 0) return 0;
|
1013
|
-
|
1014
|
-
// check for universal (star: `*`) selector
|
1015
|
-
bool is_universal = l_last_head->is_universal() ||
|
1016
|
-
r_last_head->is_universal();
|
1017
|
-
|
1018
|
-
if (is_universal)
|
1019
|
-
{
|
1020
|
-
// move the head
|
1021
|
-
l_last->head(0);
|
1022
|
-
r_last->head(unified);
|
1023
|
-
}
|
1024
|
-
|
1025
|
-
// create nodes from both selectors
|
1026
|
-
Node lhsNode = complexSelectorToNode(this);
|
1027
|
-
Node rhsNode = complexSelectorToNode(other);
|
1028
|
-
|
1029
|
-
// overwrite universal base
|
1030
|
-
if (!is_universal)
|
1031
|
-
{
|
1032
|
-
// create some temporaries to convert to node
|
1033
|
-
Complex_Selector_Obj fake = unified->to_complex();
|
1034
|
-
Node unified_node = complexSelectorToNode(fake);
|
1035
|
-
// add to permutate the list?
|
1036
|
-
rhsNode.plus(unified_node);
|
1037
|
-
}
|
1038
|
-
|
1039
|
-
// do some magic we inherit from node and extend
|
1040
|
-
Node node = subweave(lhsNode, rhsNode);
|
1041
|
-
Selector_List_Obj result = SASS_MEMORY_NEW(Selector_List, pstate());
|
1042
|
-
NodeDequePtr col = node.collection(); // move from collection to list
|
1043
|
-
for (NodeDeque::iterator it = col->begin(), end = col->end(); it != end; it++)
|
1044
|
-
{ result->append(nodeToComplexSelector(Node::naiveTrim(*it))); }
|
1045
|
-
|
1046
|
-
// only return if list has some entries
|
1047
|
-
return result->length() ? result.detach() : 0;
|
1048
|
-
|
1049
|
-
}
|
1050
|
-
|
1051
|
-
bool Compound_Selector::operator== (const Compound_Selector& rhs) const
|
1052
|
-
{
|
1053
|
-
// for array access
|
1054
|
-
size_t i = 0, n = 0;
|
1055
|
-
size_t iL = length();
|
1056
|
-
size_t nL = rhs.length();
|
1057
|
-
// create temporary vectors and sort them
|
1058
|
-
std::vector<Simple_Selector_Obj> l_lst = this->elements();
|
1059
|
-
std::vector<Simple_Selector_Obj> r_lst = rhs.elements();
|
1060
|
-
std::sort(l_lst.begin(), l_lst.end(), OrderNodes());
|
1061
|
-
std::sort(r_lst.begin(), r_lst.end(), OrderNodes());
|
1062
|
-
// process loop
|
1063
|
-
while (true)
|
1064
|
-
{
|
1065
|
-
// first check for valid index
|
1066
|
-
if (i == iL) return iL == nL;
|
1067
|
-
else if (n == nL) return iL == nL;
|
1068
|
-
// the access the vector items
|
1069
|
-
Simple_Selector_Obj l = l_lst[i];
|
1070
|
-
Simple_Selector_Obj r = r_lst[n];
|
1071
|
-
// skip nulls
|
1072
|
-
if (!l) ++i;
|
1073
|
-
if (!r) ++n;
|
1074
|
-
// do the check now
|
1075
|
-
else if (*l != *r)
|
1076
|
-
{ return false; }
|
1077
|
-
// advance now
|
1078
|
-
++i; ++n;
|
1079
|
-
}
|
1080
|
-
// there is no break?!
|
1081
|
-
}
|
1082
|
-
|
1083
|
-
bool Complex_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping)
|
1084
|
-
{
|
1085
|
-
return last()->head() && last()->head()->is_superselector_of(rhs, wrapping);
|
1086
|
-
}
|
1087
|
-
|
1088
|
-
bool Complex_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapping)
|
1089
|
-
{
|
1090
|
-
Complex_Selector_Ptr lhs = this;
|
1091
|
-
// check for selectors with leading or trailing combinators
|
1092
|
-
if (!lhs->head() || !rhs->head())
|
1093
|
-
{ return false; }
|
1094
|
-
Complex_Selector_Obj l_innermost = lhs->innermost();
|
1095
|
-
if (l_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
|
1096
|
-
{ return false; }
|
1097
|
-
Complex_Selector_Obj r_innermost = rhs->innermost();
|
1098
|
-
if (r_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
|
1099
|
-
{ return false; }
|
1100
|
-
// more complex (i.e., longer) selectors are always more specific
|
1101
|
-
size_t l_len = lhs->length(), r_len = rhs->length();
|
1102
|
-
if (l_len > r_len)
|
1103
|
-
{ return false; }
|
1104
|
-
|
1105
|
-
if (l_len == 1)
|
1106
|
-
{ return lhs->head()->is_superselector_of(rhs->last()->head(), wrapping); }
|
1107
|
-
|
1108
|
-
// we have to look one tail deeper, since we cary the
|
1109
|
-
// combinator around for it (which is important here)
|
1110
|
-
if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) {
|
1111
|
-
Complex_Selector_Obj lhs_tail = lhs->tail();
|
1112
|
-
Complex_Selector_Obj rhs_tail = rhs->tail();
|
1113
|
-
if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
|
1114
|
-
if (lhs_tail->head() && !rhs_tail->head()) return false;
|
1115
|
-
if (!lhs_tail->head() && rhs_tail->head()) return false;
|
1116
|
-
if (lhs_tail->head() && rhs_tail->head()) {
|
1117
|
-
if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false;
|
1118
|
-
}
|
1119
|
-
}
|
1120
|
-
|
1121
|
-
bool found = false;
|
1122
|
-
Complex_Selector_Obj marker = rhs;
|
1123
|
-
for (size_t i = 0, L = rhs->length(); i < L; ++i) {
|
1124
|
-
if (i == L-1)
|
1125
|
-
{ return false; }
|
1126
|
-
if (lhs->head() && marker->head() && lhs->head()->is_superselector_of(marker->head(), wrapping))
|
1127
|
-
{ found = true; break; }
|
1128
|
-
marker = marker->tail();
|
1129
|
-
}
|
1130
|
-
if (!found)
|
1131
|
-
{ return false; }
|
1132
|
-
|
1133
|
-
/*
|
1134
|
-
Hmm, I hope I have the logic right:
|
1135
|
-
|
1136
|
-
if lhs has a combinator:
|
1137
|
-
if !(marker has a combinator) return false
|
1138
|
-
if !(lhs.combinator == '~' ? marker.combinator != '>' : lhs.combinator == marker.combinator) return false
|
1139
|
-
return lhs.tail-without-innermost.is_superselector_of(marker.tail-without-innermost)
|
1140
|
-
else if marker has a combinator:
|
1141
|
-
if !(marker.combinator == ">") return false
|
1142
|
-
return lhs.tail.is_superselector_of(marker.tail)
|
1143
|
-
else
|
1144
|
-
return lhs.tail.is_superselector_of(marker.tail)
|
1145
|
-
*/
|
1146
|
-
if (lhs->combinator() != Complex_Selector::ANCESTOR_OF)
|
1147
|
-
{
|
1148
|
-
if (marker->combinator() == Complex_Selector::ANCESTOR_OF)
|
1149
|
-
{ return false; }
|
1150
|
-
if (!(lhs->combinator() == Complex_Selector::PRECEDES ? marker->combinator() != Complex_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
|
1151
|
-
{ return false; }
|
1152
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
1153
|
-
}
|
1154
|
-
else if (marker->combinator() != Complex_Selector::ANCESTOR_OF)
|
1155
|
-
{
|
1156
|
-
if (marker->combinator() != Complex_Selector::PARENT_OF)
|
1157
|
-
{ return false; }
|
1158
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
1159
|
-
}
|
1160
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
1161
|
-
}
|
1162
|
-
|
1163
|
-
size_t Complex_Selector::length() const
|
1164
|
-
{
|
1165
|
-
// TODO: make this iterative
|
1166
|
-
if (!tail()) return 1;
|
1167
|
-
return 1 + tail()->length();
|
1168
|
-
}
|
1169
|
-
|
1170
|
-
// append another complex selector at the end
|
1171
|
-
// check if we need to append some headers
|
1172
|
-
// then we need to check for the combinator
|
1173
|
-
// only then we can safely set the new tail
|
1174
|
-
void Complex_Selector::append(Complex_Selector_Obj ss, Backtraces& traces)
|
1175
|
-
{
|
1176
|
-
|
1177
|
-
Complex_Selector_Obj t = ss->tail();
|
1178
|
-
Combinator c = ss->combinator();
|
1179
|
-
String_Obj r = ss->reference();
|
1180
|
-
Compound_Selector_Obj h = ss->head();
|
1181
|
-
|
1182
|
-
if (ss->has_line_feed()) has_line_feed(true);
|
1183
|
-
if (ss->has_line_break()) has_line_break(true);
|
1184
|
-
|
1185
|
-
// append old headers
|
1186
|
-
if (h && h->length()) {
|
1187
|
-
if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
|
1188
|
-
traces.push_back(Backtrace(pstate()));
|
1189
|
-
throw Exception::InvalidParent(this, traces, ss);
|
1190
|
-
} else if (last()->head_ && last()->head_->length()) {
|
1191
|
-
Compound_Selector_Obj rh = last()->head();
|
1192
|
-
size_t i;
|
1193
|
-
size_t L = h->length();
|
1194
|
-
if (Cast<Element_Selector>(h->first())) {
|
1195
|
-
if (Class_Selector_Ptr cs = Cast<Class_Selector>(rh->last())) {
|
1196
|
-
Class_Selector_Ptr sqs = SASS_MEMORY_COPY(cs);
|
1197
|
-
sqs->name(sqs->name() + (*h)[0]->name());
|
1198
|
-
sqs->pstate((*h)[0]->pstate());
|
1199
|
-
(*rh)[rh->length()-1] = sqs;
|
1200
|
-
rh->pstate(h->pstate());
|
1201
|
-
for (i = 1; i < L; ++i) rh->append((*h)[i]);
|
1202
|
-
} else if (Id_Selector_Ptr is = Cast<Id_Selector>(rh->last())) {
|
1203
|
-
Id_Selector_Ptr sqs = SASS_MEMORY_COPY(is);
|
1204
|
-
sqs->name(sqs->name() + (*h)[0]->name());
|
1205
|
-
sqs->pstate((*h)[0]->pstate());
|
1206
|
-
(*rh)[rh->length()-1] = sqs;
|
1207
|
-
rh->pstate(h->pstate());
|
1208
|
-
for (i = 1; i < L; ++i) rh->append((*h)[i]);
|
1209
|
-
} else if (Element_Selector_Ptr ts = Cast<Element_Selector>(rh->last())) {
|
1210
|
-
Element_Selector_Ptr tss = SASS_MEMORY_COPY(ts);
|
1211
|
-
tss->name(tss->name() + (*h)[0]->name());
|
1212
|
-
tss->pstate((*h)[0]->pstate());
|
1213
|
-
(*rh)[rh->length()-1] = tss;
|
1214
|
-
rh->pstate(h->pstate());
|
1215
|
-
for (i = 1; i < L; ++i) rh->append((*h)[i]);
|
1216
|
-
} else if (Placeholder_Selector_Ptr ps = Cast<Placeholder_Selector>(rh->last())) {
|
1217
|
-
Placeholder_Selector_Ptr pss = SASS_MEMORY_COPY(ps);
|
1218
|
-
pss->name(pss->name() + (*h)[0]->name());
|
1219
|
-
pss->pstate((*h)[0]->pstate());
|
1220
|
-
(*rh)[rh->length()-1] = pss;
|
1221
|
-
rh->pstate(h->pstate());
|
1222
|
-
for (i = 1; i < L; ++i) rh->append((*h)[i]);
|
1223
|
-
} else {
|
1224
|
-
last()->head_->concat(h);
|
1225
|
-
}
|
1226
|
-
} else {
|
1227
|
-
last()->head_->concat(h);
|
1228
|
-
}
|
1229
|
-
} else if (last()->head_) {
|
1230
|
-
last()->head_->concat(h);
|
1231
|
-
}
|
1232
|
-
} else {
|
1233
|
-
// std::cerr << "has no or empty head\n";
|
1234
|
-
}
|
1235
|
-
|
1236
|
-
if (last()) {
|
1237
|
-
if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
|
1238
|
-
Complex_Selector_Ptr inter = SASS_MEMORY_NEW(Complex_Selector, pstate());
|
1239
|
-
inter->reference(r);
|
1240
|
-
inter->combinator(c);
|
1241
|
-
inter->tail(t);
|
1242
|
-
last()->tail(inter);
|
1243
|
-
} else {
|
1244
|
-
if (last()->combinator() == ANCESTOR_OF) {
|
1245
|
-
last()->combinator(c);
|
1246
|
-
last()->reference(r);
|
1247
|
-
}
|
1248
|
-
last()->tail(t);
|
1249
|
-
}
|
1250
|
-
}
|
1251
|
-
|
1252
|
-
}
|
1253
|
-
|
1254
|
-
Selector_List_Obj Selector_List::eval(Eval& eval)
|
1255
|
-
{
|
1256
|
-
Selector_List_Obj list = schema() ?
|
1257
|
-
eval(schema()) : eval(this);
|
1258
|
-
list->schema(schema());
|
1259
|
-
return list;
|
1260
|
-
}
|
1261
|
-
|
1262
|
-
Selector_List_Ptr Selector_List::resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, Backtraces& traces, bool implicit_parent)
|
1263
|
-
{
|
1264
|
-
if (!this->has_parent_ref()) return this;
|
1265
|
-
Selector_List_Ptr ss = SASS_MEMORY_NEW(Selector_List, pstate());
|
1266
|
-
Selector_List_Ptr ps = pstack.back();
|
1267
|
-
for (size_t pi = 0, pL = ps->length(); pi < pL; ++pi) {
|
1268
|
-
for (size_t si = 0, sL = this->length(); si < sL; ++si) {
|
1269
|
-
Selector_List_Obj rv = at(si)->resolve_parent_refs(pstack, traces, implicit_parent);
|
1270
|
-
ss->concat(rv);
|
1271
|
-
}
|
1272
|
-
}
|
1273
|
-
return ss;
|
1274
|
-
}
|
1275
|
-
|
1276
|
-
Selector_List_Ptr Complex_Selector::resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, Backtraces& traces, bool implicit_parent)
|
1277
|
-
{
|
1278
|
-
Complex_Selector_Obj tail = this->tail();
|
1279
|
-
Compound_Selector_Obj head = this->head();
|
1280
|
-
Selector_List_Ptr parents = pstack.back();
|
1281
|
-
|
1282
|
-
if (!this->has_real_parent_ref() && !implicit_parent) {
|
1283
|
-
Selector_List_Ptr retval = SASS_MEMORY_NEW(Selector_List, pstate());
|
1284
|
-
retval->append(this);
|
1285
|
-
return retval;
|
1286
|
-
}
|
1287
|
-
|
1288
|
-
// first resolve_parent_refs the tail (which may return an expanded list)
|
1289
|
-
Selector_List_Obj tails = tail ? tail->resolve_parent_refs(pstack, traces, implicit_parent) : 0;
|
1290
|
-
|
1291
|
-
if (head && head->length() > 0) {
|
1292
|
-
|
1293
|
-
Selector_List_Obj retval;
|
1294
|
-
// we have a parent selector in a simple compound list
|
1295
|
-
// mix parent complex selector into the compound list
|
1296
|
-
if (Cast<Parent_Selector>((*head)[0])) {
|
1297
|
-
retval = SASS_MEMORY_NEW(Selector_List, pstate());
|
1298
|
-
|
1299
|
-
// it turns out that real parent references reach
|
1300
|
-
// across @at-root rules, which comes unexpected
|
1301
|
-
if (parents == NULL && head->has_real_parent_ref()) {
|
1302
|
-
int i = pstack.size() - 1;
|
1303
|
-
while (!parents && i > -1) {
|
1304
|
-
parents = pstack.at(i--);
|
1305
|
-
}
|
1306
|
-
}
|
1307
|
-
|
1308
|
-
if (parents && parents->length()) {
|
1309
|
-
if (tails && tails->length() > 0) {
|
1310
|
-
for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
|
1311
|
-
for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
|
1312
|
-
Complex_Selector_Obj t = (*tails)[n];
|
1313
|
-
Complex_Selector_Obj parent = (*parents)[i];
|
1314
|
-
Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
|
1315
|
-
Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
|
1316
|
-
ss->tail(t ? SASS_MEMORY_CLONE(t) : NULL);
|
1317
|
-
Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
|
1318
|
-
// remove parent selector from sequence
|
1319
|
-
if (h->length()) {
|
1320
|
-
h->erase(h->begin());
|
1321
|
-
ss->head(h);
|
1322
|
-
} else {
|
1323
|
-
ss->head(NULL);
|
1324
|
-
}
|
1325
|
-
// adjust for parent selector (1 char)
|
1326
|
-
// if (h->length()) {
|
1327
|
-
// ParserState state(h->at(0)->pstate());
|
1328
|
-
// state.offset.column += 1;
|
1329
|
-
// state.column -= 1;
|
1330
|
-
// (*h)[0]->pstate(state);
|
1331
|
-
// }
|
1332
|
-
// keep old parser state
|
1333
|
-
s->pstate(pstate());
|
1334
|
-
// append new tail
|
1335
|
-
s->append(ss, traces);
|
1336
|
-
retval->append(s);
|
1337
|
-
}
|
1338
|
-
}
|
1339
|
-
}
|
1340
|
-
// have no tails but parents
|
1341
|
-
// loop above is inside out
|
1342
|
-
else {
|
1343
|
-
for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
|
1344
|
-
Complex_Selector_Obj parent = (*parents)[i];
|
1345
|
-
Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
|
1346
|
-
Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
|
1347
|
-
// this is only if valid if the parent has no trailing op
|
1348
|
-
// otherwise we cannot append more simple selectors to head
|
1349
|
-
if (parent->last()->combinator() != ANCESTOR_OF) {
|
1350
|
-
traces.push_back(Backtrace(pstate()));
|
1351
|
-
throw Exception::InvalidParent(parent, traces, ss);
|
1352
|
-
}
|
1353
|
-
ss->tail(tail ? SASS_MEMORY_CLONE(tail) : NULL);
|
1354
|
-
Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
|
1355
|
-
// remove parent selector from sequence
|
1356
|
-
if (h->length()) {
|
1357
|
-
h->erase(h->begin());
|
1358
|
-
ss->head(h);
|
1359
|
-
} else {
|
1360
|
-
ss->head(NULL);
|
1361
|
-
}
|
1362
|
-
// \/ IMO ruby sass bug \/
|
1363
|
-
ss->has_line_feed(false);
|
1364
|
-
// adjust for parent selector (1 char)
|
1365
|
-
// if (h->length()) {
|
1366
|
-
// ParserState state(h->at(0)->pstate());
|
1367
|
-
// state.offset.column += 1;
|
1368
|
-
// state.column -= 1;
|
1369
|
-
// (*h)[0]->pstate(state);
|
1370
|
-
// }
|
1371
|
-
// keep old parser state
|
1372
|
-
s->pstate(pstate());
|
1373
|
-
// append new tail
|
1374
|
-
s->append(ss, traces);
|
1375
|
-
retval->append(s);
|
1376
|
-
}
|
1377
|
-
}
|
1378
|
-
}
|
1379
|
-
// have no parent but some tails
|
1380
|
-
else {
|
1381
|
-
if (tails && tails->length() > 0) {
|
1382
|
-
for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
|
1383
|
-
Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
|
1384
|
-
cpy->tail(SASS_MEMORY_CLONE(tails->at(n)));
|
1385
|
-
cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
|
1386
|
-
for (size_t i = 1, L = this->head()->length(); i < L; ++i)
|
1387
|
-
cpy->head()->append((*this->head())[i]);
|
1388
|
-
if (!cpy->head()->length()) cpy->head(0);
|
1389
|
-
retval->append(cpy->skip_empty_reference());
|
1390
|
-
}
|
1391
|
-
}
|
1392
|
-
// have no parent nor tails
|
1393
|
-
else {
|
1394
|
-
Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
|
1395
|
-
cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
|
1396
|
-
for (size_t i = 1, L = this->head()->length(); i < L; ++i)
|
1397
|
-
cpy->head()->append((*this->head())[i]);
|
1398
|
-
if (!cpy->head()->length()) cpy->head(0);
|
1399
|
-
retval->append(cpy->skip_empty_reference());
|
1400
|
-
}
|
1401
|
-
}
|
1402
|
-
}
|
1403
|
-
// no parent selector in head
|
1404
|
-
else {
|
1405
|
-
retval = this->tails(tails);
|
1406
|
-
}
|
1407
|
-
|
1408
|
-
for (Simple_Selector_Obj ss : head->elements()) {
|
1409
|
-
if (Wrapped_Selector_Ptr ws = Cast<Wrapped_Selector>(ss)) {
|
1410
|
-
if (Selector_List_Ptr sl = Cast<Selector_List>(ws->selector())) {
|
1411
|
-
if (parents) ws->selector(sl->resolve_parent_refs(pstack, traces, implicit_parent));
|
1412
|
-
}
|
1413
|
-
}
|
1414
|
-
}
|
1415
|
-
|
1416
|
-
return retval.detach();
|
1417
|
-
|
1418
|
-
}
|
1419
|
-
// has no head
|
1420
|
-
return this->tails(tails);
|
1421
|
-
}
|
1422
|
-
|
1423
|
-
Selector_List_Ptr Complex_Selector::tails(Selector_List_Ptr tails)
|
1424
|
-
{
|
1425
|
-
Selector_List_Ptr rv = SASS_MEMORY_NEW(Selector_List, pstate_);
|
1426
|
-
if (tails && tails->length()) {
|
1427
|
-
for (size_t i = 0, iL = tails->length(); i < iL; ++i) {
|
1428
|
-
Complex_Selector_Obj pr = SASS_MEMORY_CLONE(this);
|
1429
|
-
pr->tail(tails->at(i));
|
1430
|
-
rv->append(pr);
|
1431
|
-
}
|
1432
|
-
}
|
1433
|
-
else {
|
1434
|
-
rv->append(this);
|
1435
|
-
}
|
1436
|
-
return rv;
|
1437
|
-
}
|
1438
|
-
|
1439
|
-
// return the last tail that is defined
|
1440
|
-
Complex_Selector_Obj Complex_Selector::first()
|
1441
|
-
{
|
1442
|
-
// declare variables used in loop
|
1443
|
-
Complex_Selector_Obj cur = this;
|
1444
|
-
Compound_Selector_Obj head;
|
1445
|
-
// processing loop
|
1446
|
-
while (cur)
|
1447
|
-
{
|
1448
|
-
// get the head
|
1449
|
-
head = cur->head_;
|
1450
|
-
// abort (and return) if it is not a parent selector
|
1451
|
-
if (!head || head->length() != 1 || !Cast<Parent_Selector>((*head)[0])) {
|
1452
|
-
break;
|
1453
|
-
}
|
1454
|
-
// advance to next
|
1455
|
-
cur = cur->tail_;
|
1456
|
-
}
|
1457
|
-
// result
|
1458
|
-
return cur;
|
1459
|
-
}
|
1460
|
-
|
1461
|
-
// return the last tail that is defined
|
1462
|
-
Complex_Selector_Obj Complex_Selector::last()
|
1463
|
-
{
|
1464
|
-
Complex_Selector_Ptr cur = this;
|
1465
|
-
Complex_Selector_Ptr nxt = cur;
|
1466
|
-
// loop until last
|
1467
|
-
while (nxt) {
|
1468
|
-
cur = nxt;
|
1469
|
-
nxt = cur->tail();
|
1470
|
-
}
|
1471
|
-
return cur;
|
1472
|
-
}
|
1473
|
-
|
1474
|
-
Complex_Selector::Combinator Complex_Selector::clear_innermost()
|
1475
|
-
{
|
1476
|
-
Combinator c;
|
1477
|
-
if (!tail() || tail()->tail() == 0)
|
1478
|
-
{ c = combinator(); combinator(ANCESTOR_OF); tail(0); }
|
1479
|
-
else
|
1480
|
-
{ c = tail()->clear_innermost(); }
|
1481
|
-
return c;
|
1482
|
-
}
|
1483
|
-
|
1484
|
-
void Complex_Selector::set_innermost(Complex_Selector_Obj val, Combinator c)
|
1485
|
-
{
|
1486
|
-
if (!tail())
|
1487
|
-
{ tail(val); combinator(c); }
|
1488
|
-
else
|
1489
|
-
{ tail()->set_innermost(val, c); }
|
1490
|
-
}
|
1491
|
-
|
1492
|
-
void Complex_Selector::cloneChildren()
|
1493
|
-
{
|
1494
|
-
if (head()) head(SASS_MEMORY_CLONE(head()));
|
1495
|
-
if (tail()) tail(SASS_MEMORY_CLONE(tail()));
|
1496
|
-
}
|
1497
|
-
|
1498
|
-
void Compound_Selector::cloneChildren()
|
72
|
+
const std::string AST_Node::to_string(Sass_Inspect_Options opt) const
|
1499
73
|
{
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
74
|
+
Sass_Output_Options out(opt);
|
75
|
+
Emitter emitter(out);
|
76
|
+
Inspect i(emitter);
|
77
|
+
i.in_declaration = true;
|
78
|
+
// ToDo: inspect should be const
|
79
|
+
const_cast<AST_Node*>(this)->perform(&i);
|
80
|
+
return i.get_buffer();
|
1503
81
|
}
|
1504
82
|
|
1505
|
-
|
83
|
+
const std::string AST_Node::to_string() const
|
1506
84
|
{
|
1507
|
-
|
1508
|
-
at(i) = SASS_MEMORY_CLONE(at(i));
|
1509
|
-
}
|
85
|
+
return to_string({ NESTED, 5 });
|
1510
86
|
}
|
1511
87
|
|
1512
|
-
|
1513
|
-
|
1514
|
-
selector(SASS_MEMORY_CLONE(selector()));
|
1515
|
-
}
|
88
|
+
/////////////////////////////////////////////////////////////////////////
|
89
|
+
/////////////////////////////////////////////////////////////////////////
|
1516
90
|
|
1517
|
-
|
1518
|
-
// basically unwraps parsed selectors
|
1519
|
-
void Selector_List::remove_parent_selectors()
|
91
|
+
Expression_Obj Hashed::at(Expression_Obj k) const
|
1520
92
|
{
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
if ((*this)[i]->head()->is_empty_reference()) {
|
1525
|
-
// simply move to the next tail if we have "no" combinator
|
1526
|
-
if ((*this)[i]->combinator() == Complex_Selector::ANCESTOR_OF) {
|
1527
|
-
if ((*this)[i]->tail()) {
|
1528
|
-
if ((*this)[i]->has_line_feed()) {
|
1529
|
-
(*this)[i]->tail()->has_line_feed(true);
|
1530
|
-
}
|
1531
|
-
(*this)[i] = (*this)[i]->tail();
|
1532
|
-
}
|
1533
|
-
}
|
1534
|
-
// otherwise remove the first item from head
|
1535
|
-
else {
|
1536
|
-
(*this)[i]->head()->erase((*this)[i]->head()->begin());
|
1537
|
-
}
|
1538
|
-
}
|
1539
|
-
}
|
93
|
+
if (elements_.count(k))
|
94
|
+
{ return elements_.at(k); }
|
95
|
+
else { return {}; }
|
1540
96
|
}
|
1541
97
|
|
1542
|
-
|
1543
|
-
|
1544
|
-
if (hash_ == 0) {
|
1545
|
-
hash_combine(hash_, Simple_Selector::hash());
|
1546
|
-
if (selector_) hash_combine(hash_, selector_->hash());
|
1547
|
-
}
|
1548
|
-
return hash_;
|
1549
|
-
}
|
1550
|
-
bool Wrapped_Selector::has_parent_ref() const {
|
1551
|
-
// if (has_reference()) return true;
|
1552
|
-
if (!selector()) return false;
|
1553
|
-
return selector()->has_parent_ref();
|
1554
|
-
}
|
1555
|
-
bool Wrapped_Selector::has_real_parent_ref() const {
|
1556
|
-
// if (has_reference()) return true;
|
1557
|
-
if (!selector()) return false;
|
1558
|
-
return selector()->has_real_parent_ref();
|
1559
|
-
}
|
1560
|
-
unsigned long Wrapped_Selector::specificity() const
|
1561
|
-
{
|
1562
|
-
return selector_ ? selector_->specificity() : 0;
|
1563
|
-
}
|
98
|
+
/////////////////////////////////////////////////////////////////////////
|
99
|
+
/////////////////////////////////////////////////////////////////////////
|
1564
100
|
|
101
|
+
Statement::Statement(ParserState pstate, Type st, size_t t)
|
102
|
+
: AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)
|
103
|
+
{ }
|
104
|
+
Statement::Statement(const Statement* ptr)
|
105
|
+
: AST_Node(ptr),
|
106
|
+
statement_type_(ptr->statement_type_),
|
107
|
+
tabs_(ptr->tabs_),
|
108
|
+
group_end_(ptr->group_end_)
|
109
|
+
{ }
|
1565
110
|
|
1566
|
-
bool
|
111
|
+
bool Statement::bubbles()
|
1567
112
|
{
|
1568
|
-
for (Complex_Selector_Obj s : elements()) {
|
1569
|
-
if (s && s->has_parent_ref()) return true;
|
1570
|
-
}
|
1571
113
|
return false;
|
1572
114
|
}
|
1573
115
|
|
1574
|
-
bool
|
116
|
+
bool Statement::has_content()
|
1575
117
|
{
|
1576
|
-
|
1577
|
-
if (s && s->has_real_parent_ref()) return true;
|
1578
|
-
}
|
1579
|
-
return false;
|
118
|
+
return statement_type_ == CONTENT;
|
1580
119
|
}
|
1581
120
|
|
1582
|
-
bool
|
121
|
+
bool Statement::is_invisible() const
|
1583
122
|
{
|
1584
|
-
if (String_Schema_Obj schema = Cast<String_Schema>(contents())) {
|
1585
|
-
return schema->length() > 0 && Cast<Parent_Selector>(schema->at(0)) != NULL;
|
1586
|
-
}
|
1587
123
|
return false;
|
1588
124
|
}
|
1589
125
|
|
1590
|
-
|
126
|
+
/////////////////////////////////////////////////////////////////////////
|
127
|
+
/////////////////////////////////////////////////////////////////////////
|
128
|
+
|
129
|
+
Block::Block(ParserState pstate, size_t s, bool r)
|
130
|
+
: Statement(pstate),
|
131
|
+
Vectorized<Statement_Obj>(s),
|
132
|
+
is_root_(r)
|
133
|
+
{ }
|
134
|
+
Block::Block(const Block* ptr)
|
135
|
+
: Statement(ptr),
|
136
|
+
Vectorized<Statement_Obj>(*ptr),
|
137
|
+
is_root_(ptr->is_root_)
|
138
|
+
{ }
|
139
|
+
|
140
|
+
bool Block::has_content()
|
1591
141
|
{
|
1592
|
-
|
1593
|
-
|
1594
|
-
return schema->length() > 0 && p && p->is_real_parent_ref();
|
142
|
+
for (size_t i = 0, L = elements().size(); i < L; ++i) {
|
143
|
+
if (elements()[i]->has_content()) return true;
|
1595
144
|
}
|
1596
|
-
return
|
145
|
+
return Statement::has_content();
|
1597
146
|
}
|
1598
147
|
|
1599
|
-
|
148
|
+
/////////////////////////////////////////////////////////////////////////
|
149
|
+
/////////////////////////////////////////////////////////////////////////
|
150
|
+
|
151
|
+
Has_Block::Has_Block(ParserState pstate, Block_Obj b)
|
152
|
+
: Statement(pstate), block_(b)
|
153
|
+
{ }
|
154
|
+
Has_Block::Has_Block(const Has_Block* ptr)
|
155
|
+
: Statement(ptr), block_(ptr->block_)
|
156
|
+
{ }
|
157
|
+
|
158
|
+
bool Has_Block::has_content()
|
1600
159
|
{
|
1601
|
-
|
160
|
+
return (block_ && block_->has_content()) || Statement::has_content();
|
1602
161
|
}
|
1603
162
|
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
163
|
+
/////////////////////////////////////////////////////////////////////////
|
164
|
+
/////////////////////////////////////////////////////////////////////////
|
165
|
+
|
166
|
+
Ruleset::Ruleset(ParserState pstate, Selector_List_Obj s, Block_Obj b)
|
167
|
+
: Has_Block(pstate, b), selector_(s), is_root_(false)
|
168
|
+
{ statement_type(RULESET); }
|
169
|
+
Ruleset::Ruleset(const Ruleset* ptr)
|
170
|
+
: Has_Block(ptr),
|
171
|
+
selector_(ptr->selector_),
|
172
|
+
is_root_(ptr->is_root_)
|
173
|
+
{ statement_type(RULESET); }
|
174
|
+
|
175
|
+
bool Ruleset::is_invisible() const {
|
176
|
+
if (Selector_List* sl = Cast<Selector_List>(selector())) {
|
177
|
+
for (size_t i = 0, L = sl->length(); i < L; ++i)
|
178
|
+
if (!(*sl)[i]->has_placeholder()) return false;
|
1611
179
|
}
|
1612
180
|
return true;
|
1613
181
|
}
|
1614
182
|
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
183
|
+
/////////////////////////////////////////////////////////////////////////
|
184
|
+
/////////////////////////////////////////////////////////////////////////
|
185
|
+
|
186
|
+
Bubble::Bubble(ParserState pstate, Statement_Obj n, Statement_Obj g, size_t t)
|
187
|
+
: Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == 0)
|
188
|
+
{ }
|
189
|
+
Bubble::Bubble(const Bubble* ptr)
|
190
|
+
: Statement(ptr),
|
191
|
+
node_(ptr->node_),
|
192
|
+
group_end_(ptr->group_end_)
|
193
|
+
{ }
|
194
|
+
|
195
|
+
bool Bubble::bubbles()
|
1618
196
|
{
|
1619
|
-
// Check every rhs selector against left hand list
|
1620
|
-
for(size_t i = 0, L = sub->length(); i < L; ++i) {
|
1621
|
-
if (!is_superselector_of((*sub)[i], wrapping)) return false;
|
1622
|
-
}
|
1623
197
|
return true;
|
1624
198
|
}
|
1625
199
|
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
200
|
+
/////////////////////////////////////////////////////////////////////////
|
201
|
+
/////////////////////////////////////////////////////////////////////////
|
202
|
+
|
203
|
+
Trace::Trace(ParserState pstate, std::string n, Block_Obj b, char type)
|
204
|
+
: Has_Block(pstate, b), type_(type), name_(n)
|
205
|
+
{ }
|
206
|
+
Trace::Trace(const Trace* ptr)
|
207
|
+
: Has_Block(ptr),
|
208
|
+
type_(ptr->type_),
|
209
|
+
name_(ptr->name_)
|
210
|
+
{ }
|
211
|
+
|
212
|
+
/////////////////////////////////////////////////////////////////////////
|
213
|
+
/////////////////////////////////////////////////////////////////////////
|
214
|
+
|
215
|
+
Media_Block::Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b)
|
216
|
+
: Has_Block(pstate, b), media_queries_(mqs)
|
217
|
+
{ statement_type(MEDIA); }
|
218
|
+
Media_Block::Media_Block(const Media_Block* ptr)
|
219
|
+
: Has_Block(ptr), media_queries_(ptr->media_queries_)
|
220
|
+
{ statement_type(MEDIA); }
|
221
|
+
|
222
|
+
bool Media_Block::is_invisible() const {
|
223
|
+
for (size_t i = 0, L = block()->length(); i < L; ++i) {
|
224
|
+
Statement_Obj stm = block()->at(i);
|
225
|
+
if (!stm->is_invisible()) return false;
|
1633
226
|
}
|
1634
|
-
return
|
227
|
+
return true;
|
1635
228
|
}
|
1636
229
|
|
1637
|
-
|
1638
|
-
// is a superselector of any one of the left side selectors
|
1639
|
-
bool Selector_List::is_superselector_of(Complex_Selector_Obj sub, std::string wrapping)
|
230
|
+
bool Media_Block::bubbles()
|
1640
231
|
{
|
1641
|
-
|
1642
|
-
for(size_t i = 0, L = length(); i < L; ++i) {
|
1643
|
-
if ((*this)[i]->is_superselector_of(sub)) return true;
|
1644
|
-
}
|
1645
|
-
return false;
|
232
|
+
return true;
|
1646
233
|
}
|
1647
234
|
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
235
|
+
/////////////////////////////////////////////////////////////////////////
|
236
|
+
/////////////////////////////////////////////////////////////////////////
|
237
|
+
|
238
|
+
Directive::Directive(ParserState pstate, std::string kwd, Selector_List_Obj sel, Block_Obj b, Expression_Obj val)
|
239
|
+
: Has_Block(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
|
240
|
+
{ statement_type(DIRECTIVE); }
|
241
|
+
Directive::Directive(const Directive* ptr)
|
242
|
+
: Has_Block(ptr),
|
243
|
+
keyword_(ptr->keyword_),
|
244
|
+
selector_(ptr->selector_),
|
245
|
+
value_(ptr->value_) // set value manually if needed
|
246
|
+
{ statement_type(DIRECTIVE); }
|
247
|
+
|
248
|
+
bool Directive::bubbles() { return is_keyframes() || is_media(); }
|
249
|
+
|
250
|
+
bool Directive::is_media() {
|
251
|
+
return keyword_.compare("@-webkit-media") == 0 ||
|
252
|
+
keyword_.compare("@-moz-media") == 0 ||
|
253
|
+
keyword_.compare("@-o-media") == 0 ||
|
254
|
+
keyword_.compare("@media") == 0;
|
255
|
+
}
|
256
|
+
bool Directive::is_keyframes() {
|
257
|
+
return keyword_.compare("@-webkit-keyframes") == 0 ||
|
258
|
+
keyword_.compare("@-moz-keyframes") == 0 ||
|
259
|
+
keyword_.compare("@-o-keyframes") == 0 ||
|
260
|
+
keyword_.compare("@keyframes") == 0;
|
261
|
+
}
|
262
|
+
|
263
|
+
/////////////////////////////////////////////////////////////////////////
|
264
|
+
/////////////////////////////////////////////////////////////////////////
|
265
|
+
|
266
|
+
Keyframe_Rule::Keyframe_Rule(ParserState pstate, Block_Obj b)
|
267
|
+
: Has_Block(pstate, b), name_()
|
268
|
+
{ statement_type(KEYFRAMERULE); }
|
269
|
+
Keyframe_Rule::Keyframe_Rule(const Keyframe_Rule* ptr)
|
270
|
+
: Has_Block(ptr), name_(ptr->name_)
|
271
|
+
{ statement_type(KEYFRAMERULE); }
|
272
|
+
|
273
|
+
/////////////////////////////////////////////////////////////////////////
|
274
|
+
/////////////////////////////////////////////////////////////////////////
|
275
|
+
|
276
|
+
Declaration::Declaration(ParserState pstate, String_Obj prop, Expression_Obj val, bool i, bool c, Block_Obj b)
|
277
|
+
: Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_custom_property_(c), is_indented_(false)
|
278
|
+
{ statement_type(DECLARATION); }
|
279
|
+
Declaration::Declaration(const Declaration* ptr)
|
280
|
+
: Has_Block(ptr),
|
281
|
+
property_(ptr->property_),
|
282
|
+
value_(ptr->value_),
|
283
|
+
is_important_(ptr->is_important_),
|
284
|
+
is_custom_property_(ptr->is_custom_property_),
|
285
|
+
is_indented_(ptr->is_indented_)
|
286
|
+
{ statement_type(DECLARATION); }
|
1664
287
|
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
288
|
+
bool Declaration::is_invisible() const
|
289
|
+
{
|
290
|
+
if (is_custom_property()) return false;
|
291
|
+
return !(value_ && !Cast<Null>(value_));
|
292
|
+
}
|
293
|
+
|
294
|
+
/////////////////////////////////////////////////////////////////////////
|
295
|
+
/////////////////////////////////////////////////////////////////////////
|
296
|
+
|
297
|
+
Assignment::Assignment(ParserState pstate, std::string var, Expression_Obj val, bool is_default, bool is_global)
|
298
|
+
: Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
|
299
|
+
{ statement_type(ASSIGNMENT); }
|
300
|
+
Assignment::Assignment(const Assignment* ptr)
|
301
|
+
: Statement(ptr),
|
302
|
+
variable_(ptr->variable_),
|
303
|
+
value_(ptr->value_),
|
304
|
+
is_default_(ptr->is_default_),
|
305
|
+
is_global_(ptr->is_global_)
|
306
|
+
{ statement_type(ASSIGNMENT); }
|
307
|
+
|
308
|
+
/////////////////////////////////////////////////////////////////////////
|
309
|
+
/////////////////////////////////////////////////////////////////////////
|
310
|
+
|
311
|
+
Import::Import(ParserState pstate)
|
312
|
+
: Statement(pstate),
|
313
|
+
urls_(std::vector<Expression_Obj>()),
|
314
|
+
incs_(std::vector<Include>()),
|
315
|
+
import_queries_()
|
316
|
+
{ statement_type(IMPORT); }
|
317
|
+
Import::Import(const Import* ptr)
|
318
|
+
: Statement(ptr),
|
319
|
+
urls_(ptr->urls_),
|
320
|
+
incs_(ptr->incs_),
|
321
|
+
import_queries_(ptr->import_queries_)
|
322
|
+
{ statement_type(IMPORT); }
|
323
|
+
|
324
|
+
std::vector<Include>& Import::incs() { return incs_; }
|
325
|
+
std::vector<Expression_Obj>& Import::urls() { return urls_; }
|
326
|
+
|
327
|
+
/////////////////////////////////////////////////////////////////////////
|
328
|
+
/////////////////////////////////////////////////////////////////////////
|
329
|
+
|
330
|
+
Import_Stub::Import_Stub(ParserState pstate, Include res)
|
331
|
+
: Statement(pstate), resource_(res)
|
332
|
+
{ statement_type(IMPORT_STUB); }
|
333
|
+
Import_Stub::Import_Stub(const Import_Stub* ptr)
|
334
|
+
: Statement(ptr), resource_(ptr->resource_)
|
335
|
+
{ statement_type(IMPORT_STUB); }
|
336
|
+
Include Import_Stub::resource() { return resource_; };
|
337
|
+
std::string Import_Stub::imp_path() { return resource_.imp_path; };
|
338
|
+
std::string Import_Stub::abs_path() { return resource_.abs_path; };
|
339
|
+
|
340
|
+
/////////////////////////////////////////////////////////////////////////
|
341
|
+
/////////////////////////////////////////////////////////////////////////
|
342
|
+
|
343
|
+
Warning::Warning(ParserState pstate, Expression_Obj msg)
|
344
|
+
: Statement(pstate), message_(msg)
|
345
|
+
{ statement_type(WARNING); }
|
346
|
+
Warning::Warning(const Warning* ptr)
|
347
|
+
: Statement(ptr), message_(ptr->message_)
|
348
|
+
{ statement_type(WARNING); }
|
349
|
+
|
350
|
+
/////////////////////////////////////////////////////////////////////////
|
351
|
+
/////////////////////////////////////////////////////////////////////////
|
352
|
+
|
353
|
+
Error::Error(ParserState pstate, Expression_Obj msg)
|
354
|
+
: Statement(pstate), message_(msg)
|
355
|
+
{ statement_type(ERROR); }
|
356
|
+
Error::Error(const Error* ptr)
|
357
|
+
: Statement(ptr), message_(ptr->message_)
|
358
|
+
{ statement_type(ERROR); }
|
359
|
+
|
360
|
+
/////////////////////////////////////////////////////////////////////////
|
361
|
+
/////////////////////////////////////////////////////////////////////////
|
362
|
+
|
363
|
+
Debug::Debug(ParserState pstate, Expression_Obj val)
|
364
|
+
: Statement(pstate), value_(val)
|
365
|
+
{ statement_type(DEBUGSTMT); }
|
366
|
+
Debug::Debug(const Debug* ptr)
|
367
|
+
: Statement(ptr), value_(ptr->value_)
|
368
|
+
{ statement_type(DEBUGSTMT); }
|
369
|
+
|
370
|
+
/////////////////////////////////////////////////////////////////////////
|
371
|
+
/////////////////////////////////////////////////////////////////////////
|
372
|
+
|
373
|
+
Comment::Comment(ParserState pstate, String_Obj txt, bool is_important)
|
374
|
+
: Statement(pstate), text_(txt), is_important_(is_important)
|
375
|
+
{ statement_type(COMMENT); }
|
376
|
+
Comment::Comment(const Comment* ptr)
|
377
|
+
: Statement(ptr),
|
378
|
+
text_(ptr->text_),
|
379
|
+
is_important_(ptr->is_important_)
|
380
|
+
{ statement_type(COMMENT); }
|
381
|
+
|
382
|
+
bool Comment::is_invisible() const
|
383
|
+
{
|
384
|
+
return false;
|
385
|
+
}
|
386
|
+
|
387
|
+
/////////////////////////////////////////////////////////////////////////
|
388
|
+
/////////////////////////////////////////////////////////////////////////
|
389
|
+
|
390
|
+
If::If(ParserState pstate, Expression_Obj pred, Block_Obj con, Block_Obj alt)
|
391
|
+
: Has_Block(pstate, con), predicate_(pred), alternative_(alt)
|
392
|
+
{ statement_type(IF); }
|
393
|
+
If::If(const If* ptr)
|
394
|
+
: Has_Block(ptr),
|
395
|
+
predicate_(ptr->predicate_),
|
396
|
+
alternative_(ptr->alternative_)
|
397
|
+
{ statement_type(IF); }
|
398
|
+
|
399
|
+
bool If::has_content()
|
400
|
+
{
|
401
|
+
return Has_Block::has_content() || (alternative_ && alternative_->has_content());
|
402
|
+
}
|
403
|
+
|
404
|
+
/////////////////////////////////////////////////////////////////////////
|
405
|
+
/////////////////////////////////////////////////////////////////////////
|
406
|
+
|
407
|
+
For::For(ParserState pstate,
|
408
|
+
std::string var, Expression_Obj lo, Expression_Obj hi, Block_Obj b, bool inc)
|
409
|
+
: Has_Block(pstate, b),
|
410
|
+
variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc)
|
411
|
+
{ statement_type(FOR); }
|
412
|
+
For::For(const For* ptr)
|
413
|
+
: Has_Block(ptr),
|
414
|
+
variable_(ptr->variable_),
|
415
|
+
lower_bound_(ptr->lower_bound_),
|
416
|
+
upper_bound_(ptr->upper_bound_),
|
417
|
+
is_inclusive_(ptr->is_inclusive_)
|
418
|
+
{ statement_type(FOR); }
|
419
|
+
|
420
|
+
/////////////////////////////////////////////////////////////////////////
|
421
|
+
/////////////////////////////////////////////////////////////////////////
|
422
|
+
|
423
|
+
Each::Each(ParserState pstate, std::vector<std::string> vars, Expression_Obj lst, Block_Obj b)
|
424
|
+
: Has_Block(pstate, b), variables_(vars), list_(lst)
|
425
|
+
{ statement_type(EACH); }
|
426
|
+
Each::Each(const Each* ptr)
|
427
|
+
: Has_Block(ptr), variables_(ptr->variables_), list_(ptr->list_)
|
428
|
+
{ statement_type(EACH); }
|
429
|
+
|
430
|
+
/////////////////////////////////////////////////////////////////////////
|
431
|
+
/////////////////////////////////////////////////////////////////////////
|
432
|
+
|
433
|
+
While::While(ParserState pstate, Expression_Obj pred, Block_Obj b)
|
434
|
+
: Has_Block(pstate, b), predicate_(pred)
|
435
|
+
{ statement_type(WHILE); }
|
436
|
+
While::While(const While* ptr)
|
437
|
+
: Has_Block(ptr), predicate_(ptr->predicate_)
|
438
|
+
{ statement_type(WHILE); }
|
439
|
+
|
440
|
+
/////////////////////////////////////////////////////////////////////////
|
441
|
+
/////////////////////////////////////////////////////////////////////////
|
442
|
+
|
443
|
+
Return::Return(ParserState pstate, Expression_Obj val)
|
444
|
+
: Statement(pstate), value_(val)
|
445
|
+
{ statement_type(RETURN); }
|
446
|
+
Return::Return(const Return* ptr)
|
447
|
+
: Statement(ptr), value_(ptr->value_)
|
448
|
+
{ statement_type(RETURN); }
|
449
|
+
|
450
|
+
/////////////////////////////////////////////////////////////////////////
|
451
|
+
/////////////////////////////////////////////////////////////////////////
|
452
|
+
|
453
|
+
Extension::Extension(ParserState pstate, Selector_List_Obj s)
|
454
|
+
: Statement(pstate), selector_(s)
|
455
|
+
{ statement_type(EXTEND); }
|
456
|
+
Extension::Extension(const Extension* ptr)
|
457
|
+
: Statement(ptr), selector_(ptr->selector_)
|
458
|
+
{ statement_type(EXTEND); }
|
459
|
+
|
460
|
+
/////////////////////////////////////////////////////////////////////////
|
461
|
+
/////////////////////////////////////////////////////////////////////////
|
462
|
+
|
463
|
+
Definition::Definition(const Definition* ptr)
|
464
|
+
: Has_Block(ptr),
|
465
|
+
name_(ptr->name_),
|
466
|
+
parameters_(ptr->parameters_),
|
467
|
+
environment_(ptr->environment_),
|
468
|
+
type_(ptr->type_),
|
469
|
+
native_function_(ptr->native_function_),
|
470
|
+
c_function_(ptr->c_function_),
|
471
|
+
cookie_(ptr->cookie_),
|
472
|
+
is_overload_stub_(ptr->is_overload_stub_),
|
473
|
+
signature_(ptr->signature_)
|
474
|
+
{ }
|
475
|
+
|
476
|
+
Definition::Definition(ParserState pstate,
|
477
|
+
std::string n,
|
478
|
+
Parameters_Obj params,
|
479
|
+
Block_Obj b,
|
480
|
+
Type t)
|
481
|
+
: Has_Block(pstate, b),
|
482
|
+
name_(n),
|
483
|
+
parameters_(params),
|
484
|
+
environment_(0),
|
485
|
+
type_(t),
|
486
|
+
native_function_(0),
|
487
|
+
c_function_(0),
|
488
|
+
cookie_(0),
|
489
|
+
is_overload_stub_(false),
|
490
|
+
signature_(0)
|
491
|
+
{ }
|
492
|
+
|
493
|
+
Definition::Definition(ParserState pstate,
|
494
|
+
Signature sig,
|
495
|
+
std::string n,
|
496
|
+
Parameters_Obj params,
|
497
|
+
Native_Function func_ptr,
|
498
|
+
bool overload_stub)
|
499
|
+
: Has_Block(pstate, {}),
|
500
|
+
name_(n),
|
501
|
+
parameters_(params),
|
502
|
+
environment_(0),
|
503
|
+
type_(FUNCTION),
|
504
|
+
native_function_(func_ptr),
|
505
|
+
c_function_(0),
|
506
|
+
cookie_(0),
|
507
|
+
is_overload_stub_(overload_stub),
|
508
|
+
signature_(sig)
|
509
|
+
{ }
|
510
|
+
|
511
|
+
Definition::Definition(ParserState pstate,
|
512
|
+
Signature sig,
|
513
|
+
std::string n,
|
514
|
+
Parameters_Obj params,
|
515
|
+
Sass_Function_Entry c_func)
|
516
|
+
: Has_Block(pstate, {}),
|
517
|
+
name_(n),
|
518
|
+
parameters_(params),
|
519
|
+
environment_(0),
|
520
|
+
type_(FUNCTION),
|
521
|
+
native_function_(0),
|
522
|
+
c_function_(c_func),
|
523
|
+
cookie_(sass_function_get_cookie(c_func)),
|
524
|
+
is_overload_stub_(false),
|
525
|
+
signature_(sig)
|
526
|
+
{ }
|
527
|
+
|
528
|
+
/////////////////////////////////////////////////////////////////////////
|
529
|
+
/////////////////////////////////////////////////////////////////////////
|
530
|
+
|
531
|
+
Mixin_Call::Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Parameters_Obj b_params, Block_Obj b)
|
532
|
+
: Has_Block(pstate, b), name_(n), arguments_(args), block_parameters_(b_params)
|
533
|
+
{ }
|
534
|
+
Mixin_Call::Mixin_Call(const Mixin_Call* ptr)
|
535
|
+
: Has_Block(ptr),
|
536
|
+
name_(ptr->name_),
|
537
|
+
arguments_(ptr->arguments_),
|
538
|
+
block_parameters_(ptr->block_parameters_)
|
539
|
+
{ }
|
540
|
+
|
541
|
+
/////////////////////////////////////////////////////////////////////////
|
542
|
+
/////////////////////////////////////////////////////////////////////////
|
543
|
+
|
544
|
+
Content::Content(ParserState pstate, Arguments_Obj args)
|
545
|
+
: Statement(pstate),
|
546
|
+
arguments_(args)
|
547
|
+
{ statement_type(CONTENT); }
|
548
|
+
Content::Content(const Content* ptr)
|
549
|
+
: Statement(ptr),
|
550
|
+
arguments_(ptr->arguments_)
|
551
|
+
{ statement_type(CONTENT); }
|
552
|
+
|
553
|
+
/////////////////////////////////////////////////////////////////////////
|
554
|
+
/////////////////////////////////////////////////////////////////////////
|
555
|
+
|
556
|
+
Expression::Expression(ParserState pstate, bool d, bool e, bool i, Type ct)
|
557
|
+
: AST_Node(pstate),
|
558
|
+
is_delayed_(d),
|
559
|
+
is_expanded_(e),
|
560
|
+
is_interpolant_(i),
|
561
|
+
concrete_type_(ct)
|
562
|
+
{ }
|
563
|
+
|
564
|
+
Expression::Expression(const Expression* ptr)
|
565
|
+
: AST_Node(ptr),
|
566
|
+
is_delayed_(ptr->is_delayed_),
|
567
|
+
is_expanded_(ptr->is_expanded_),
|
568
|
+
is_interpolant_(ptr->is_interpolant_),
|
569
|
+
concrete_type_(ptr->concrete_type_)
|
570
|
+
{ }
|
571
|
+
|
572
|
+
/////////////////////////////////////////////////////////////////////////
|
573
|
+
/////////////////////////////////////////////////////////////////////////
|
574
|
+
|
575
|
+
Unary_Expression::Unary_Expression(ParserState pstate, Type t, Expression_Obj o)
|
576
|
+
: Expression(pstate), optype_(t), operand_(o), hash_(0)
|
577
|
+
{ }
|
578
|
+
Unary_Expression::Unary_Expression(const Unary_Expression* ptr)
|
579
|
+
: Expression(ptr),
|
580
|
+
optype_(ptr->optype_),
|
581
|
+
operand_(ptr->operand_),
|
582
|
+
hash_(ptr->hash_)
|
583
|
+
{ }
|
584
|
+
const std::string Unary_Expression::type_name() {
|
585
|
+
switch (optype_) {
|
586
|
+
case PLUS: return "plus";
|
587
|
+
case MINUS: return "minus";
|
588
|
+
case SLASH: return "slash";
|
589
|
+
case NOT: return "not";
|
590
|
+
default: return "invalid";
|
591
|
+
}
|
592
|
+
}
|
593
|
+
bool Unary_Expression::operator==(const Expression& rhs) const
|
594
|
+
{
|
595
|
+
try
|
596
|
+
{
|
597
|
+
const Unary_Expression* m = Cast<Unary_Expression>(&rhs);
|
598
|
+
if (m == 0) return false;
|
599
|
+
return type() == m->type() &&
|
600
|
+
*operand() == *m->operand();
|
601
|
+
}
|
602
|
+
catch (std::bad_cast&)
|
603
|
+
{
|
604
|
+
return false;
|
1669
605
|
}
|
1670
|
-
|
606
|
+
catch (...) { throw; }
|
1671
607
|
}
|
1672
|
-
|
1673
|
-
void Selector_List::populate_extends(Selector_List_Obj extendee, Subset_Map& extends)
|
608
|
+
size_t Unary_Expression::hash() const
|
1674
609
|
{
|
610
|
+
if (hash_ == 0) {
|
611
|
+
hash_ = std::hash<size_t>()(optype_);
|
612
|
+
hash_combine(hash_, operand()->hash());
|
613
|
+
};
|
614
|
+
return hash_;
|
615
|
+
}
|
1675
616
|
|
1676
|
-
|
1677
|
-
|
1678
|
-
Complex_Selector_Obj c = complex_sel;
|
1679
|
-
|
1680
|
-
|
1681
|
-
// Ignore any parent selectors, until we find the first non Selectorerence head
|
1682
|
-
Compound_Selector_Obj compound_sel = c->head();
|
1683
|
-
Complex_Selector_Obj pIter = complex_sel;
|
1684
|
-
while (pIter) {
|
1685
|
-
Compound_Selector_Obj pHead = pIter->head();
|
1686
|
-
if (pHead && Cast<Parent_Selector>(pHead->elements()[0]) == NULL) {
|
1687
|
-
compound_sel = pHead;
|
1688
|
-
break;
|
1689
|
-
}
|
1690
|
-
|
1691
|
-
pIter = pIter->tail();
|
1692
|
-
}
|
1693
|
-
|
1694
|
-
if (!pIter->head() || pIter->tail()) {
|
1695
|
-
coreError("nested selectors may not be extended", c->pstate());
|
1696
|
-
}
|
1697
|
-
|
1698
|
-
compound_sel->is_optional(extendee->is_optional());
|
617
|
+
/////////////////////////////////////////////////////////////////////////
|
618
|
+
/////////////////////////////////////////////////////////////////////////
|
1699
619
|
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
620
|
+
Argument::Argument(ParserState pstate, Expression_Obj val, std::string n, bool rest, bool keyword)
|
621
|
+
: Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)
|
622
|
+
{
|
623
|
+
if (!name_.empty() && is_rest_argument_) {
|
624
|
+
coreError("variable-length argument may not be passed by name", pstate_);
|
1703
625
|
}
|
1704
|
-
}
|
1705
|
-
|
1706
|
-
|
626
|
+
}
|
627
|
+
Argument::Argument(const Argument* ptr)
|
628
|
+
: Expression(ptr),
|
629
|
+
value_(ptr->value_),
|
630
|
+
name_(ptr->name_),
|
631
|
+
is_rest_argument_(ptr->is_rest_argument_),
|
632
|
+
is_keyword_argument_(ptr->is_keyword_argument_),
|
633
|
+
hash_(ptr->hash_)
|
1707
634
|
{
|
1708
|
-
|
1709
|
-
|
635
|
+
if (!name_.empty() && is_rest_argument_) {
|
636
|
+
coreError("variable-length argument may not be passed by name", pstate_);
|
637
|
+
}
|
1710
638
|
}
|
1711
639
|
|
1712
|
-
|
640
|
+
void Argument::set_delayed(bool delayed)
|
1713
641
|
{
|
1714
|
-
|
1715
|
-
|
642
|
+
if (value_) value_->set_delayed(delayed);
|
643
|
+
is_delayed(delayed);
|
644
|
+
}
|
1716
645
|
|
1717
|
-
|
1718
|
-
|
646
|
+
bool Argument::operator==(const Expression& rhs) const
|
647
|
+
{
|
648
|
+
try
|
1719
649
|
{
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
break;
|
1728
|
-
}
|
1729
|
-
}
|
1730
|
-
if (!found) result->append((*this)[i]);
|
650
|
+
const Argument* m = Cast<Argument>(&rhs);
|
651
|
+
if (!(m && name() == m->name())) return false;
|
652
|
+
return *value() == *m->value();
|
653
|
+
}
|
654
|
+
catch (std::bad_cast&)
|
655
|
+
{
|
656
|
+
return false;
|
1731
657
|
}
|
658
|
+
catch (...) { throw; }
|
659
|
+
}
|
1732
660
|
|
1733
|
-
|
661
|
+
size_t Argument::hash() const
|
662
|
+
{
|
663
|
+
if (hash_ == 0) {
|
664
|
+
hash_ = std::hash<std::string>()(name());
|
665
|
+
hash_combine(hash_, value()->hash());
|
666
|
+
}
|
667
|
+
return hash_;
|
1734
668
|
}
|
1735
669
|
|
1736
|
-
|
670
|
+
/////////////////////////////////////////////////////////////////////////
|
671
|
+
/////////////////////////////////////////////////////////////////////////
|
672
|
+
|
673
|
+
Arguments::Arguments(ParserState pstate)
|
674
|
+
: Expression(pstate),
|
675
|
+
Vectorized<Argument_Obj>(),
|
676
|
+
has_named_arguments_(false),
|
677
|
+
has_rest_argument_(false),
|
678
|
+
has_keyword_argument_(false)
|
679
|
+
{ }
|
680
|
+
Arguments::Arguments(const Arguments* ptr)
|
681
|
+
: Expression(ptr),
|
682
|
+
Vectorized<Argument_Obj>(*ptr),
|
683
|
+
has_named_arguments_(ptr->has_named_arguments_),
|
684
|
+
has_rest_argument_(ptr->has_rest_argument_),
|
685
|
+
has_keyword_argument_(ptr->has_keyword_argument_)
|
686
|
+
{ }
|
687
|
+
|
688
|
+
void Arguments::set_delayed(bool delayed)
|
1737
689
|
{
|
1738
|
-
for (
|
1739
|
-
|
690
|
+
for (Argument_Obj arg : elements()) {
|
691
|
+
if (arg) arg->set_delayed(delayed);
|
1740
692
|
}
|
693
|
+
is_delayed(delayed);
|
1741
694
|
}
|
1742
695
|
|
1743
696
|
Argument_Obj Arguments::get_rest_argument()
|
@@ -1749,7 +702,7 @@ namespace Sass {
|
|
1749
702
|
}
|
1750
703
|
}
|
1751
704
|
}
|
1752
|
-
return
|
705
|
+
return {};
|
1753
706
|
}
|
1754
707
|
|
1755
708
|
Argument_Obj Arguments::get_keyword_argument()
|
@@ -1761,7 +714,7 @@ namespace Sass {
|
|
1761
714
|
}
|
1762
715
|
}
|
1763
716
|
}
|
1764
|
-
return
|
717
|
+
return {};
|
1765
718
|
}
|
1766
719
|
|
1767
720
|
void Arguments::adjust_after_pushing(Argument_Obj a)
|
@@ -1797,397 +750,185 @@ namespace Sass {
|
|
1797
750
|
}
|
1798
751
|
}
|
1799
752
|
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
}
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
753
|
+
/////////////////////////////////////////////////////////////////////////
|
754
|
+
/////////////////////////////////////////////////////////////////////////
|
755
|
+
|
756
|
+
Media_Query::Media_Query(ParserState pstate, String_Obj t, size_t s, bool n, bool r)
|
757
|
+
: Expression(pstate), Vectorized<Media_Query_Expression_Obj>(s),
|
758
|
+
media_type_(t), is_negated_(n), is_restricted_(r)
|
759
|
+
{ }
|
760
|
+
Media_Query::Media_Query(const Media_Query* ptr)
|
761
|
+
: Expression(ptr),
|
762
|
+
Vectorized<Media_Query_Expression_Obj>(*ptr),
|
763
|
+
media_type_(ptr->media_type_),
|
764
|
+
is_negated_(ptr->is_negated_),
|
765
|
+
is_restricted_(ptr->is_restricted_)
|
766
|
+
{ }
|
767
|
+
|
768
|
+
/////////////////////////////////////////////////////////////////////////
|
769
|
+
/////////////////////////////////////////////////////////////////////////
|
770
|
+
|
771
|
+
Media_Query_Expression::Media_Query_Expression(ParserState pstate,
|
772
|
+
Expression_Obj f, Expression_Obj v, bool i)
|
773
|
+
: Expression(pstate), feature_(f), value_(v), is_interpolated_(i)
|
774
|
+
{ }
|
775
|
+
Media_Query_Expression::Media_Query_Expression(const Media_Query_Expression* ptr)
|
776
|
+
: Expression(ptr),
|
777
|
+
feature_(ptr->feature_),
|
778
|
+
value_(ptr->value_),
|
779
|
+
is_interpolated_(ptr->is_interpolated_)
|
780
|
+
{ }
|
781
|
+
|
782
|
+
/////////////////////////////////////////////////////////////////////////
|
783
|
+
/////////////////////////////////////////////////////////////////////////
|
784
|
+
|
785
|
+
At_Root_Query::At_Root_Query(ParserState pstate, Expression_Obj f, Expression_Obj v, bool i)
|
786
|
+
: Expression(pstate), feature_(f), value_(v)
|
787
|
+
{ }
|
788
|
+
At_Root_Query::At_Root_Query(const At_Root_Query* ptr)
|
789
|
+
: Expression(ptr),
|
790
|
+
feature_(ptr->feature_),
|
791
|
+
value_(ptr->value_)
|
792
|
+
{ }
|
1815
793
|
|
1816
|
-
|
1817
|
-
: Value(pstate),
|
1818
|
-
Units(),
|
1819
|
-
value_(val),
|
1820
|
-
zero_(zero),
|
1821
|
-
hash_(0)
|
794
|
+
bool At_Root_Query::exclude(std::string str)
|
1822
795
|
{
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
if (r == std::string::npos) break;
|
1835
|
-
// ToDo: should error for multiple slashes
|
1836
|
-
// if (!nominator && u[r] == '/') error(...)
|
1837
|
-
if (u[r] == '/')
|
1838
|
-
nominator = false;
|
1839
|
-
// strange math parsing?
|
1840
|
-
// else if (u[r] == '*')
|
1841
|
-
// nominator = true;
|
1842
|
-
l = r + 1;
|
796
|
+
bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
|
797
|
+
List* l = static_cast<List*>(value().ptr());
|
798
|
+
std::string v;
|
799
|
+
|
800
|
+
if (with)
|
801
|
+
{
|
802
|
+
if (!l || l->length() == 0) return str.compare("rule") != 0;
|
803
|
+
for (size_t i = 0, L = l->length(); i < L; ++i)
|
804
|
+
{
|
805
|
+
v = unquote((*l)[i]->to_string());
|
806
|
+
if (v.compare("all") == 0 || v == str) return false;
|
1843
807
|
}
|
808
|
+
return true;
|
809
|
+
}
|
810
|
+
else
|
811
|
+
{
|
812
|
+
if (!l || !l->length()) return str.compare("rule") == 0;
|
813
|
+
for (size_t i = 0, L = l->length(); i < L; ++i)
|
814
|
+
{
|
815
|
+
v = unquote((*l)[i]->to_string());
|
816
|
+
if (v.compare("all") == 0 || v == str) return true;
|
817
|
+
}
|
818
|
+
return false;
|
1844
819
|
}
|
1845
|
-
concrete_type(NUMBER);
|
1846
|
-
}
|
1847
|
-
|
1848
|
-
// cancel out unnecessary units
|
1849
|
-
void Number::reduce()
|
1850
|
-
{
|
1851
|
-
// apply conversion factor
|
1852
|
-
value_ *= this->Units::reduce();
|
1853
820
|
}
|
1854
821
|
|
1855
|
-
|
1856
|
-
|
1857
|
-
// apply conversion factor
|
1858
|
-
value_ *= this->Units::normalize();
|
1859
|
-
}
|
822
|
+
/////////////////////////////////////////////////////////////////////////
|
823
|
+
/////////////////////////////////////////////////////////////////////////
|
1860
824
|
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
}
|
825
|
+
At_Root_Block::At_Root_Block(ParserState pstate, Block_Obj b, At_Root_Query_Obj e)
|
826
|
+
: Has_Block(pstate, b), expression_(e)
|
827
|
+
{ statement_type(ATROOT); }
|
828
|
+
At_Root_Block::At_Root_Block(const At_Root_Block* ptr)
|
829
|
+
: Has_Block(ptr), expression_(ptr->expression_)
|
830
|
+
{ statement_type(ATROOT); }
|
1868
831
|
|
1869
|
-
bool
|
1870
|
-
|
1871
|
-
if (Custom_Error_Ptr_Const r = Cast<Custom_Error>(&rhs)) {
|
1872
|
-
return message() == r->message();
|
1873
|
-
}
|
1874
|
-
return false;
|
832
|
+
bool At_Root_Block::bubbles() {
|
833
|
+
return true;
|
1875
834
|
}
|
1876
835
|
|
1877
|
-
bool
|
1878
|
-
|
1879
|
-
|
1880
|
-
return
|
836
|
+
bool At_Root_Block::exclude_node(Statement_Obj s) {
|
837
|
+
if (expression() == 0)
|
838
|
+
{
|
839
|
+
return s->statement_type() == Statement::RULESET;
|
1881
840
|
}
|
1882
|
-
return false;
|
1883
|
-
}
|
1884
841
|
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
842
|
+
if (s->statement_type() == Statement::DIRECTIVE)
|
843
|
+
{
|
844
|
+
if (Directive_Obj dir = Cast<Directive>(s))
|
845
|
+
{
|
846
|
+
std::string keyword(dir->keyword());
|
847
|
+
if (keyword.length() > 0) keyword.erase(0, 1);
|
848
|
+
return expression()->exclude(keyword);
|
849
|
+
}
|
1893
850
|
}
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
NEAR_EQUAL(l.value(), r.value());
|
1898
|
-
}
|
1899
|
-
|
1900
|
-
bool Number::operator< (const Number& rhs) const
|
1901
|
-
{
|
1902
|
-
Number l(*this), r(rhs); l.reduce(); r.reduce();
|
1903
|
-
size_t lhs_units = l.numerators.size() + l.denominators.size();
|
1904
|
-
size_t rhs_units = r.numerators.size() + r.denominators.size();
|
1905
|
-
// unitless and only having one unit seems equivalent (will change in future)
|
1906
|
-
if (!lhs_units || !rhs_units) {
|
1907
|
-
return l.value() < r.value();
|
851
|
+
if (s->statement_type() == Statement::MEDIA)
|
852
|
+
{
|
853
|
+
return expression()->exclude("media");
|
1908
854
|
}
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
/* ToDo: do we always get usefull backtraces? */
|
1913
|
-
throw Exception::IncompatibleUnits(rhs, *this);
|
855
|
+
if (s->statement_type() == Statement::RULESET)
|
856
|
+
{
|
857
|
+
return expression()->exclude("rule");
|
1914
858
|
}
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
bool String_Quoted::operator== (const Expression& rhs) const
|
1920
|
-
{
|
1921
|
-
if (String_Quoted_Ptr_Const qstr = Cast<String_Quoted>(&rhs)) {
|
1922
|
-
return (value() == qstr->value());
|
1923
|
-
} else if (String_Constant_Ptr_Const cstr = Cast<String_Constant>(&rhs)) {
|
1924
|
-
return (value() == cstr->value());
|
859
|
+
if (s->statement_type() == Statement::SUPPORTS)
|
860
|
+
{
|
861
|
+
return expression()->exclude("supports");
|
1925
862
|
}
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
bool String_Constant::is_invisible() const {
|
1930
|
-
return value_.empty() && quote_mark_ == 0;
|
1931
|
-
}
|
1932
|
-
|
1933
|
-
bool String_Constant::operator== (const Expression& rhs) const
|
1934
|
-
{
|
1935
|
-
if (String_Quoted_Ptr_Const qstr = Cast<String_Quoted>(&rhs)) {
|
1936
|
-
return (value() == qstr->value());
|
1937
|
-
} else if (String_Constant_Ptr_Const cstr = Cast<String_Constant>(&rhs)) {
|
1938
|
-
return (value() == cstr->value());
|
863
|
+
if (Directive_Obj dir = Cast<Directive>(s))
|
864
|
+
{
|
865
|
+
if (dir->is_keyframes()) return expression()->exclude("keyframes");
|
1939
866
|
}
|
1940
867
|
return false;
|
1941
868
|
}
|
1942
869
|
|
1943
|
-
|
1944
|
-
|
1945
|
-
return length() && first()->is_left_interpolant();
|
1946
|
-
}
|
1947
|
-
bool String_Schema::is_right_interpolant(void) const
|
1948
|
-
{
|
1949
|
-
return length() && last()->is_right_interpolant();
|
1950
|
-
}
|
870
|
+
/////////////////////////////////////////////////////////////////////////
|
871
|
+
/////////////////////////////////////////////////////////////////////////
|
1951
872
|
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
}
|
1962
|
-
return true;
|
1963
|
-
}
|
1964
|
-
return false;
|
1965
|
-
}
|
873
|
+
Parameter::Parameter(ParserState pstate, std::string n, Expression_Obj def, bool rest)
|
874
|
+
: AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)
|
875
|
+
{ }
|
876
|
+
Parameter::Parameter(const Parameter* ptr)
|
877
|
+
: AST_Node(ptr),
|
878
|
+
name_(ptr->name_),
|
879
|
+
default_value_(ptr->default_value_),
|
880
|
+
is_rest_parameter_(ptr->is_rest_parameter_)
|
881
|
+
{ }
|
1966
882
|
|
1967
|
-
|
1968
|
-
|
1969
|
-
if (Boolean_Ptr_Const r = Cast<Boolean>(&rhs)) {
|
1970
|
-
return (value() == r->value());
|
1971
|
-
}
|
1972
|
-
return false;
|
1973
|
-
}
|
883
|
+
/////////////////////////////////////////////////////////////////////////
|
884
|
+
/////////////////////////////////////////////////////////////////////////
|
1974
885
|
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
886
|
+
Parameters::Parameters(ParserState pstate)
|
887
|
+
: AST_Node(pstate),
|
888
|
+
Vectorized<Parameter_Obj>(),
|
889
|
+
has_optional_parameters_(false),
|
890
|
+
has_rest_parameter_(false)
|
891
|
+
{ }
|
892
|
+
Parameters::Parameters(const Parameters* ptr)
|
893
|
+
: AST_Node(ptr),
|
894
|
+
Vectorized<Parameter_Obj>(*ptr),
|
895
|
+
has_optional_parameters_(ptr->has_optional_parameters_),
|
896
|
+
has_rest_parameter_(ptr->has_rest_parameter_)
|
897
|
+
{ }
|
1985
898
|
|
1986
|
-
|
899
|
+
void Parameters::adjust_after_pushing(Parameter_Obj p)
|
1987
900
|
{
|
1988
|
-
if (
|
1989
|
-
if (
|
1990
|
-
|
1991
|
-
if (is_bracketed() != r->is_bracketed()) return false;
|
1992
|
-
for (size_t i = 0, L = length(); i < L; ++i) {
|
1993
|
-
Expression_Obj rv = r->at(i);
|
1994
|
-
Expression_Obj lv = this->at(i);
|
1995
|
-
if (!lv || !rv) return false;
|
1996
|
-
if (!(*lv == *rv)) return false;
|
901
|
+
if (p->default_value()) {
|
902
|
+
if (has_rest_parameter()) {
|
903
|
+
coreError("optional parameters may not be combined with variable-length parameters", p->pstate());
|
1997
904
|
}
|
1998
|
-
|
905
|
+
has_optional_parameters(true);
|
1999
906
|
}
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
bool Map::operator== (const Expression& rhs) const
|
2004
|
-
{
|
2005
|
-
if (Map_Ptr_Const r = Cast<Map>(&rhs)) {
|
2006
|
-
if (length() != r->length()) return false;
|
2007
|
-
for (auto key : keys()) {
|
2008
|
-
Expression_Obj lv = at(key);
|
2009
|
-
Expression_Obj rv = r->at(key);
|
2010
|
-
if (!rv || !lv) return false;
|
2011
|
-
if (!(*lv == *rv)) return false;
|
907
|
+
else if (p->is_rest_parameter()) {
|
908
|
+
if (has_rest_parameter()) {
|
909
|
+
coreError("functions and mixins cannot have more than one variable-length parameter", p->pstate());
|
2012
910
|
}
|
2013
|
-
|
2014
|
-
}
|
2015
|
-
return false;
|
2016
|
-
}
|
2017
|
-
|
2018
|
-
bool Null::operator== (const Expression& rhs) const
|
2019
|
-
{
|
2020
|
-
return rhs.concrete_type() == NULL_VAL;
|
2021
|
-
}
|
2022
|
-
|
2023
|
-
bool Function::operator== (const Expression& rhs) const
|
2024
|
-
{
|
2025
|
-
if (Function_Ptr_Const r = Cast<Function>(&rhs)) {
|
2026
|
-
Definition_Ptr_Const d1 = Cast<Definition>(definition());
|
2027
|
-
Definition_Ptr_Const d2 = Cast<Definition>(r->definition());
|
2028
|
-
return d1 && d2 && d1 == d2 && is_css() == r->is_css();
|
911
|
+
has_rest_parameter(true);
|
2029
912
|
}
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
size_t List::size() const {
|
2034
|
-
if (!is_arglist_) return length();
|
2035
|
-
// arglist expects a list of arguments
|
2036
|
-
// so we need to break before keywords
|
2037
|
-
for (size_t i = 0, L = length(); i < L; ++i) {
|
2038
|
-
Expression_Obj obj = this->at(i);
|
2039
|
-
if (Argument_Ptr arg = Cast<Argument>(obj)) {
|
2040
|
-
if (!arg->name().empty()) return i;
|
913
|
+
else {
|
914
|
+
if (has_rest_parameter()) {
|
915
|
+
coreError("required parameters must precede variable-length parameters", p->pstate());
|
2041
916
|
}
|
2042
|
-
|
2043
|
-
|
2044
|
-
}
|
2045
|
-
|
2046
|
-
Expression_Obj Hashed::at(Expression_Obj k) const
|
2047
|
-
{
|
2048
|
-
if (elements_.count(k))
|
2049
|
-
{ return elements_.at(k); }
|
2050
|
-
else { return NULL; }
|
2051
|
-
}
|
2052
|
-
|
2053
|
-
bool Binary_Expression::is_left_interpolant(void) const
|
2054
|
-
{
|
2055
|
-
return is_interpolant() || (left() && left()->is_left_interpolant());
|
2056
|
-
}
|
2057
|
-
bool Binary_Expression::is_right_interpolant(void) const
|
2058
|
-
{
|
2059
|
-
return is_interpolant() || (right() && right()->is_right_interpolant());
|
2060
|
-
}
|
2061
|
-
|
2062
|
-
const std::string AST_Node::to_string(Sass_Inspect_Options opt) const
|
2063
|
-
{
|
2064
|
-
Sass_Output_Options out(opt);
|
2065
|
-
Emitter emitter(out);
|
2066
|
-
Inspect i(emitter);
|
2067
|
-
i.in_declaration = true;
|
2068
|
-
// ToDo: inspect should be const
|
2069
|
-
const_cast<AST_Node_Ptr>(this)->perform(&i);
|
2070
|
-
return i.get_buffer();
|
2071
|
-
}
|
2072
|
-
|
2073
|
-
const std::string AST_Node::to_string() const
|
2074
|
-
{
|
2075
|
-
return to_string({ NESTED, 5 });
|
2076
|
-
}
|
2077
|
-
|
2078
|
-
std::string String_Quoted::inspect() const
|
2079
|
-
{
|
2080
|
-
return quote(value_, '*');
|
2081
|
-
}
|
2082
|
-
|
2083
|
-
std::string String_Constant::inspect() const
|
2084
|
-
{
|
2085
|
-
return quote(value_, '*');
|
2086
|
-
}
|
2087
|
-
|
2088
|
-
bool Declaration::is_invisible() const
|
2089
|
-
{
|
2090
|
-
if (is_custom_property()) return false;
|
2091
|
-
|
2092
|
-
return !(value_ && value_->concrete_type() != Expression::NULL_VAL);
|
2093
|
-
}
|
2094
|
-
|
2095
|
-
//////////////////////////////////////////////////////////////////////////////////////////
|
2096
|
-
// Additional method on Lists to retrieve values directly or from an encompassed Argument.
|
2097
|
-
//////////////////////////////////////////////////////////////////////////////////////////
|
2098
|
-
Expression_Obj List::value_at_index(size_t i) {
|
2099
|
-
Expression_Obj obj = this->at(i);
|
2100
|
-
if (is_arglist_) {
|
2101
|
-
if (Argument_Ptr arg = Cast<Argument>(obj)) {
|
2102
|
-
return arg->value();
|
2103
|
-
} else {
|
2104
|
-
return obj;
|
917
|
+
if (has_optional_parameters()) {
|
918
|
+
coreError("required parameters must precede optional parameters", p->pstate());
|
2105
919
|
}
|
2106
|
-
} else {
|
2107
|
-
return obj;
|
2108
920
|
}
|
2109
921
|
}
|
2110
922
|
|
2111
|
-
|
2112
|
-
|
2113
|
-
//////////////////////////////////////////////////////////////////////////////////////////
|
2114
|
-
List_Obj Map::to_list(ParserState& pstate) {
|
2115
|
-
List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);
|
2116
|
-
|
2117
|
-
for (auto key : keys()) {
|
2118
|
-
List_Obj l = SASS_MEMORY_NEW(List, pstate, 2);
|
2119
|
-
l->append(key);
|
2120
|
-
l->append(at(key));
|
2121
|
-
ret->append(l);
|
2122
|
-
}
|
2123
|
-
|
2124
|
-
return ret;
|
2125
|
-
}
|
923
|
+
/////////////////////////////////////////////////////////////////////////
|
924
|
+
/////////////////////////////////////////////////////////////////////////
|
2126
925
|
|
2127
|
-
//////////////////////////////////////////////////////////////////////////////////////////
|
2128
|
-
// Copy implementations
|
2129
|
-
//////////////////////////////////////////////////////////////////////////////////////////
|
2130
|
-
|
2131
|
-
#ifdef DEBUG_SHARED_PTR
|
2132
|
-
|
2133
|
-
#define IMPLEMENT_AST_OPERATORS(klass) \
|
2134
|
-
klass##_Ptr klass::copy(std::string file, size_t line) const { \
|
2135
|
-
klass##_Ptr cpy = new klass(this); \
|
2136
|
-
cpy->trace(file, line); \
|
2137
|
-
return cpy; \
|
2138
|
-
} \
|
2139
|
-
klass##_Ptr klass::clone(std::string file, size_t line) const { \
|
2140
|
-
klass##_Ptr cpy = copy(file, line); \
|
2141
|
-
cpy->cloneChildren(); \
|
2142
|
-
return cpy; \
|
2143
|
-
} \
|
2144
|
-
|
2145
|
-
#else
|
2146
|
-
|
2147
|
-
#define IMPLEMENT_AST_OPERATORS(klass) \
|
2148
|
-
klass##_Ptr klass::copy() const { \
|
2149
|
-
return new klass(this); \
|
2150
|
-
} \
|
2151
|
-
klass##_Ptr klass::clone() const { \
|
2152
|
-
klass##_Ptr cpy = copy(); \
|
2153
|
-
cpy->cloneChildren(); \
|
2154
|
-
return cpy; \
|
2155
|
-
} \
|
2156
|
-
|
2157
|
-
#endif
|
2158
|
-
|
2159
|
-
IMPLEMENT_AST_OPERATORS(Supports_Operator);
|
2160
|
-
IMPLEMENT_AST_OPERATORS(Supports_Negation);
|
2161
|
-
IMPLEMENT_AST_OPERATORS(Compound_Selector);
|
2162
|
-
IMPLEMENT_AST_OPERATORS(Complex_Selector);
|
2163
|
-
IMPLEMENT_AST_OPERATORS(Element_Selector);
|
2164
|
-
IMPLEMENT_AST_OPERATORS(Class_Selector);
|
2165
|
-
IMPLEMENT_AST_OPERATORS(Id_Selector);
|
2166
|
-
IMPLEMENT_AST_OPERATORS(Pseudo_Selector);
|
2167
|
-
IMPLEMENT_AST_OPERATORS(Wrapped_Selector);
|
2168
|
-
IMPLEMENT_AST_OPERATORS(Selector_List);
|
2169
926
|
IMPLEMENT_AST_OPERATORS(Ruleset);
|
2170
927
|
IMPLEMENT_AST_OPERATORS(Media_Block);
|
2171
|
-
IMPLEMENT_AST_OPERATORS(Custom_Warning);
|
2172
|
-
IMPLEMENT_AST_OPERATORS(Custom_Error);
|
2173
|
-
IMPLEMENT_AST_OPERATORS(List);
|
2174
|
-
IMPLEMENT_AST_OPERATORS(Map);
|
2175
|
-
IMPLEMENT_AST_OPERATORS(Function);
|
2176
|
-
IMPLEMENT_AST_OPERATORS(Number);
|
2177
|
-
IMPLEMENT_AST_OPERATORS(Binary_Expression);
|
2178
|
-
IMPLEMENT_AST_OPERATORS(String_Schema);
|
2179
|
-
IMPLEMENT_AST_OPERATORS(String_Constant);
|
2180
|
-
IMPLEMENT_AST_OPERATORS(String_Quoted);
|
2181
|
-
IMPLEMENT_AST_OPERATORS(Boolean);
|
2182
|
-
IMPLEMENT_AST_OPERATORS(Color);
|
2183
|
-
IMPLEMENT_AST_OPERATORS(Null);
|
2184
|
-
IMPLEMENT_AST_OPERATORS(Parent_Selector);
|
2185
928
|
IMPLEMENT_AST_OPERATORS(Import);
|
2186
929
|
IMPLEMENT_AST_OPERATORS(Import_Stub);
|
2187
|
-
IMPLEMENT_AST_OPERATORS(Function_Call);
|
2188
930
|
IMPLEMENT_AST_OPERATORS(Directive);
|
2189
931
|
IMPLEMENT_AST_OPERATORS(At_Root_Block);
|
2190
|
-
IMPLEMENT_AST_OPERATORS(Supports_Block);
|
2191
932
|
IMPLEMENT_AST_OPERATORS(While);
|
2192
933
|
IMPLEMENT_AST_OPERATORS(Each);
|
2193
934
|
IMPLEMENT_AST_OPERATORS(For);
|
@@ -2202,25 +943,21 @@ namespace Sass {
|
|
2202
943
|
IMPLEMENT_AST_OPERATORS(Assignment);
|
2203
944
|
IMPLEMENT_AST_OPERATORS(Return);
|
2204
945
|
IMPLEMENT_AST_OPERATORS(At_Root_Query);
|
2205
|
-
IMPLEMENT_AST_OPERATORS(Variable);
|
2206
946
|
IMPLEMENT_AST_OPERATORS(Comment);
|
2207
|
-
IMPLEMENT_AST_OPERATORS(Attribute_Selector);
|
2208
|
-
IMPLEMENT_AST_OPERATORS(Supports_Interpolation);
|
2209
|
-
IMPLEMENT_AST_OPERATORS(Supports_Declaration);
|
2210
|
-
IMPLEMENT_AST_OPERATORS(Supports_Condition);
|
2211
947
|
IMPLEMENT_AST_OPERATORS(Parameters);
|
2212
948
|
IMPLEMENT_AST_OPERATORS(Parameter);
|
2213
949
|
IMPLEMENT_AST_OPERATORS(Arguments);
|
2214
950
|
IMPLEMENT_AST_OPERATORS(Argument);
|
2215
951
|
IMPLEMENT_AST_OPERATORS(Unary_Expression);
|
2216
|
-
IMPLEMENT_AST_OPERATORS(Function_Call_Schema);
|
2217
952
|
IMPLEMENT_AST_OPERATORS(Block);
|
2218
953
|
IMPLEMENT_AST_OPERATORS(Content);
|
2219
954
|
IMPLEMENT_AST_OPERATORS(Trace);
|
2220
955
|
IMPLEMENT_AST_OPERATORS(Keyframe_Rule);
|
2221
956
|
IMPLEMENT_AST_OPERATORS(Bubble);
|
2222
|
-
IMPLEMENT_AST_OPERATORS(Selector_Schema);
|
2223
|
-
IMPLEMENT_AST_OPERATORS(Placeholder_Selector);
|
2224
957
|
IMPLEMENT_AST_OPERATORS(Definition);
|
2225
958
|
IMPLEMENT_AST_OPERATORS(Declaration);
|
959
|
+
|
960
|
+
/////////////////////////////////////////////////////////////////////////
|
961
|
+
/////////////////////////////////////////////////////////////////////////
|
962
|
+
|
2226
963
|
}
|