sassc 2.0.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.gitmodules +1 -1
- data/.travis.yml +9 -3
- data/CHANGELOG.md +36 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +1 -1
- data/Rakefile +43 -7
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/include/sass/base.h +9 -1
- data/ext/libsass/include/sass/context.h +5 -1
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +755 -2028
- data/ext/libsass/src/ast.hpp +492 -2477
- data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +70 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +275 -0
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +1043 -0
- data/ext/libsass/src/ast_selectors.hpp +522 -0
- data/ext/libsass/src/ast_supports.cpp +114 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +1154 -0
- data/ext/libsass/src/ast_values.hpp +498 -0
- data/ext/libsass/src/backtrace.cpp +11 -7
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +5 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +35 -34
- data/ext/libsass/src/bind.hpp +3 -1
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +83 -88
- data/ext/libsass/src/check_nesting.hpp +39 -34
- data/ext/libsass/src/color_maps.cpp +168 -164
- data/ext/libsass/src/color_maps.hpp +152 -160
- data/ext/libsass/src/constants.cpp +20 -0
- data/ext/libsass/src/constants.hpp +19 -0
- data/ext/libsass/src/context.cpp +104 -121
- data/ext/libsass/src/context.hpp +43 -55
- data/ext/libsass/src/cssize.cpp +103 -188
- data/ext/libsass/src/cssize.hpp +45 -51
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +524 -361
- data/ext/libsass/src/emitter.cpp +26 -26
- data/ext/libsass/src/emitter.hpp +20 -18
- data/ext/libsass/src/environment.cpp +41 -27
- data/ext/libsass/src/environment.hpp +33 -22
- data/ext/libsass/src/error_handling.cpp +92 -94
- data/ext/libsass/src/error_handling.hpp +73 -50
- data/ext/libsass/src/eval.cpp +380 -515
- data/ext/libsass/src/eval.hpp +64 -57
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +322 -263
- data/ext/libsass/src/expand.hpp +55 -39
- data/ext/libsass/src/extender.cpp +1188 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +134 -88
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +596 -0
- data/ext/libsass/src/fn_colors.hpp +85 -0
- data/ext/libsass/src/fn_lists.cpp +285 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +244 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +227 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +205 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +268 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +158 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +253 -266
- data/ext/libsass/src/inspect.hpp +72 -74
- data/ext/libsass/src/json.cpp +2 -2
- data/ext/libsass/src/lexer.cpp +25 -84
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +27 -43
- data/ext/libsass/src/listize.hpp +14 -11
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
- data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
- data/ext/libsass/src/operation.hpp +193 -143
- data/ext/libsass/src/operators.cpp +56 -29
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +59 -75
- data/ext/libsass/src/output.hpp +15 -22
- data/ext/libsass/src/parser.cpp +662 -818
- data/ext/libsass/src/parser.hpp +96 -100
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +12 -8
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +10 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +14 -8
- data/ext/libsass/src/prelexer.hpp +9 -9
- data/ext/libsass/src/remove_placeholders.cpp +59 -57
- data/ext/libsass/src/remove_placeholders.hpp +20 -18
- data/ext/libsass/src/sass.cpp +25 -18
- data/ext/libsass/src/sass.hpp +22 -14
- data/ext/libsass/src/sass2scss.cpp +49 -18
- data/ext/libsass/src/sass_context.cpp +104 -132
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +7 -4
- data/ext/libsass/src/sass_functions.hpp +1 -1
- data/ext/libsass/src/sass_values.cpp +26 -21
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +27 -20
- data/ext/libsass/src/source_map.hpp +14 -11
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +24 -22
- data/ext/libsass/src/to_value.hpp +18 -22
- data/ext/libsass/src/units.cpp +28 -22
- data/ext/libsass/src/units.hpp +9 -8
- data/ext/libsass/src/utf8/checked.h +12 -10
- data/ext/libsass/src/utf8/core.h +3 -0
- data/ext/libsass/src/utf8_string.cpp +12 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +97 -107
- data/ext/libsass/src/util.hpp +74 -30
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +33 -24
- data/ext/libsass/src/values.hpp +2 -2
- data/lib/sassc.rb +24 -0
- data/lib/sassc/engine.rb +7 -5
- data/lib/sassc/functions_handler.rb +11 -13
- data/lib/sassc/native.rb +10 -9
- data/lib/sassc/native/native_functions_api.rb +0 -5
- data/lib/sassc/script.rb +4 -6
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +32 -12
- data/test/engine_test.rb +32 -2
- data/test/functions_test.rb +38 -1
- data/test/native_test.rb +4 -4
- metadata +95 -109
- data/ext/Rakefile +0 -3
- data/ext/libsass/.editorconfig +0 -15
- data/ext/libsass/.gitattributes +0 -2
- data/ext/libsass/.github/CONTRIBUTING.md +0 -65
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
- data/ext/libsass/.gitignore +0 -85
- data/ext/libsass/.travis.yml +0 -64
- data/ext/libsass/COPYING +0 -25
- data/ext/libsass/GNUmakefile.am +0 -88
- data/ext/libsass/INSTALL +0 -1
- data/ext/libsass/LICENSE +0 -25
- data/ext/libsass/Makefile +0 -351
- data/ext/libsass/Makefile.conf +0 -55
- data/ext/libsass/Readme.md +0 -104
- data/ext/libsass/SECURITY.md +0 -10
- data/ext/libsass/appveyor.yml +0 -91
- data/ext/libsass/configure.ac +0 -138
- data/ext/libsass/contrib/libsass.spec +0 -66
- data/ext/libsass/docs/README.md +0 -20
- data/ext/libsass/docs/api-context-example.md +0 -45
- data/ext/libsass/docs/api-context-internal.md +0 -163
- data/ext/libsass/docs/api-context.md +0 -295
- data/ext/libsass/docs/api-doc.md +0 -215
- data/ext/libsass/docs/api-function-example.md +0 -67
- data/ext/libsass/docs/api-function-internal.md +0 -8
- data/ext/libsass/docs/api-function.md +0 -74
- data/ext/libsass/docs/api-importer-example.md +0 -112
- data/ext/libsass/docs/api-importer-internal.md +0 -20
- data/ext/libsass/docs/api-importer.md +0 -86
- data/ext/libsass/docs/api-value-example.md +0 -55
- data/ext/libsass/docs/api-value-internal.md +0 -76
- data/ext/libsass/docs/api-value.md +0 -154
- data/ext/libsass/docs/build-on-darwin.md +0 -27
- data/ext/libsass/docs/build-on-gentoo.md +0 -55
- data/ext/libsass/docs/build-on-windows.md +0 -139
- data/ext/libsass/docs/build-shared-library.md +0 -35
- data/ext/libsass/docs/build-with-autotools.md +0 -78
- data/ext/libsass/docs/build-with-makefiles.md +0 -68
- data/ext/libsass/docs/build-with-mingw.md +0 -107
- data/ext/libsass/docs/build-with-visual-studio.md +0 -90
- data/ext/libsass/docs/build.md +0 -97
- data/ext/libsass/docs/compatibility-plan.md +0 -48
- data/ext/libsass/docs/contributing.md +0 -17
- data/ext/libsass/docs/custom-functions-internal.md +0 -122
- data/ext/libsass/docs/dev-ast-memory.md +0 -223
- data/ext/libsass/docs/implementations.md +0 -56
- data/ext/libsass/docs/plugins.md +0 -47
- data/ext/libsass/docs/setup-environment.md +0 -68
- data/ext/libsass/docs/source-map-internals.md +0 -51
- data/ext/libsass/docs/trace.md +0 -26
- data/ext/libsass/docs/triage.md +0 -17
- data/ext/libsass/docs/unicode.md +0 -39
- data/ext/libsass/extconf.rb +0 -6
- data/ext/libsass/include/sass/version.h.in +0 -12
- data/ext/libsass/m4/.gitkeep +0 -0
- data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
- data/ext/libsass/res/resource.rc +0 -35
- data/ext/libsass/script/bootstrap +0 -13
- data/ext/libsass/script/branding +0 -10
- data/ext/libsass/script/ci-build-libsass +0 -134
- data/ext/libsass/script/ci-build-plugin +0 -62
- data/ext/libsass/script/ci-install-compiler +0 -6
- data/ext/libsass/script/ci-install-deps +0 -20
- data/ext/libsass/script/ci-report-coverage +0 -42
- data/ext/libsass/script/spec +0 -5
- data/ext/libsass/script/tap-driver +0 -652
- data/ext/libsass/script/tap-runner +0 -1
- data/ext/libsass/script/test-leaks.pl +0 -103
- data/ext/libsass/src/GNUmakefile.am +0 -54
- data/ext/libsass/src/extend.cpp +0 -2130
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/functions.cpp +0 -2234
- data/ext/libsass/src/functions.hpp +0 -198
- data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
- data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
- data/ext/libsass/src/node.cpp +0 -319
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -149
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -55
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/ext/libsass/src/support/libsass.pc.in +0 -11
- data/ext/libsass/src/to_c.hpp +0 -39
- data/ext/libsass/test/test_node.cpp +0 -94
- data/ext/libsass/test/test_paths.cpp +0 -28
- data/ext/libsass/test/test_selector_difference.cpp +0 -25
- data/ext/libsass/test/test_specificity.cpp +0 -25
- data/ext/libsass/test/test_subset_map.cpp +0 -472
- data/ext/libsass/test/test_superselector.cpp +0 -69
- data/ext/libsass/test/test_unification.cpp +0 -31
- data/ext/libsass/version.sh +0 -10
- data/ext/libsass/win/libsass.sln +0 -39
- data/ext/libsass/win/libsass.sln.DotSettings +0 -9
- data/ext/libsass/win/libsass.targets +0 -118
- data/ext/libsass/win/libsass.vcxproj +0 -188
- data/ext/libsass/win/libsass.vcxproj.filters +0 -357
- data/lib/sassc/native/lib_c.rb +0 -21
- data/lib/tasks/libsass.rb +0 -33
data/ext/libsass/src/eval.cpp
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
1
3
|
#include "sass.hpp"
|
|
4
|
+
|
|
2
5
|
#include <cstdlib>
|
|
3
6
|
#include <cmath>
|
|
4
7
|
#include <iostream>
|
|
@@ -17,7 +20,8 @@
|
|
|
17
20
|
#include "position.hpp"
|
|
18
21
|
#include "sass/values.h"
|
|
19
22
|
#include "to_value.hpp"
|
|
20
|
-
#include "
|
|
23
|
+
#include "ast2c.hpp"
|
|
24
|
+
#include "c2ast.hpp"
|
|
21
25
|
#include "context.hpp"
|
|
22
26
|
#include "backtrace.hpp"
|
|
23
27
|
#include "lexer.hpp"
|
|
@@ -26,6 +30,8 @@
|
|
|
26
30
|
#include "expand.hpp"
|
|
27
31
|
#include "color_maps.hpp"
|
|
28
32
|
#include "sass_functions.hpp"
|
|
33
|
+
#include "error_handling.hpp"
|
|
34
|
+
#include "util_string.hpp"
|
|
29
35
|
|
|
30
36
|
namespace Sass {
|
|
31
37
|
|
|
@@ -47,14 +53,34 @@ namespace Sass {
|
|
|
47
53
|
return exp.environment();
|
|
48
54
|
}
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
const sass::string Eval::cwd()
|
|
57
|
+
{
|
|
58
|
+
return ctx.cwd();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
struct Sass_Inspect_Options& Eval::options()
|
|
62
|
+
{
|
|
63
|
+
return ctx.c_options;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
struct Sass_Compiler* Eval::compiler()
|
|
67
|
+
{
|
|
68
|
+
return ctx.c_compiler;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
EnvStack& Eval::env_stack()
|
|
51
72
|
{
|
|
52
|
-
return exp.
|
|
73
|
+
return exp.env_stack;
|
|
53
74
|
}
|
|
54
75
|
|
|
55
|
-
|
|
76
|
+
sass::vector<Sass_Callee>& Eval::callee_stack()
|
|
56
77
|
{
|
|
57
|
-
|
|
78
|
+
return ctx.callee_stack;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
Expression* Eval::operator()(Block* b)
|
|
82
|
+
{
|
|
83
|
+
Expression* val = 0;
|
|
58
84
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
|
59
85
|
val = b->at(i)->perform(this);
|
|
60
86
|
if (val) return val;
|
|
@@ -62,14 +88,20 @@ namespace Sass {
|
|
|
62
88
|
return val;
|
|
63
89
|
}
|
|
64
90
|
|
|
65
|
-
|
|
91
|
+
Expression* Eval::operator()(Assignment* a)
|
|
66
92
|
{
|
|
67
|
-
Env* env =
|
|
68
|
-
|
|
93
|
+
Env* env = environment();
|
|
94
|
+
sass::string var(a->variable());
|
|
69
95
|
if (a->is_global()) {
|
|
96
|
+
if (!env->has_global(var)) {
|
|
97
|
+
deprecated(
|
|
98
|
+
"!global assignments won't be able to declare new variables in future versions.",
|
|
99
|
+
"Consider adding `" + var + ": null` at the top level.",
|
|
100
|
+
true, a->pstate());
|
|
101
|
+
}
|
|
70
102
|
if (a->is_default()) {
|
|
71
103
|
if (env->has_global(var)) {
|
|
72
|
-
|
|
104
|
+
Expression* e = Cast<Expression>(env->get_global(var));
|
|
73
105
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
|
74
106
|
env->set_global(var, a->value()->perform(this));
|
|
75
107
|
}
|
|
@@ -88,7 +120,7 @@ namespace Sass {
|
|
|
88
120
|
while (cur && cur->is_lexical()) {
|
|
89
121
|
if (cur->has_local(var)) {
|
|
90
122
|
if (AST_Node_Obj node = cur->get_local(var)) {
|
|
91
|
-
|
|
123
|
+
Expression* e = Cast<Expression>(node);
|
|
92
124
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
|
93
125
|
cur->set_local(var, a->value()->perform(this));
|
|
94
126
|
}
|
|
@@ -104,7 +136,7 @@ namespace Sass {
|
|
|
104
136
|
}
|
|
105
137
|
else if (env->has_global(var)) {
|
|
106
138
|
if (AST_Node_Obj node = env->get_global(var)) {
|
|
107
|
-
|
|
139
|
+
Expression* e = Cast<Expression>(node);
|
|
108
140
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
|
109
141
|
env->set_global(var, a->value()->perform(this));
|
|
110
142
|
}
|
|
@@ -123,12 +155,12 @@ namespace Sass {
|
|
|
123
155
|
return 0;
|
|
124
156
|
}
|
|
125
157
|
|
|
126
|
-
|
|
158
|
+
Expression* Eval::operator()(If* i)
|
|
127
159
|
{
|
|
128
|
-
|
|
129
|
-
Env env(
|
|
130
|
-
|
|
131
|
-
|
|
160
|
+
ExpressionObj rv;
|
|
161
|
+
Env env(environment());
|
|
162
|
+
env_stack().push_back(&env);
|
|
163
|
+
ExpressionObj cond = i->predicate()->perform(this);
|
|
132
164
|
if (!cond->is_false()) {
|
|
133
165
|
rv = i->block()->perform(this);
|
|
134
166
|
}
|
|
@@ -136,21 +168,21 @@ namespace Sass {
|
|
|
136
168
|
Block_Obj alt = i->alternative();
|
|
137
169
|
if (alt) rv = alt->perform(this);
|
|
138
170
|
}
|
|
139
|
-
|
|
171
|
+
env_stack().pop_back();
|
|
140
172
|
return rv.detach();
|
|
141
173
|
}
|
|
142
174
|
|
|
143
175
|
// For does not create a new env scope
|
|
144
176
|
// But iteration vars are reset afterwards
|
|
145
|
-
|
|
177
|
+
Expression* Eval::operator()(ForRule* f)
|
|
146
178
|
{
|
|
147
|
-
|
|
148
|
-
|
|
179
|
+
sass::string variable(f->variable());
|
|
180
|
+
ExpressionObj low = f->lower_bound()->perform(this);
|
|
149
181
|
if (low->concrete_type() != Expression::NUMBER) {
|
|
150
182
|
traces.push_back(Backtrace(low->pstate()));
|
|
151
183
|
throw Exception::TypeMismatch(traces, *low, "integer");
|
|
152
184
|
}
|
|
153
|
-
|
|
185
|
+
ExpressionObj high = f->upper_bound()->perform(this);
|
|
154
186
|
if (high->concrete_type() != Expression::NUMBER) {
|
|
155
187
|
traces.push_back(Backtrace(high->pstate()));
|
|
156
188
|
throw Exception::TypeMismatch(traces, *high, "integer");
|
|
@@ -159,7 +191,7 @@ namespace Sass {
|
|
|
159
191
|
Number_Obj sass_end = Cast<Number>(high);
|
|
160
192
|
// check if units are valid for sequence
|
|
161
193
|
if (sass_start->unit() != sass_end->unit()) {
|
|
162
|
-
|
|
194
|
+
sass::ostream msg; msg << "Incompatible units: '"
|
|
163
195
|
<< sass_end->unit() << "' and '"
|
|
164
196
|
<< sass_start->unit() << "'.";
|
|
165
197
|
error(msg.str(), low->pstate(), traces);
|
|
@@ -168,9 +200,9 @@ namespace Sass {
|
|
|
168
200
|
double end = sass_end->value();
|
|
169
201
|
// only create iterator once in this environment
|
|
170
202
|
Env env(environment(), true);
|
|
171
|
-
|
|
203
|
+
env_stack().push_back(&env);
|
|
172
204
|
Block_Obj body = f->block();
|
|
173
|
-
|
|
205
|
+
Expression* val = 0;
|
|
174
206
|
if (start < end) {
|
|
175
207
|
if (f->is_inclusive()) ++end;
|
|
176
208
|
for (double i = start;
|
|
@@ -192,26 +224,25 @@ namespace Sass {
|
|
|
192
224
|
if (val) break;
|
|
193
225
|
}
|
|
194
226
|
}
|
|
195
|
-
|
|
227
|
+
env_stack().pop_back();
|
|
196
228
|
return val;
|
|
197
229
|
}
|
|
198
230
|
|
|
199
231
|
// Eval does not create a new env scope
|
|
200
232
|
// But iteration vars are reset afterwards
|
|
201
|
-
|
|
233
|
+
Expression* Eval::operator()(EachRule* e)
|
|
202
234
|
{
|
|
203
|
-
|
|
204
|
-
|
|
235
|
+
sass::vector<sass::string> variables(e->variables());
|
|
236
|
+
ExpressionObj expr = e->list()->perform(this);
|
|
205
237
|
Env env(environment(), true);
|
|
206
|
-
|
|
207
|
-
List_Obj list
|
|
208
|
-
|
|
238
|
+
env_stack().push_back(&env);
|
|
239
|
+
List_Obj list;
|
|
240
|
+
Map* map = nullptr;
|
|
209
241
|
if (expr->concrete_type() == Expression::MAP) {
|
|
210
242
|
map = Cast<Map>(expr);
|
|
211
243
|
}
|
|
212
|
-
else if (
|
|
213
|
-
Listize
|
|
214
|
-
Expression_Obj rv = ls->perform(&listize);
|
|
244
|
+
else if (SelectorList * ls = Cast<SelectorList>(expr)) {
|
|
245
|
+
ExpressionObj rv = Listize::perform(ls);
|
|
215
246
|
list = Cast<List>(rv);
|
|
216
247
|
}
|
|
217
248
|
else if (expr->concrete_type() != Expression::LIST) {
|
|
@@ -223,14 +254,14 @@ namespace Sass {
|
|
|
223
254
|
}
|
|
224
255
|
|
|
225
256
|
Block_Obj body = e->block();
|
|
226
|
-
|
|
257
|
+
ExpressionObj val;
|
|
227
258
|
|
|
228
259
|
if (map) {
|
|
229
|
-
for (
|
|
230
|
-
|
|
260
|
+
for (ExpressionObj key : map->keys()) {
|
|
261
|
+
ExpressionObj value = map->at(key);
|
|
231
262
|
|
|
232
263
|
if (variables.size() == 1) {
|
|
233
|
-
|
|
264
|
+
List* variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
|
|
234
265
|
variable->append(key);
|
|
235
266
|
variable->append(value);
|
|
236
267
|
env.set_local(variables[0], variable);
|
|
@@ -244,25 +275,23 @@ namespace Sass {
|
|
|
244
275
|
}
|
|
245
276
|
}
|
|
246
277
|
else {
|
|
247
|
-
if (list->length() == 1 && Cast<
|
|
278
|
+
if (list->length() == 1 && Cast<SelectorList>(list)) {
|
|
248
279
|
list = Cast<List>(list);
|
|
249
280
|
}
|
|
250
281
|
for (size_t i = 0, L = list->length(); i < L; ++i) {
|
|
251
|
-
|
|
282
|
+
Expression* item = list->at(i);
|
|
252
283
|
// unwrap value if the expression is an argument
|
|
253
|
-
if (
|
|
284
|
+
if (Argument* arg = Cast<Argument>(item)) item = arg->value();
|
|
254
285
|
// check if we got passed a list of args (investigate)
|
|
255
|
-
if (
|
|
286
|
+
if (List* scalars = Cast<List>(item)) {
|
|
256
287
|
if (variables.size() == 1) {
|
|
257
|
-
|
|
288
|
+
Expression* var = scalars;
|
|
258
289
|
env.set_local(variables[0], var);
|
|
259
290
|
} else {
|
|
260
|
-
//
|
|
291
|
+
// https://github.com/sass/libsass/issues/3078
|
|
261
292
|
for (size_t j = 0, K = variables.size(); j < K; ++j) {
|
|
262
|
-
|
|
263
|
-
? SASS_MEMORY_NEW(Null, expr->pstate())
|
|
264
|
-
: scalars->at(j);
|
|
265
|
-
env.set_local(variables[j], res);
|
|
293
|
+
env.set_local(variables[j], j >= scalars->length()
|
|
294
|
+
? SASS_MEMORY_NEW(Null, expr->pstate()) : scalars->at(j));
|
|
266
295
|
}
|
|
267
296
|
}
|
|
268
297
|
} else {
|
|
@@ -270,7 +299,7 @@ namespace Sass {
|
|
|
270
299
|
env.set_local(variables.at(0), item);
|
|
271
300
|
for (size_t j = 1, K = variables.size(); j < K; ++j) {
|
|
272
301
|
// XXX: this is never hit via spec tests
|
|
273
|
-
|
|
302
|
+
Expression* res = SASS_MEMORY_NEW(Null, expr->pstate());
|
|
274
303
|
env.set_local(variables[j], res);
|
|
275
304
|
}
|
|
276
305
|
}
|
|
@@ -279,177 +308,177 @@ namespace Sass {
|
|
|
279
308
|
if (val) break;
|
|
280
309
|
}
|
|
281
310
|
}
|
|
282
|
-
|
|
311
|
+
env_stack().pop_back();
|
|
283
312
|
return val.detach();
|
|
284
313
|
}
|
|
285
314
|
|
|
286
|
-
|
|
315
|
+
Expression* Eval::operator()(WhileRule* w)
|
|
287
316
|
{
|
|
288
|
-
|
|
317
|
+
ExpressionObj pred = w->predicate();
|
|
289
318
|
Block_Obj body = w->block();
|
|
290
319
|
Env env(environment(), true);
|
|
291
|
-
|
|
292
|
-
|
|
320
|
+
env_stack().push_back(&env);
|
|
321
|
+
ExpressionObj cond = pred->perform(this);
|
|
293
322
|
while (!cond->is_false()) {
|
|
294
|
-
|
|
323
|
+
ExpressionObj val = body->perform(this);
|
|
295
324
|
if (val) {
|
|
296
|
-
|
|
325
|
+
env_stack().pop_back();
|
|
297
326
|
return val.detach();
|
|
298
327
|
}
|
|
299
328
|
cond = pred->perform(this);
|
|
300
329
|
}
|
|
301
|
-
|
|
330
|
+
env_stack().pop_back();
|
|
302
331
|
return 0;
|
|
303
332
|
}
|
|
304
333
|
|
|
305
|
-
|
|
334
|
+
Expression* Eval::operator()(Return* r)
|
|
306
335
|
{
|
|
307
336
|
return r->value()->perform(this);
|
|
308
337
|
}
|
|
309
338
|
|
|
310
|
-
|
|
339
|
+
Expression* Eval::operator()(WarningRule* w)
|
|
311
340
|
{
|
|
312
|
-
Sass_Output_Style outstyle =
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
Env* env =
|
|
341
|
+
Sass_Output_Style outstyle = options().output_style;
|
|
342
|
+
options().output_style = NESTED;
|
|
343
|
+
ExpressionObj message = w->message()->perform(this);
|
|
344
|
+
Env* env = environment();
|
|
316
345
|
|
|
317
346
|
// try to use generic function
|
|
318
347
|
if (env->has("@warn[f]")) {
|
|
319
348
|
|
|
320
349
|
// add call stack entry
|
|
321
|
-
|
|
350
|
+
callee_stack().push_back({
|
|
322
351
|
"@warn",
|
|
323
|
-
w->pstate().
|
|
324
|
-
w->pstate().
|
|
325
|
-
w->pstate().
|
|
352
|
+
w->pstate().getPath(),
|
|
353
|
+
w->pstate().getLine(),
|
|
354
|
+
w->pstate().getColumn(),
|
|
326
355
|
SASS_CALLEE_FUNCTION,
|
|
327
356
|
{ env }
|
|
328
357
|
});
|
|
329
358
|
|
|
330
|
-
|
|
359
|
+
Definition* def = Cast<Definition>((*env)["@warn[f]"]);
|
|
331
360
|
// Block_Obj body = def->block();
|
|
332
361
|
// Native_Function func = def->native_function();
|
|
333
362
|
Sass_Function_Entry c_function = def->c_function();
|
|
334
363
|
Sass_Function_Fn c_func = sass_function_get_function(c_function);
|
|
335
364
|
|
|
336
|
-
|
|
365
|
+
AST2C ast2c;
|
|
337
366
|
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);
|
|
338
|
-
sass_list_set_value(c_args, 0, message->perform(&
|
|
339
|
-
union Sass_Value* c_val = c_func(c_args, c_function,
|
|
340
|
-
|
|
341
|
-
|
|
367
|
+
sass_list_set_value(c_args, 0, message->perform(&ast2c));
|
|
368
|
+
union Sass_Value* c_val = c_func(c_args, c_function, compiler());
|
|
369
|
+
options().output_style = outstyle;
|
|
370
|
+
callee_stack().pop_back();
|
|
342
371
|
sass_delete_value(c_args);
|
|
343
372
|
sass_delete_value(c_val);
|
|
344
373
|
return 0;
|
|
345
374
|
|
|
346
375
|
}
|
|
347
376
|
|
|
348
|
-
|
|
377
|
+
sass::string result(unquote(message->to_sass()));
|
|
349
378
|
std::cerr << "WARNING: " << result << std::endl;
|
|
350
379
|
traces.push_back(Backtrace(w->pstate()));
|
|
351
380
|
std::cerr << traces_to_string(traces, " ");
|
|
352
381
|
std::cerr << std::endl;
|
|
353
|
-
|
|
382
|
+
options().output_style = outstyle;
|
|
354
383
|
traces.pop_back();
|
|
355
384
|
return 0;
|
|
356
385
|
}
|
|
357
386
|
|
|
358
|
-
|
|
387
|
+
Expression* Eval::operator()(ErrorRule* e)
|
|
359
388
|
{
|
|
360
|
-
Sass_Output_Style outstyle =
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
Env* env =
|
|
389
|
+
Sass_Output_Style outstyle = options().output_style;
|
|
390
|
+
options().output_style = NESTED;
|
|
391
|
+
ExpressionObj message = e->message()->perform(this);
|
|
392
|
+
Env* env = environment();
|
|
364
393
|
|
|
365
394
|
// try to use generic function
|
|
366
395
|
if (env->has("@error[f]")) {
|
|
367
396
|
|
|
368
397
|
// add call stack entry
|
|
369
|
-
|
|
398
|
+
callee_stack().push_back({
|
|
370
399
|
"@error",
|
|
371
|
-
e->pstate().
|
|
372
|
-
e->pstate().
|
|
373
|
-
e->pstate().
|
|
400
|
+
e->pstate().getPath(),
|
|
401
|
+
e->pstate().getLine(),
|
|
402
|
+
e->pstate().getColumn(),
|
|
374
403
|
SASS_CALLEE_FUNCTION,
|
|
375
404
|
{ env }
|
|
376
405
|
});
|
|
377
406
|
|
|
378
|
-
|
|
407
|
+
Definition* def = Cast<Definition>((*env)["@error[f]"]);
|
|
379
408
|
// Block_Obj body = def->block();
|
|
380
409
|
// Native_Function func = def->native_function();
|
|
381
410
|
Sass_Function_Entry c_function = def->c_function();
|
|
382
411
|
Sass_Function_Fn c_func = sass_function_get_function(c_function);
|
|
383
412
|
|
|
384
|
-
|
|
413
|
+
AST2C ast2c;
|
|
385
414
|
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);
|
|
386
|
-
sass_list_set_value(c_args, 0, message->perform(&
|
|
387
|
-
union Sass_Value* c_val = c_func(c_args, c_function,
|
|
388
|
-
|
|
389
|
-
|
|
415
|
+
sass_list_set_value(c_args, 0, message->perform(&ast2c));
|
|
416
|
+
union Sass_Value* c_val = c_func(c_args, c_function, compiler());
|
|
417
|
+
options().output_style = outstyle;
|
|
418
|
+
callee_stack().pop_back();
|
|
390
419
|
sass_delete_value(c_args);
|
|
391
420
|
sass_delete_value(c_val);
|
|
392
421
|
return 0;
|
|
393
422
|
|
|
394
423
|
}
|
|
395
424
|
|
|
396
|
-
|
|
397
|
-
|
|
425
|
+
sass::string result(unquote(message->to_sass()));
|
|
426
|
+
options().output_style = outstyle;
|
|
398
427
|
error(result, e->pstate(), traces);
|
|
399
428
|
return 0;
|
|
400
429
|
}
|
|
401
430
|
|
|
402
|
-
|
|
431
|
+
Expression* Eval::operator()(DebugRule* d)
|
|
403
432
|
{
|
|
404
|
-
Sass_Output_Style outstyle =
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
Env* env =
|
|
433
|
+
Sass_Output_Style outstyle = options().output_style;
|
|
434
|
+
options().output_style = NESTED;
|
|
435
|
+
ExpressionObj message = d->value()->perform(this);
|
|
436
|
+
Env* env = environment();
|
|
408
437
|
|
|
409
438
|
// try to use generic function
|
|
410
439
|
if (env->has("@debug[f]")) {
|
|
411
440
|
|
|
412
441
|
// add call stack entry
|
|
413
|
-
|
|
442
|
+
callee_stack().push_back({
|
|
414
443
|
"@debug",
|
|
415
|
-
d->pstate().
|
|
416
|
-
d->pstate().
|
|
417
|
-
d->pstate().
|
|
444
|
+
d->pstate().getPath(),
|
|
445
|
+
d->pstate().getLine(),
|
|
446
|
+
d->pstate().getColumn(),
|
|
418
447
|
SASS_CALLEE_FUNCTION,
|
|
419
448
|
{ env }
|
|
420
449
|
});
|
|
421
450
|
|
|
422
|
-
|
|
451
|
+
Definition* def = Cast<Definition>((*env)["@debug[f]"]);
|
|
423
452
|
// Block_Obj body = def->block();
|
|
424
453
|
// Native_Function func = def->native_function();
|
|
425
454
|
Sass_Function_Entry c_function = def->c_function();
|
|
426
455
|
Sass_Function_Fn c_func = sass_function_get_function(c_function);
|
|
427
456
|
|
|
428
|
-
|
|
457
|
+
AST2C ast2c;
|
|
429
458
|
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);
|
|
430
|
-
sass_list_set_value(c_args, 0, message->perform(&
|
|
431
|
-
union Sass_Value* c_val = c_func(c_args, c_function,
|
|
432
|
-
|
|
433
|
-
|
|
459
|
+
sass_list_set_value(c_args, 0, message->perform(&ast2c));
|
|
460
|
+
union Sass_Value* c_val = c_func(c_args, c_function, compiler());
|
|
461
|
+
options().output_style = outstyle;
|
|
462
|
+
callee_stack().pop_back();
|
|
434
463
|
sass_delete_value(c_args);
|
|
435
464
|
sass_delete_value(c_val);
|
|
436
465
|
return 0;
|
|
437
466
|
|
|
438
467
|
}
|
|
439
468
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
ctx.c_options.output_style = outstyle;
|
|
469
|
+
sass::string result(unquote(message->to_sass()));
|
|
470
|
+
sass::string abs_path(Sass::File::rel2abs(d->pstate().getPath(), cwd(), cwd()));
|
|
471
|
+
sass::string rel_path(Sass::File::abs2rel(d->pstate().getPath(), cwd(), cwd()));
|
|
472
|
+
sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().getPath()));
|
|
473
|
+
options().output_style = outstyle;
|
|
446
474
|
|
|
447
|
-
std::cerr << output_path << ":" << d->pstate().
|
|
475
|
+
std::cerr << output_path << ":" << d->pstate().getLine() << " DEBUG: " << result;
|
|
448
476
|
std::cerr << std::endl;
|
|
449
477
|
return 0;
|
|
450
478
|
}
|
|
451
479
|
|
|
452
|
-
|
|
480
|
+
|
|
481
|
+
Expression* Eval::operator()(List* l)
|
|
453
482
|
{
|
|
454
483
|
// special case for unevaluated map
|
|
455
484
|
if (l->separator() == SASS_HASH) {
|
|
@@ -458,8 +487,8 @@ namespace Sass {
|
|
|
458
487
|
l->length() / 2);
|
|
459
488
|
for (size_t i = 0, L = l->length(); i < L; i += 2)
|
|
460
489
|
{
|
|
461
|
-
|
|
462
|
-
|
|
490
|
+
ExpressionObj key = (*l)[i+0]->perform(this);
|
|
491
|
+
ExpressionObj val = (*l)[i+1]->perform(this);
|
|
463
492
|
// make sure the color key never displays its real name
|
|
464
493
|
key->is_delayed(true); // verified
|
|
465
494
|
*lm << std::make_pair(key, val);
|
|
@@ -490,7 +519,7 @@ namespace Sass {
|
|
|
490
519
|
return ll.detach();
|
|
491
520
|
}
|
|
492
521
|
|
|
493
|
-
|
|
522
|
+
Expression* Eval::operator()(Map* m)
|
|
494
523
|
{
|
|
495
524
|
if (m->is_expanded()) return m;
|
|
496
525
|
|
|
@@ -505,8 +534,8 @@ namespace Sass {
|
|
|
505
534
|
m->pstate(),
|
|
506
535
|
m->length());
|
|
507
536
|
for (auto key : m->keys()) {
|
|
508
|
-
|
|
509
|
-
|
|
537
|
+
Expression* ex_key = key->perform(this);
|
|
538
|
+
Expression* ex_val = m->at(key);
|
|
510
539
|
if (ex_val == NULL) continue;
|
|
511
540
|
ex_val = ex_val->perform(this);
|
|
512
541
|
*mm << std::make_pair(ex_key, ex_val);
|
|
@@ -522,11 +551,11 @@ namespace Sass {
|
|
|
522
551
|
return mm.detach();
|
|
523
552
|
}
|
|
524
553
|
|
|
525
|
-
|
|
554
|
+
Expression* Eval::operator()(Binary_Expression* b_in)
|
|
526
555
|
{
|
|
527
556
|
|
|
528
|
-
|
|
529
|
-
|
|
557
|
+
ExpressionObj lhs = b_in->left();
|
|
558
|
+
ExpressionObj rhs = b_in->right();
|
|
530
559
|
enum Sass_OP op_type = b_in->optype();
|
|
531
560
|
|
|
532
561
|
if (op_type == Sass_OP::AND) {
|
|
@@ -543,21 +572,21 @@ namespace Sass {
|
|
|
543
572
|
}
|
|
544
573
|
|
|
545
574
|
// Evaluate variables as early o
|
|
546
|
-
while (
|
|
575
|
+
while (Variable* l_v = Cast<Variable>(lhs)) {
|
|
547
576
|
lhs = operator()(l_v);
|
|
548
577
|
}
|
|
549
|
-
while (
|
|
578
|
+
while (Variable* r_v = Cast<Variable>(rhs)) {
|
|
550
579
|
rhs = operator()(r_v);
|
|
551
580
|
}
|
|
552
581
|
|
|
553
|
-
|
|
582
|
+
Binary_ExpressionObj b = b_in;
|
|
554
583
|
|
|
555
584
|
// Evaluate sub-expressions early on
|
|
556
|
-
while (
|
|
585
|
+
while (Binary_Expression* l_b = Cast<Binary_Expression>(lhs)) {
|
|
557
586
|
if (!force && l_b->is_delayed()) break;
|
|
558
587
|
lhs = operator()(l_b);
|
|
559
588
|
}
|
|
560
|
-
while (
|
|
589
|
+
while (Binary_Expression* r_b = Cast<Binary_Expression>(rhs)) {
|
|
561
590
|
if (!force && r_b->is_delayed()) break;
|
|
562
591
|
rhs = operator()(r_b);
|
|
563
592
|
}
|
|
@@ -571,9 +600,9 @@ namespace Sass {
|
|
|
571
600
|
|
|
572
601
|
// specific types we know are final
|
|
573
602
|
// handle them early to avoid overhead
|
|
574
|
-
if (
|
|
603
|
+
if (Number* l_n = Cast<Number>(lhs)) {
|
|
575
604
|
// lhs is number and rhs is number
|
|
576
|
-
if (
|
|
605
|
+
if (Number* r_n = Cast<Number>(rhs)) {
|
|
577
606
|
try {
|
|
578
607
|
switch (op_type) {
|
|
579
608
|
case Sass_OP::EQ: return *l_n == *r_n ? bool_true : bool_false;
|
|
@@ -583,7 +612,7 @@ namespace Sass {
|
|
|
583
612
|
case Sass_OP::LTE: return *l_n < *r_n || *l_n == *r_n ? bool_true : bool_false;
|
|
584
613
|
case Sass_OP::GT: return *l_n < *r_n || *l_n == *r_n ? bool_false : bool_true;
|
|
585
614
|
case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
|
|
586
|
-
return Operators::op_numbers(op_type, *l_n, *r_n,
|
|
615
|
+
return Operators::op_numbers(op_type, *l_n, *r_n, options(), b_in->pstate());
|
|
587
616
|
default: break;
|
|
588
617
|
}
|
|
589
618
|
}
|
|
@@ -594,17 +623,15 @@ namespace Sass {
|
|
|
594
623
|
}
|
|
595
624
|
}
|
|
596
625
|
// lhs is number and rhs is color
|
|
597
|
-
|
|
626
|
+
// Todo: allow to work with HSLA colors
|
|
627
|
+
else if (Color* r_col = Cast<Color>(rhs)) {
|
|
628
|
+
Color_RGBA_Obj r_c = r_col->toRGBA();
|
|
598
629
|
try {
|
|
599
630
|
switch (op_type) {
|
|
600
631
|
case Sass_OP::EQ: return *l_n == *r_c ? bool_true : bool_false;
|
|
601
632
|
case Sass_OP::NEQ: return *l_n == *r_c ? bool_false : bool_true;
|
|
602
|
-
case Sass_OP::LT: return *l_n < *r_c ? bool_true : bool_false;
|
|
603
|
-
case Sass_OP::GTE: return *l_n < *r_c ? bool_false : bool_true;
|
|
604
|
-
case Sass_OP::LTE: return *l_n < *r_c || *l_n == *r_c ? bool_true : bool_false;
|
|
605
|
-
case Sass_OP::GT: return *l_n < *r_c || *l_n == *r_c ? bool_false : bool_true;
|
|
606
633
|
case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
|
|
607
|
-
return Operators::op_number_color(op_type, *l_n, *r_c,
|
|
634
|
+
return Operators::op_number_color(op_type, *l_n, *r_c, options(), b_in->pstate());
|
|
608
635
|
default: break;
|
|
609
636
|
}
|
|
610
637
|
}
|
|
@@ -615,9 +642,11 @@ namespace Sass {
|
|
|
615
642
|
}
|
|
616
643
|
}
|
|
617
644
|
}
|
|
618
|
-
else if (
|
|
645
|
+
else if (Color* l_col = Cast<Color>(lhs)) {
|
|
646
|
+
Color_RGBA_Obj l_c = l_col->toRGBA();
|
|
619
647
|
// lhs is color and rhs is color
|
|
620
|
-
if (
|
|
648
|
+
if (Color* r_col = Cast<Color>(rhs)) {
|
|
649
|
+
Color_RGBA_Obj r_c = r_col->toRGBA();
|
|
621
650
|
try {
|
|
622
651
|
switch (op_type) {
|
|
623
652
|
case Sass_OP::EQ: return *l_c == *r_c ? bool_true : bool_false;
|
|
@@ -627,7 +656,7 @@ namespace Sass {
|
|
|
627
656
|
case Sass_OP::LTE: return *l_c < *r_c || *l_c == *r_c ? bool_true : bool_false;
|
|
628
657
|
case Sass_OP::GT: return *l_c < *r_c || *l_c == *r_c ? bool_false : bool_true;
|
|
629
658
|
case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
|
|
630
|
-
return Operators::op_colors(op_type, *l_c, *r_c,
|
|
659
|
+
return Operators::op_colors(op_type, *l_c, *r_c, options(), b_in->pstate());
|
|
631
660
|
default: break;
|
|
632
661
|
}
|
|
633
662
|
}
|
|
@@ -638,17 +667,13 @@ namespace Sass {
|
|
|
638
667
|
}
|
|
639
668
|
}
|
|
640
669
|
// lhs is color and rhs is number
|
|
641
|
-
else if (
|
|
670
|
+
else if (Number* r_n = Cast<Number>(rhs)) {
|
|
642
671
|
try {
|
|
643
672
|
switch (op_type) {
|
|
644
673
|
case Sass_OP::EQ: return *l_c == *r_n ? bool_true : bool_false;
|
|
645
674
|
case Sass_OP::NEQ: return *l_c == *r_n ? bool_false : bool_true;
|
|
646
|
-
case Sass_OP::LT: return *l_c < *r_n ? bool_true : bool_false;
|
|
647
|
-
case Sass_OP::GTE: return *l_c < *r_n ? bool_false : bool_true;
|
|
648
|
-
case Sass_OP::LTE: return *l_c < *r_n || *l_c == *r_n ? bool_true : bool_false;
|
|
649
|
-
case Sass_OP::GT: return *l_c < *r_n || *l_c == *r_n ? bool_false : bool_true;
|
|
650
675
|
case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
|
|
651
|
-
return Operators::op_color_number(op_type, *l_c, *r_n,
|
|
676
|
+
return Operators::op_color_number(op_type, *l_c, *r_n, options(), b_in->pstate());
|
|
652
677
|
default: break;
|
|
653
678
|
}
|
|
654
679
|
}
|
|
@@ -663,10 +688,10 @@ namespace Sass {
|
|
|
663
688
|
String_Schema_Obj ret_schema;
|
|
664
689
|
|
|
665
690
|
// only the last item will be used to eval the binary expression
|
|
666
|
-
if (
|
|
691
|
+
if (String_Schema* s_l = Cast<String_Schema>(b->left())) {
|
|
667
692
|
if (!s_l->has_interpolant() && (!s_l->is_right_interpolant())) {
|
|
668
693
|
ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate());
|
|
669
|
-
|
|
694
|
+
Binary_ExpressionObj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(),
|
|
670
695
|
b->op(), s_l->last(), b->right());
|
|
671
696
|
bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // unverified
|
|
672
697
|
for (size_t i = 0; i < s_l->length() - 1; ++i) {
|
|
@@ -676,11 +701,11 @@ namespace Sass {
|
|
|
676
701
|
return ret_schema->perform(this);
|
|
677
702
|
}
|
|
678
703
|
}
|
|
679
|
-
if (
|
|
704
|
+
if (String_Schema* s_r = Cast<String_Schema>(b->right())) {
|
|
680
705
|
|
|
681
706
|
if (!s_r->has_interpolant() && (!s_r->is_left_interpolant() || op_type == Sass_OP::DIV)) {
|
|
682
707
|
ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate());
|
|
683
|
-
|
|
708
|
+
Binary_ExpressionObj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(),
|
|
684
709
|
b->op(), b->left(), s_r->first());
|
|
685
710
|
bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // verified
|
|
686
711
|
ret_schema->append(bin_ex->perform(this));
|
|
@@ -716,14 +741,14 @@ namespace Sass {
|
|
|
716
741
|
AST_Node_Obj lu = lhs;
|
|
717
742
|
AST_Node_Obj ru = rhs;
|
|
718
743
|
|
|
719
|
-
Expression::
|
|
720
|
-
Expression::
|
|
744
|
+
Expression::Type l_type;
|
|
745
|
+
Expression::Type r_type;
|
|
721
746
|
|
|
722
747
|
// Is one of the operands an interpolant?
|
|
723
748
|
String_Schema_Obj s1 = Cast<String_Schema>(b->left());
|
|
724
749
|
String_Schema_Obj s2 = Cast<String_Schema>(b->right());
|
|
725
|
-
|
|
726
|
-
|
|
750
|
+
Binary_ExpressionObj b1 = Cast<Binary_Expression>(b->left());
|
|
751
|
+
Binary_ExpressionObj b2 = Cast<Binary_Expression>(b->right());
|
|
727
752
|
|
|
728
753
|
bool schema_op = false;
|
|
729
754
|
|
|
@@ -737,16 +762,16 @@ namespace Sass {
|
|
|
737
762
|
if (op_type == Sass_OP::DIV || op_type == Sass_OP::MUL || op_type == Sass_OP::MOD || op_type == Sass_OP::ADD || op_type == Sass_OP::SUB ||
|
|
738
763
|
op_type == Sass_OP::EQ) {
|
|
739
764
|
// If possible upgrade LHS to a number (for number to string compare)
|
|
740
|
-
if (
|
|
741
|
-
|
|
765
|
+
if (String_Constant* str = Cast<String_Constant>(lhs)) {
|
|
766
|
+
sass::string value(str->value());
|
|
742
767
|
const char* start = value.c_str();
|
|
743
768
|
if (Prelexer::sequence < Prelexer::dimension, Prelexer::end_of_file >(start) != 0) {
|
|
744
769
|
lhs = Parser::lexed_dimension(b->pstate(), str->value());
|
|
745
770
|
}
|
|
746
771
|
}
|
|
747
772
|
// If possible upgrade RHS to a number (for string to number compare)
|
|
748
|
-
if (
|
|
749
|
-
|
|
773
|
+
if (String_Constant* str = Cast<String_Constant>(rhs)) {
|
|
774
|
+
sass::string value(str->value());
|
|
750
775
|
const char* start = value.c_str();
|
|
751
776
|
if (Prelexer::sequence < Prelexer::dimension, Prelexer::number >(start) != 0) {
|
|
752
777
|
rhs = Parser::lexed_dimension(b->pstate(), str->value());
|
|
@@ -755,17 +780,17 @@ namespace Sass {
|
|
|
755
780
|
}
|
|
756
781
|
|
|
757
782
|
To_Value to_value(ctx);
|
|
758
|
-
|
|
759
|
-
|
|
783
|
+
ValueObj v_l = Cast<Value>(lhs->perform(&to_value));
|
|
784
|
+
ValueObj v_r = Cast<Value>(rhs->perform(&to_value));
|
|
760
785
|
|
|
761
786
|
if (force_delay) {
|
|
762
|
-
|
|
763
|
-
str += v_l->to_string(
|
|
787
|
+
sass::string str("");
|
|
788
|
+
str += v_l->to_string(options());
|
|
764
789
|
if (b->op().ws_before) str += " ";
|
|
765
790
|
str += b->separator();
|
|
766
791
|
if (b->op().ws_after) str += " ";
|
|
767
|
-
str += v_r->to_string(
|
|
768
|
-
|
|
792
|
+
str += v_r->to_string(options());
|
|
793
|
+
String_Constant* val = SASS_MEMORY_NEW(String_Constant, b->pstate(), str);
|
|
769
794
|
val->is_interpolant(b->left()->has_interpolant());
|
|
770
795
|
return val;
|
|
771
796
|
}
|
|
@@ -785,7 +810,6 @@ namespace Sass {
|
|
|
785
810
|
}
|
|
786
811
|
catch (Exception::OperationError& err)
|
|
787
812
|
{
|
|
788
|
-
// throw Exception::Base(b->pstate(), err.what());
|
|
789
813
|
traces.push_back(Backtrace(b->pstate()));
|
|
790
814
|
throw Exception::SassValueError(traces, b->pstate(), err);
|
|
791
815
|
}
|
|
@@ -795,35 +819,35 @@ namespace Sass {
|
|
|
795
819
|
|
|
796
820
|
// ToDo: throw error in op functions
|
|
797
821
|
// ToDo: then catch and re-throw them
|
|
798
|
-
|
|
822
|
+
ExpressionObj rv;
|
|
799
823
|
try {
|
|
800
|
-
|
|
824
|
+
SourceSpan pstate(b->pstate());
|
|
801
825
|
if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
|
|
802
|
-
|
|
803
|
-
|
|
826
|
+
Number* l_n = Cast<Number>(lhs);
|
|
827
|
+
Number* r_n = Cast<Number>(rhs);
|
|
804
828
|
l_n->reduce(); r_n->reduce();
|
|
805
|
-
rv = Operators::op_numbers(op_type, *l_n, *r_n,
|
|
829
|
+
rv = Operators::op_numbers(op_type, *l_n, *r_n, options(), pstate);
|
|
806
830
|
}
|
|
807
831
|
else if (l_type == Expression::NUMBER && r_type == Expression::COLOR) {
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
rv = Operators::op_number_color(op_type, *l_n, *r_c,
|
|
832
|
+
Number* l_n = Cast<Number>(lhs);
|
|
833
|
+
Color_RGBA_Obj r_c = Cast<Color>(rhs)->toRGBA();
|
|
834
|
+
rv = Operators::op_number_color(op_type, *l_n, *r_c, options(), pstate);
|
|
811
835
|
}
|
|
812
836
|
else if (l_type == Expression::COLOR && r_type == Expression::NUMBER) {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
rv = Operators::op_color_number(op_type, *l_c, *r_n,
|
|
837
|
+
Color_RGBA_Obj l_c = Cast<Color>(lhs)->toRGBA();
|
|
838
|
+
Number* r_n = Cast<Number>(rhs);
|
|
839
|
+
rv = Operators::op_color_number(op_type, *l_c, *r_n, options(), pstate);
|
|
816
840
|
}
|
|
817
841
|
else if (l_type == Expression::COLOR && r_type == Expression::COLOR) {
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
rv = Operators::op_colors(op_type, *l_c, *r_c,
|
|
842
|
+
Color_RGBA_Obj l_c = Cast<Color>(lhs)->toRGBA();
|
|
843
|
+
Color_RGBA_Obj r_c = Cast<Color>(rhs)->toRGBA();
|
|
844
|
+
rv = Operators::op_colors(op_type, *l_c, *r_c, options(), pstate);
|
|
821
845
|
}
|
|
822
846
|
else {
|
|
823
847
|
To_Value to_value(ctx);
|
|
824
848
|
// this will leak if perform does not return a value!
|
|
825
|
-
|
|
826
|
-
|
|
849
|
+
ValueObj v_l = Cast<Value>(lhs->perform(&to_value));
|
|
850
|
+
ValueObj v_r = Cast<Value>(rhs->perform(&to_value));
|
|
827
851
|
bool interpolant = b->is_right_interpolant() ||
|
|
828
852
|
b->is_left_interpolant() ||
|
|
829
853
|
b->is_interpolant();
|
|
@@ -838,15 +862,15 @@ namespace Sass {
|
|
|
838
862
|
traces.push_back(Backtrace(v_r->pstate()));
|
|
839
863
|
throw Exception::InvalidValue(traces, *v_r);
|
|
840
864
|
}
|
|
841
|
-
|
|
842
|
-
if (
|
|
865
|
+
Value* ex = Operators::op_strings(b->op(), *v_l, *v_r, options(), pstate, !interpolant); // pass true to compress
|
|
866
|
+
if (String_Constant* str = Cast<String_Constant>(ex))
|
|
843
867
|
{
|
|
844
868
|
if (str->concrete_type() == Expression::STRING)
|
|
845
869
|
{
|
|
846
|
-
|
|
847
|
-
|
|
870
|
+
String_Constant* lstr = Cast<String_Constant>(lhs);
|
|
871
|
+
String_Constant* rstr = Cast<String_Constant>(rhs);
|
|
848
872
|
if (op_type != Sass_OP::SUB) {
|
|
849
|
-
if (
|
|
873
|
+
if (String_Constant* org = lstr ? lstr : rstr)
|
|
850
874
|
{ str->quote_mark(org->quote_mark()); }
|
|
851
875
|
}
|
|
852
876
|
}
|
|
@@ -874,11 +898,11 @@ namespace Sass {
|
|
|
874
898
|
|
|
875
899
|
}
|
|
876
900
|
|
|
877
|
-
|
|
901
|
+
Expression* Eval::operator()(Unary_Expression* u)
|
|
878
902
|
{
|
|
879
|
-
|
|
903
|
+
ExpressionObj operand = u->operand()->perform(this);
|
|
880
904
|
if (u->optype() == Unary_Expression::NOT) {
|
|
881
|
-
|
|
905
|
+
Boolean* result = SASS_MEMORY_NEW(Boolean, u->pstate(), (bool)*operand);
|
|
882
906
|
result->value(!result->value());
|
|
883
907
|
return result;
|
|
884
908
|
}
|
|
@@ -890,28 +914,35 @@ namespace Sass {
|
|
|
890
914
|
return cpy.detach(); // return the copy
|
|
891
915
|
}
|
|
892
916
|
else if (u->optype() == Unary_Expression::SLASH) {
|
|
893
|
-
|
|
917
|
+
sass::string str = '/' + nr->to_string(options());
|
|
894
918
|
return SASS_MEMORY_NEW(String_Constant, u->pstate(), str);
|
|
895
919
|
}
|
|
896
920
|
// nothing for positive
|
|
897
921
|
return nr.detach();
|
|
898
922
|
}
|
|
899
923
|
else {
|
|
900
|
-
// Special cases: +/- variables which evaluate to null
|
|
924
|
+
// Special cases: +/- variables which evaluate to null output just +/-,
|
|
901
925
|
// but +/- null itself outputs the string
|
|
902
926
|
if (operand->concrete_type() == Expression::NULL_VAL && Cast<Variable>(u->operand())) {
|
|
903
927
|
u->operand(SASS_MEMORY_NEW(String_Quoted, u->pstate(), ""));
|
|
904
928
|
}
|
|
905
929
|
// Never apply unary opertions on colors @see #2140
|
|
906
|
-
else if (
|
|
930
|
+
else if (Color* color = Cast<Color>(operand)) {
|
|
907
931
|
// Use the color name if this was eval with one
|
|
908
932
|
if (color->disp().length() > 0) {
|
|
909
|
-
|
|
910
|
-
|
|
933
|
+
Unary_ExpressionObj cpy = SASS_MEMORY_COPY(u);
|
|
934
|
+
cpy->operand(SASS_MEMORY_NEW(String_Constant, operand->pstate(), color->disp()));
|
|
935
|
+
return SASS_MEMORY_NEW(String_Quoted,
|
|
936
|
+
cpy->pstate(),
|
|
937
|
+
cpy->inspect());
|
|
911
938
|
}
|
|
912
939
|
}
|
|
913
940
|
else {
|
|
914
|
-
u
|
|
941
|
+
Unary_ExpressionObj cpy = SASS_MEMORY_COPY(u);
|
|
942
|
+
cpy->operand(operand);
|
|
943
|
+
return SASS_MEMORY_NEW(String_Quoted,
|
|
944
|
+
cpy->pstate(),
|
|
945
|
+
cpy->inspect());
|
|
915
946
|
}
|
|
916
947
|
|
|
917
948
|
return SASS_MEMORY_NEW(String_Quoted,
|
|
@@ -922,16 +953,26 @@ namespace Sass {
|
|
|
922
953
|
return u;
|
|
923
954
|
}
|
|
924
955
|
|
|
925
|
-
|
|
956
|
+
Expression* Eval::operator()(Function_Call* c)
|
|
926
957
|
{
|
|
927
958
|
if (traces.size() > Constants::MaxCallStack) {
|
|
928
959
|
// XXX: this is never hit via spec tests
|
|
929
|
-
|
|
960
|
+
sass::ostream stm;
|
|
930
961
|
stm << "Stack depth exceeded max of " << Constants::MaxCallStack;
|
|
931
962
|
error(stm.str(), c->pstate(), traces);
|
|
932
963
|
}
|
|
933
|
-
|
|
934
|
-
|
|
964
|
+
|
|
965
|
+
if (Cast<String_Schema>(c->sname())) {
|
|
966
|
+
ExpressionObj evaluated_name = c->sname()->perform(this);
|
|
967
|
+
ExpressionObj evaluated_args = c->arguments()->perform(this);
|
|
968
|
+
sass::string str(evaluated_name->to_string());
|
|
969
|
+
str += evaluated_args->to_string();
|
|
970
|
+
return SASS_MEMORY_NEW(String_Constant, c->pstate(), str);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
sass::string name(Util::normalize_underscores(c->name()));
|
|
974
|
+
sass::string full_name(name + "[f]");
|
|
975
|
+
|
|
935
976
|
// we make a clone here, need to implement that further
|
|
936
977
|
Arguments_Obj args = c->arguments();
|
|
937
978
|
|
|
@@ -949,11 +990,11 @@ namespace Sass {
|
|
|
949
990
|
c->name(),
|
|
950
991
|
args);
|
|
951
992
|
if (args->has_named_arguments()) {
|
|
952
|
-
error("
|
|
993
|
+
error("Plain CSS function " + c->name() + " doesn't support keyword arguments", c->pstate(), traces);
|
|
953
994
|
}
|
|
954
|
-
|
|
995
|
+
String_Quoted* str = SASS_MEMORY_NEW(String_Quoted,
|
|
955
996
|
c->pstate(),
|
|
956
|
-
lit->to_string(
|
|
997
|
+
lit->to_string(options()));
|
|
957
998
|
str->is_interpolant(c->is_interpolant());
|
|
958
999
|
return str;
|
|
959
1000
|
} else {
|
|
@@ -969,28 +1010,28 @@ namespace Sass {
|
|
|
969
1010
|
if (full_name != "if[f]") {
|
|
970
1011
|
args = Cast<Arguments>(args->perform(this));
|
|
971
1012
|
}
|
|
972
|
-
|
|
1013
|
+
Definition* def = Cast<Definition>((*env)[full_name]);
|
|
973
1014
|
|
|
974
1015
|
if (c->func()) def = c->func()->definition();
|
|
975
1016
|
|
|
976
1017
|
if (def->is_overload_stub()) {
|
|
977
|
-
|
|
1018
|
+
sass::ostream ss;
|
|
978
1019
|
size_t L = args->length();
|
|
979
1020
|
// account for rest arguments
|
|
980
1021
|
if (args->has_rest_argument() && args->length() > 0) {
|
|
981
1022
|
// get the rest arguments list
|
|
982
|
-
|
|
1023
|
+
List* rest = Cast<List>(args->last()->value());
|
|
983
1024
|
// arguments before rest argument plus rest
|
|
984
1025
|
if (rest) L += rest->length() - 1;
|
|
985
1026
|
}
|
|
986
1027
|
ss << full_name << L;
|
|
987
1028
|
full_name = ss.str();
|
|
988
|
-
|
|
989
|
-
if (!env->has(resolved_name)) error("overloaded function `" +
|
|
1029
|
+
sass::string resolved_name(full_name);
|
|
1030
|
+
if (!env->has(resolved_name)) error("overloaded function `" + sass::string(c->name()) + "` given wrong number of arguments", c->pstate(), traces);
|
|
990
1031
|
def = Cast<Definition>((*env)[resolved_name]);
|
|
991
1032
|
}
|
|
992
1033
|
|
|
993
|
-
|
|
1034
|
+
ExpressionObj result = c;
|
|
994
1035
|
Block_Obj body = def->block();
|
|
995
1036
|
Native_Function func = def->native_function();
|
|
996
1037
|
Sass_Function_Entry c_function = def->c_function();
|
|
@@ -999,17 +1040,17 @@ namespace Sass {
|
|
|
999
1040
|
|
|
1000
1041
|
Parameters_Obj params = def->parameters();
|
|
1001
1042
|
Env fn_env(def->environment());
|
|
1002
|
-
|
|
1043
|
+
env_stack().push_back(&fn_env);
|
|
1003
1044
|
|
|
1004
1045
|
if (func || body) {
|
|
1005
|
-
bind(
|
|
1006
|
-
|
|
1046
|
+
bind(sass::string("Function"), c->name(), params, args, &fn_env, this, traces);
|
|
1047
|
+
sass::string msg(", in function `" + c->name() + "`");
|
|
1007
1048
|
traces.push_back(Backtrace(c->pstate(), msg));
|
|
1008
|
-
|
|
1049
|
+
callee_stack().push_back({
|
|
1009
1050
|
c->name().c_str(),
|
|
1010
|
-
c->pstate().
|
|
1011
|
-
c->pstate().
|
|
1012
|
-
c->pstate().
|
|
1051
|
+
c->pstate().getPath(),
|
|
1052
|
+
c->pstate().getLine(),
|
|
1053
|
+
c->pstate().getColumn(),
|
|
1013
1054
|
SASS_CALLEE_FUNCTION,
|
|
1014
1055
|
{ env }
|
|
1015
1056
|
});
|
|
@@ -1019,12 +1060,12 @@ namespace Sass {
|
|
|
1019
1060
|
result = body->perform(this);
|
|
1020
1061
|
}
|
|
1021
1062
|
else if (func) {
|
|
1022
|
-
result = func(fn_env, *env, ctx, def->signature(), c->pstate(), traces, exp.
|
|
1063
|
+
result = func(fn_env, *env, ctx, def->signature(), c->pstate(), traces, exp.getSelectorStack(), exp.originalStack);
|
|
1023
1064
|
}
|
|
1024
1065
|
if (!result) {
|
|
1025
|
-
error(
|
|
1066
|
+
error(sass::string("Function ") + c->name() + " finished without @return", c->pstate(), traces);
|
|
1026
1067
|
}
|
|
1027
|
-
|
|
1068
|
+
callee_stack().pop_back();
|
|
1028
1069
|
traces.pop_back();
|
|
1029
1070
|
}
|
|
1030
1071
|
|
|
@@ -1041,37 +1082,43 @@ namespace Sass {
|
|
|
1041
1082
|
}
|
|
1042
1083
|
|
|
1043
1084
|
// populates env with default values for params
|
|
1044
|
-
|
|
1045
|
-
bind(
|
|
1046
|
-
|
|
1085
|
+
sass::string ff(c->name());
|
|
1086
|
+
bind(sass::string("Function"), c->name(), params, args, &fn_env, this, traces);
|
|
1087
|
+
sass::string msg(", in function `" + c->name() + "`");
|
|
1047
1088
|
traces.push_back(Backtrace(c->pstate(), msg));
|
|
1048
|
-
|
|
1089
|
+
callee_stack().push_back({
|
|
1049
1090
|
c->name().c_str(),
|
|
1050
|
-
c->pstate().
|
|
1051
|
-
c->pstate().
|
|
1052
|
-
c->pstate().
|
|
1091
|
+
c->pstate().getPath(),
|
|
1092
|
+
c->pstate().getLine(),
|
|
1093
|
+
c->pstate().getColumn(),
|
|
1053
1094
|
SASS_CALLEE_C_FUNCTION,
|
|
1054
1095
|
{ env }
|
|
1055
1096
|
});
|
|
1056
1097
|
|
|
1057
|
-
|
|
1098
|
+
AST2C ast2c;
|
|
1058
1099
|
union Sass_Value* c_args = sass_make_list(params->length(), SASS_COMMA, false);
|
|
1059
1100
|
for(size_t i = 0; i < params->length(); i++) {
|
|
1060
1101
|
Parameter_Obj param = params->at(i);
|
|
1061
|
-
|
|
1102
|
+
sass::string key = param->name();
|
|
1062
1103
|
AST_Node_Obj node = fn_env.get_local(key);
|
|
1063
|
-
|
|
1064
|
-
sass_list_set_value(c_args, i, arg->perform(&
|
|
1104
|
+
ExpressionObj arg = Cast<Expression>(node);
|
|
1105
|
+
sass_list_set_value(c_args, i, arg->perform(&ast2c));
|
|
1065
1106
|
}
|
|
1066
|
-
union Sass_Value* c_val = c_func(c_args, c_function,
|
|
1107
|
+
union Sass_Value* c_val = c_func(c_args, c_function, compiler());
|
|
1067
1108
|
if (sass_value_get_tag(c_val) == SASS_ERROR) {
|
|
1068
|
-
|
|
1109
|
+
sass::string message("error in C function " + c->name() + ": " + sass_error_get_message(c_val));
|
|
1110
|
+
sass_delete_value(c_val);
|
|
1111
|
+
sass_delete_value(c_args);
|
|
1112
|
+
error(message, c->pstate(), traces);
|
|
1069
1113
|
} else if (sass_value_get_tag(c_val) == SASS_WARNING) {
|
|
1070
|
-
|
|
1114
|
+
sass::string message("warning in C function " + c->name() + ": " + sass_warning_get_message(c_val));
|
|
1115
|
+
sass_delete_value(c_val);
|
|
1116
|
+
sass_delete_value(c_args);
|
|
1117
|
+
error(message, c->pstate(), traces);
|
|
1071
1118
|
}
|
|
1072
|
-
result =
|
|
1119
|
+
result = c2ast(c_val, traces, c->pstate());
|
|
1073
1120
|
|
|
1074
|
-
|
|
1121
|
+
callee_stack().pop_back();
|
|
1075
1122
|
traces.pop_back();
|
|
1076
1123
|
sass_delete_value(c_args);
|
|
1077
1124
|
if (c_val != c_args)
|
|
@@ -1080,35 +1127,25 @@ namespace Sass {
|
|
|
1080
1127
|
|
|
1081
1128
|
// link back to function definition
|
|
1082
1129
|
// only do this for custom functions
|
|
1083
|
-
if (result->pstate().
|
|
1130
|
+
if (result->pstate().getSrcId() == sass::string::npos)
|
|
1084
1131
|
result->pstate(c->pstate());
|
|
1085
1132
|
|
|
1086
1133
|
result = result->perform(this);
|
|
1087
1134
|
result->is_interpolant(c->is_interpolant());
|
|
1088
|
-
|
|
1135
|
+
env_stack().pop_back();
|
|
1089
1136
|
return result.detach();
|
|
1090
1137
|
}
|
|
1091
1138
|
|
|
1092
|
-
|
|
1093
|
-
{
|
|
1094
|
-
Expression_Ptr evaluated_name = s->name()->perform(this);
|
|
1095
|
-
Expression_Ptr evaluated_args = s->arguments()->perform(this);
|
|
1096
|
-
String_Schema_Obj ss = SASS_MEMORY_NEW(String_Schema, s->pstate(), 2);
|
|
1097
|
-
ss->append(evaluated_name);
|
|
1098
|
-
ss->append(evaluated_args);
|
|
1099
|
-
return ss->perform(this);
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
Expression_Ptr Eval::operator()(Variable_Ptr v)
|
|
1139
|
+
Expression* Eval::operator()(Variable* v)
|
|
1103
1140
|
{
|
|
1104
|
-
|
|
1141
|
+
ExpressionObj value;
|
|
1105
1142
|
Env* env = environment();
|
|
1106
|
-
const
|
|
1143
|
+
const sass::string& name(v->name());
|
|
1107
1144
|
EnvResult rv(env->find(name));
|
|
1108
1145
|
if (rv.found) value = static_cast<Expression*>(rv.it->second.ptr());
|
|
1109
1146
|
else error("Undefined variable: \"" + v->name() + "\".", v->pstate(), traces);
|
|
1110
|
-
if (
|
|
1111
|
-
if (
|
|
1147
|
+
if (Argument* arg = Cast<Argument>(value)) value = arg->value();
|
|
1148
|
+
if (Number* nr = Cast<Number>(value)) nr->zero(true); // force flag
|
|
1112
1149
|
value->is_interpolant(v->is_interpolant());
|
|
1113
1150
|
if (force) value->is_expanded(false);
|
|
1114
1151
|
value->set_delayed(false); // verified
|
|
@@ -1117,27 +1154,32 @@ namespace Sass {
|
|
|
1117
1154
|
return value.detach();
|
|
1118
1155
|
}
|
|
1119
1156
|
|
|
1120
|
-
|
|
1157
|
+
Expression* Eval::operator()(Color_RGBA* c)
|
|
1121
1158
|
{
|
|
1122
1159
|
return c;
|
|
1123
1160
|
}
|
|
1124
1161
|
|
|
1125
|
-
|
|
1162
|
+
Expression* Eval::operator()(Color_HSLA* c)
|
|
1163
|
+
{
|
|
1164
|
+
return c;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
Expression* Eval::operator()(Number* n)
|
|
1126
1168
|
{
|
|
1127
1169
|
return n;
|
|
1128
1170
|
}
|
|
1129
1171
|
|
|
1130
|
-
|
|
1172
|
+
Expression* Eval::operator()(Boolean* b)
|
|
1131
1173
|
{
|
|
1132
1174
|
return b;
|
|
1133
1175
|
}
|
|
1134
1176
|
|
|
1135
|
-
void Eval::interpolation(Context& ctx,
|
|
1177
|
+
void Eval::interpolation(Context& ctx, sass::string& res, ExpressionObj ex, bool into_quotes, bool was_itpl) {
|
|
1136
1178
|
|
|
1137
1179
|
bool needs_closing_brace = false;
|
|
1138
1180
|
|
|
1139
|
-
if (
|
|
1140
|
-
|
|
1181
|
+
if (Arguments* args = Cast<Arguments>(ex)) {
|
|
1182
|
+
List* ll = SASS_MEMORY_NEW(List, args->pstate(), 0, SASS_COMMA);
|
|
1141
1183
|
for(auto arg : args->elements()) {
|
|
1142
1184
|
ll->append(arg->value());
|
|
1143
1185
|
}
|
|
@@ -1146,7 +1188,7 @@ namespace Sass {
|
|
|
1146
1188
|
res += "(";
|
|
1147
1189
|
ex = ll;
|
|
1148
1190
|
}
|
|
1149
|
-
if (
|
|
1191
|
+
if (Number* nr = Cast<Number>(ex)) {
|
|
1150
1192
|
Number reduced(nr);
|
|
1151
1193
|
reduced.reduce();
|
|
1152
1194
|
if (!reduced.is_valid_css_unit()) {
|
|
@@ -1154,10 +1196,10 @@ namespace Sass {
|
|
|
1154
1196
|
throw Exception::InvalidValue(traces, *nr);
|
|
1155
1197
|
}
|
|
1156
1198
|
}
|
|
1157
|
-
if (
|
|
1199
|
+
if (Argument* arg = Cast<Argument>(ex)) {
|
|
1158
1200
|
ex = arg->value();
|
|
1159
1201
|
}
|
|
1160
|
-
if (
|
|
1202
|
+
if (String_Quoted* sq = Cast<String_Quoted>(ex)) {
|
|
1161
1203
|
if (was_itpl) {
|
|
1162
1204
|
bool was_interpolant = ex->is_interpolant();
|
|
1163
1205
|
ex = SASS_MEMORY_NEW(String_Constant, sq->pstate(), sq->value());
|
|
@@ -1168,18 +1210,18 @@ namespace Sass {
|
|
|
1168
1210
|
if (Cast<Null>(ex)) { return; }
|
|
1169
1211
|
|
|
1170
1212
|
// parent selector needs another go
|
|
1171
|
-
if (Cast<
|
|
1213
|
+
if (Cast<Parent_Reference>(ex)) {
|
|
1172
1214
|
// XXX: this is never hit via spec tests
|
|
1173
1215
|
ex = ex->perform(this);
|
|
1174
1216
|
}
|
|
1175
1217
|
|
|
1176
|
-
if (
|
|
1218
|
+
if (List* l = Cast<List>(ex)) {
|
|
1177
1219
|
List_Obj ll = SASS_MEMORY_NEW(List, l->pstate(), 0, l->separator());
|
|
1178
1220
|
// this fixes an issue with bourbon sample, not really sure why
|
|
1179
1221
|
// if (l->size() && Cast<Null>((*l)[0])) { res += ""; }
|
|
1180
|
-
for(
|
|
1222
|
+
for(ExpressionObj item : *l) {
|
|
1181
1223
|
item->is_interpolant(l->is_interpolant());
|
|
1182
|
-
|
|
1224
|
+
sass::string rl(""); interpolation(ctx, rl, item, into_quotes, l->is_interpolant());
|
|
1183
1225
|
bool is_null = Cast<Null>(item) != 0; // rl != ""
|
|
1184
1226
|
if (!is_null) ll->append(SASS_MEMORY_NEW(String_Quoted, item->pstate(), rl));
|
|
1185
1227
|
}
|
|
@@ -1187,12 +1229,12 @@ namespace Sass {
|
|
|
1187
1229
|
// here. Normally single list items are already unwrapped.
|
|
1188
1230
|
if (l->size() > 1) {
|
|
1189
1231
|
// string_to_output would fail "#{'_\a' '_\a'}";
|
|
1190
|
-
|
|
1232
|
+
sass::string str(ll->to_string(options()));
|
|
1191
1233
|
str = read_hex_escapes(str); // read escapes
|
|
1192
1234
|
newline_to_space(str); // replace directly
|
|
1193
1235
|
res += str; // append to result string
|
|
1194
1236
|
} else {
|
|
1195
|
-
res += (ll->to_string(
|
|
1237
|
+
res += (ll->to_string(options()));
|
|
1196
1238
|
}
|
|
1197
1239
|
ll->is_interpolant(l->is_interpolant());
|
|
1198
1240
|
}
|
|
@@ -1202,14 +1244,13 @@ namespace Sass {
|
|
|
1202
1244
|
// Selector_List
|
|
1203
1245
|
// String_Quoted
|
|
1204
1246
|
// String_Constant
|
|
1205
|
-
// Parent_Selector
|
|
1206
1247
|
// Binary_Expression
|
|
1207
1248
|
else {
|
|
1208
1249
|
// ex = ex->perform(this);
|
|
1209
1250
|
if (into_quotes && ex->is_interpolant()) {
|
|
1210
|
-
res += evacuate_escapes(ex ? ex->to_string(
|
|
1251
|
+
res += evacuate_escapes(ex ? ex->to_string(options()) : "");
|
|
1211
1252
|
} else {
|
|
1212
|
-
|
|
1253
|
+
sass::string str(ex ? ex->to_string(options()) : "");
|
|
1213
1254
|
if (into_quotes) str = read_hex_escapes(str);
|
|
1214
1255
|
res += str; // append to result string
|
|
1215
1256
|
}
|
|
@@ -1219,14 +1260,14 @@ namespace Sass {
|
|
|
1219
1260
|
|
|
1220
1261
|
}
|
|
1221
1262
|
|
|
1222
|
-
|
|
1263
|
+
Expression* Eval::operator()(String_Schema* s)
|
|
1223
1264
|
{
|
|
1224
1265
|
size_t L = s->length();
|
|
1225
1266
|
bool into_quotes = false;
|
|
1226
1267
|
if (L > 1) {
|
|
1227
1268
|
if (!Cast<String_Quoted>((*s)[0]) && !Cast<String_Quoted>((*s)[L - 1])) {
|
|
1228
|
-
if (
|
|
1229
|
-
if (
|
|
1269
|
+
if (String_Constant* l = Cast<String_Constant>((*s)[0])) {
|
|
1270
|
+
if (String_Constant* r = Cast<String_Constant>((*s)[L - 1])) {
|
|
1230
1271
|
if (r->value().size() > 0) {
|
|
1231
1272
|
if (l->value()[0] == '"' && r->value()[r->value().size() - 1] == '"') into_quotes = true;
|
|
1232
1273
|
if (l->value()[0] == '\'' && r->value()[r->value().size() - 1] == '\'') into_quotes = true;
|
|
@@ -1237,12 +1278,12 @@ namespace Sass {
|
|
|
1237
1278
|
}
|
|
1238
1279
|
bool was_quoted = false;
|
|
1239
1280
|
bool was_interpolant = false;
|
|
1240
|
-
|
|
1281
|
+
sass::string res("");
|
|
1241
1282
|
for (size_t i = 0; i < L; ++i) {
|
|
1242
1283
|
bool is_quoted = Cast<String_Quoted>((*s)[i]) != NULL;
|
|
1243
1284
|
if (was_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; }
|
|
1244
1285
|
else if (i > 0 && is_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; }
|
|
1245
|
-
|
|
1286
|
+
ExpressionObj ex = (*s)[i]->perform(this);
|
|
1246
1287
|
interpolation(ctx, res, ex, into_quotes, ex->is_interpolant());
|
|
1247
1288
|
was_quoted = Cast<String_Quoted>((*s)[i]) != NULL;
|
|
1248
1289
|
was_interpolant = (*s)[i]->is_interpolant();
|
|
@@ -1250,12 +1291,13 @@ namespace Sass {
|
|
|
1250
1291
|
}
|
|
1251
1292
|
if (!s->is_interpolant()) {
|
|
1252
1293
|
if (s->length() > 1 && res == "") return SASS_MEMORY_NEW(Null, s->pstate());
|
|
1253
|
-
|
|
1294
|
+
String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res, s->css());
|
|
1295
|
+
return str.detach();
|
|
1254
1296
|
}
|
|
1255
1297
|
// string schema seems to have a special unquoting behavior (also handles "nested" quotes)
|
|
1256
1298
|
String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), res, 0, false, false, false, s->css());
|
|
1257
1299
|
// if (s->is_interpolant()) str->quote_mark(0);
|
|
1258
|
-
//
|
|
1300
|
+
// String_Constant* str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res);
|
|
1259
1301
|
if (str->quote_mark()) str->quote_mark('*');
|
|
1260
1302
|
else if (!is_in_comment) str->value(string_to_output(str->value()));
|
|
1261
1303
|
str->is_interpolant(s->is_interpolant());
|
|
@@ -1263,85 +1305,78 @@ namespace Sass {
|
|
|
1263
1305
|
}
|
|
1264
1306
|
|
|
1265
1307
|
|
|
1266
|
-
|
|
1308
|
+
Expression* Eval::operator()(String_Constant* s)
|
|
1267
1309
|
{
|
|
1268
|
-
if (!s->is_delayed() && name_to_color(s->value())) {
|
|
1269
|
-
Color_Ptr c = SASS_MEMORY_COPY(name_to_color(s->value())); // copy
|
|
1270
|
-
c->pstate(s->pstate());
|
|
1271
|
-
c->disp(s->value());
|
|
1272
|
-
c->is_delayed(true);
|
|
1273
|
-
return c;
|
|
1274
|
-
}
|
|
1275
1310
|
return s;
|
|
1276
1311
|
}
|
|
1277
1312
|
|
|
1278
|
-
|
|
1313
|
+
Expression* Eval::operator()(String_Quoted* s)
|
|
1279
1314
|
{
|
|
1280
|
-
|
|
1315
|
+
String_Quoted* str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), "");
|
|
1281
1316
|
str->value(s->value());
|
|
1282
1317
|
str->quote_mark(s->quote_mark());
|
|
1283
1318
|
str->is_interpolant(s->is_interpolant());
|
|
1284
1319
|
return str;
|
|
1285
1320
|
}
|
|
1286
1321
|
|
|
1287
|
-
|
|
1322
|
+
Expression* Eval::operator()(SupportsOperation* c)
|
|
1288
1323
|
{
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1324
|
+
Expression* left = c->left()->perform(this);
|
|
1325
|
+
Expression* right = c->right()->perform(this);
|
|
1326
|
+
SupportsOperation* cc = SASS_MEMORY_NEW(SupportsOperation,
|
|
1292
1327
|
c->pstate(),
|
|
1293
|
-
Cast<
|
|
1294
|
-
Cast<
|
|
1328
|
+
Cast<SupportsCondition>(left),
|
|
1329
|
+
Cast<SupportsCondition>(right),
|
|
1295
1330
|
c->operand());
|
|
1296
1331
|
return cc;
|
|
1297
1332
|
}
|
|
1298
1333
|
|
|
1299
|
-
|
|
1334
|
+
Expression* Eval::operator()(SupportsNegation* c)
|
|
1300
1335
|
{
|
|
1301
|
-
|
|
1302
|
-
|
|
1336
|
+
Expression* condition = c->condition()->perform(this);
|
|
1337
|
+
SupportsNegation* cc = SASS_MEMORY_NEW(SupportsNegation,
|
|
1303
1338
|
c->pstate(),
|
|
1304
|
-
Cast<
|
|
1339
|
+
Cast<SupportsCondition>(condition));
|
|
1305
1340
|
return cc;
|
|
1306
1341
|
}
|
|
1307
1342
|
|
|
1308
|
-
|
|
1343
|
+
Expression* Eval::operator()(SupportsDeclaration* c)
|
|
1309
1344
|
{
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1345
|
+
Expression* feature = c->feature()->perform(this);
|
|
1346
|
+
Expression* value = c->value()->perform(this);
|
|
1347
|
+
SupportsDeclaration* cc = SASS_MEMORY_NEW(SupportsDeclaration,
|
|
1313
1348
|
c->pstate(),
|
|
1314
1349
|
feature,
|
|
1315
1350
|
value);
|
|
1316
1351
|
return cc;
|
|
1317
1352
|
}
|
|
1318
1353
|
|
|
1319
|
-
|
|
1354
|
+
Expression* Eval::operator()(Supports_Interpolation* c)
|
|
1320
1355
|
{
|
|
1321
|
-
|
|
1322
|
-
|
|
1356
|
+
Expression* value = c->value()->perform(this);
|
|
1357
|
+
Supports_Interpolation* cc = SASS_MEMORY_NEW(Supports_Interpolation,
|
|
1323
1358
|
c->pstate(),
|
|
1324
1359
|
value);
|
|
1325
1360
|
return cc;
|
|
1326
1361
|
}
|
|
1327
1362
|
|
|
1328
|
-
|
|
1363
|
+
Expression* Eval::operator()(At_Root_Query* e)
|
|
1329
1364
|
{
|
|
1330
|
-
|
|
1365
|
+
ExpressionObj feature = e->feature();
|
|
1331
1366
|
feature = (feature ? feature->perform(this) : 0);
|
|
1332
|
-
|
|
1367
|
+
ExpressionObj value = e->value();
|
|
1333
1368
|
value = (value ? value->perform(this) : 0);
|
|
1334
|
-
|
|
1369
|
+
Expression* ee = SASS_MEMORY_NEW(At_Root_Query,
|
|
1335
1370
|
e->pstate(),
|
|
1336
1371
|
Cast<String>(feature),
|
|
1337
1372
|
value);
|
|
1338
1373
|
return ee;
|
|
1339
1374
|
}
|
|
1340
1375
|
|
|
1341
|
-
|
|
1376
|
+
Media_Query* Eval::operator()(Media_Query* q)
|
|
1342
1377
|
{
|
|
1343
1378
|
String_Obj t = q->media_type();
|
|
1344
|
-
t = static_cast<
|
|
1379
|
+
t = static_cast<String*>(t.isNull() ? 0 : t->perform(this));
|
|
1345
1380
|
Media_Query_Obj qq = SASS_MEMORY_NEW(Media_Query,
|
|
1346
1381
|
q->pstate(),
|
|
1347
1382
|
t,
|
|
@@ -1349,21 +1384,21 @@ namespace Sass {
|
|
|
1349
1384
|
q->is_negated(),
|
|
1350
1385
|
q->is_restricted());
|
|
1351
1386
|
for (size_t i = 0, L = q->length(); i < L; ++i) {
|
|
1352
|
-
qq->append(static_cast<
|
|
1387
|
+
qq->append(static_cast<Media_Query_Expression*>((*q)[i]->perform(this)));
|
|
1353
1388
|
}
|
|
1354
1389
|
return qq.detach();
|
|
1355
1390
|
}
|
|
1356
1391
|
|
|
1357
|
-
|
|
1392
|
+
Expression* Eval::operator()(Media_Query_Expression* e)
|
|
1358
1393
|
{
|
|
1359
|
-
|
|
1394
|
+
ExpressionObj feature = e->feature();
|
|
1360
1395
|
feature = (feature ? feature->perform(this) : 0);
|
|
1361
1396
|
if (feature && Cast<String_Quoted>(feature)) {
|
|
1362
1397
|
feature = SASS_MEMORY_NEW(String_Quoted,
|
|
1363
1398
|
feature->pstate(),
|
|
1364
1399
|
Cast<String_Quoted>(feature)->value());
|
|
1365
1400
|
}
|
|
1366
|
-
|
|
1401
|
+
ExpressionObj value = e->value();
|
|
1367
1402
|
value = (value ? value->perform(this) : 0);
|
|
1368
1403
|
if (value && Cast<String_Quoted>(value)) {
|
|
1369
1404
|
// XXX: this is never hit via spec tests
|
|
@@ -1378,14 +1413,14 @@ namespace Sass {
|
|
|
1378
1413
|
e->is_interpolated());
|
|
1379
1414
|
}
|
|
1380
1415
|
|
|
1381
|
-
|
|
1416
|
+
Expression* Eval::operator()(Null* n)
|
|
1382
1417
|
{
|
|
1383
1418
|
return n;
|
|
1384
1419
|
}
|
|
1385
1420
|
|
|
1386
|
-
|
|
1421
|
+
Expression* Eval::operator()(Argument* a)
|
|
1387
1422
|
{
|
|
1388
|
-
|
|
1423
|
+
ExpressionObj val = a->value()->perform(this);
|
|
1389
1424
|
bool is_rest_argument = a->is_rest_argument();
|
|
1390
1425
|
bool is_keyword_argument = a->is_keyword_argument();
|
|
1391
1426
|
|
|
@@ -1412,25 +1447,25 @@ namespace Sass {
|
|
|
1412
1447
|
is_keyword_argument);
|
|
1413
1448
|
}
|
|
1414
1449
|
|
|
1415
|
-
|
|
1450
|
+
Expression* Eval::operator()(Arguments* a)
|
|
1416
1451
|
{
|
|
1417
1452
|
Arguments_Obj aa = SASS_MEMORY_NEW(Arguments, a->pstate());
|
|
1418
1453
|
if (a->length() == 0) return aa.detach();
|
|
1419
1454
|
for (size_t i = 0, L = a->length(); i < L; ++i) {
|
|
1420
|
-
|
|
1421
|
-
|
|
1455
|
+
ExpressionObj rv = (*a)[i]->perform(this);
|
|
1456
|
+
Argument* arg = Cast<Argument>(rv);
|
|
1422
1457
|
if (!(arg->is_rest_argument() || arg->is_keyword_argument())) {
|
|
1423
1458
|
aa->append(arg);
|
|
1424
1459
|
}
|
|
1425
1460
|
}
|
|
1426
1461
|
|
|
1427
1462
|
if (a->has_rest_argument()) {
|
|
1428
|
-
|
|
1429
|
-
|
|
1463
|
+
ExpressionObj rest = a->get_rest_argument()->perform(this);
|
|
1464
|
+
ExpressionObj splat = Cast<Argument>(rest)->value()->perform(this);
|
|
1430
1465
|
|
|
1431
1466
|
Sass_Separator separator = SASS_COMMA;
|
|
1432
|
-
|
|
1433
|
-
|
|
1467
|
+
List* ls = Cast<List>(splat);
|
|
1468
|
+
Map* ms = Cast<Map>(splat);
|
|
1434
1469
|
|
|
1435
1470
|
List_Obj arglist = SASS_MEMORY_NEW(List,
|
|
1436
1471
|
splat->pstate(),
|
|
@@ -1453,226 +1488,56 @@ namespace Sass {
|
|
|
1453
1488
|
}
|
|
1454
1489
|
|
|
1455
1490
|
if (a->has_keyword_argument()) {
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1491
|
+
ExpressionObj rv = a->get_keyword_argument()->perform(this);
|
|
1492
|
+
Argument* rvarg = Cast<Argument>(rv);
|
|
1493
|
+
ExpressionObj kwarg = rvarg->value()->perform(this);
|
|
1459
1494
|
|
|
1460
1495
|
aa->append(SASS_MEMORY_NEW(Argument, kwarg->pstate(), kwarg, "", false, true));
|
|
1461
1496
|
}
|
|
1462
1497
|
return aa.detach();
|
|
1463
1498
|
}
|
|
1464
1499
|
|
|
1465
|
-
|
|
1500
|
+
Expression* Eval::operator()(Comment* c)
|
|
1466
1501
|
{
|
|
1467
1502
|
return 0;
|
|
1468
1503
|
}
|
|
1469
1504
|
|
|
1470
|
-
|
|
1471
|
-
{
|
|
1472
|
-
return static_cast<Expression_Ptr>(n);
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
|
-
// All the binary helpers.
|
|
1476
|
-
|
|
1477
|
-
Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtraces traces, ParserState pstate)
|
|
1478
|
-
{
|
|
1479
|
-
using std::strlen;
|
|
1480
|
-
using std::strcpy;
|
|
1481
|
-
Expression_Ptr e = NULL;
|
|
1482
|
-
switch (sass_value_get_tag(v)) {
|
|
1483
|
-
case SASS_BOOLEAN: {
|
|
1484
|
-
e = SASS_MEMORY_NEW(Boolean, pstate, !!sass_boolean_get_value(v));
|
|
1485
|
-
} break;
|
|
1486
|
-
case SASS_NUMBER: {
|
|
1487
|
-
e = SASS_MEMORY_NEW(Number, pstate, sass_number_get_value(v), sass_number_get_unit(v));
|
|
1488
|
-
} break;
|
|
1489
|
-
case SASS_COLOR: {
|
|
1490
|
-
e = SASS_MEMORY_NEW(Color, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v));
|
|
1491
|
-
} break;
|
|
1492
|
-
case SASS_STRING: {
|
|
1493
|
-
if (sass_string_is_quoted(v))
|
|
1494
|
-
e = SASS_MEMORY_NEW(String_Quoted, pstate, sass_string_get_value(v));
|
|
1495
|
-
else {
|
|
1496
|
-
e = SASS_MEMORY_NEW(String_Constant, pstate, sass_string_get_value(v));
|
|
1497
|
-
}
|
|
1498
|
-
} break;
|
|
1499
|
-
case SASS_LIST: {
|
|
1500
|
-
List_Ptr l = SASS_MEMORY_NEW(List, pstate, sass_list_get_length(v), sass_list_get_separator(v));
|
|
1501
|
-
for (size_t i = 0, L = sass_list_get_length(v); i < L; ++i) {
|
|
1502
|
-
l->append(cval_to_astnode(sass_list_get_value(v, i), traces, pstate));
|
|
1503
|
-
}
|
|
1504
|
-
l->is_bracketed(sass_list_get_is_bracketed(v));
|
|
1505
|
-
e = l;
|
|
1506
|
-
} break;
|
|
1507
|
-
case SASS_MAP: {
|
|
1508
|
-
Map_Ptr m = SASS_MEMORY_NEW(Map, pstate);
|
|
1509
|
-
for (size_t i = 0, L = sass_map_get_length(v); i < L; ++i) {
|
|
1510
|
-
*m << std::make_pair(
|
|
1511
|
-
cval_to_astnode(sass_map_get_key(v, i), traces, pstate),
|
|
1512
|
-
cval_to_astnode(sass_map_get_value(v, i), traces, pstate));
|
|
1513
|
-
}
|
|
1514
|
-
e = m;
|
|
1515
|
-
} break;
|
|
1516
|
-
case SASS_NULL: {
|
|
1517
|
-
e = SASS_MEMORY_NEW(Null, pstate);
|
|
1518
|
-
} break;
|
|
1519
|
-
case SASS_ERROR: {
|
|
1520
|
-
error("Error in C function: " + std::string(sass_error_get_message(v)), pstate, traces);
|
|
1521
|
-
} break;
|
|
1522
|
-
case SASS_WARNING: {
|
|
1523
|
-
error("Warning in C function: " + std::string(sass_warning_get_message(v)), pstate, traces);
|
|
1524
|
-
} break;
|
|
1525
|
-
default: break;
|
|
1526
|
-
}
|
|
1527
|
-
return e;
|
|
1528
|
-
}
|
|
1529
|
-
|
|
1530
|
-
Selector_List_Ptr Eval::operator()(Selector_List_Ptr s)
|
|
1531
|
-
{
|
|
1532
|
-
std::vector<Selector_List_Obj> rv;
|
|
1533
|
-
Selector_List_Obj sl = SASS_MEMORY_NEW(Selector_List, s->pstate());
|
|
1534
|
-
sl->is_optional(s->is_optional());
|
|
1535
|
-
sl->media_block(s->media_block());
|
|
1536
|
-
sl->is_optional(s->is_optional());
|
|
1537
|
-
for (size_t i = 0, iL = s->length(); i < iL; ++i) {
|
|
1538
|
-
rv.push_back(operator()((*s)[i]));
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
// we should actually permutate parent first
|
|
1542
|
-
// but here we have permutated the selector first
|
|
1543
|
-
size_t round = 0;
|
|
1544
|
-
while (round != std::string::npos) {
|
|
1545
|
-
bool abort = true;
|
|
1546
|
-
for (size_t i = 0, iL = rv.size(); i < iL; ++i) {
|
|
1547
|
-
if (rv[i]->length() > round) {
|
|
1548
|
-
sl->append((*rv[i])[round]);
|
|
1549
|
-
abort = false;
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
if (abort) {
|
|
1553
|
-
round = std::string::npos;
|
|
1554
|
-
} else {
|
|
1555
|
-
++ round;
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
}
|
|
1559
|
-
return sl.detach();
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
Selector_List_Ptr Eval::operator()(Complex_Selector_Ptr s)
|
|
1564
|
-
{
|
|
1565
|
-
bool implicit_parent = !exp.old_at_root_without_rule;
|
|
1566
|
-
if (is_in_selector_schema) exp.selector_stack.push_back(0);
|
|
1567
|
-
Selector_List_Obj resolved = s->resolve_parent_refs(exp.selector_stack, traces, implicit_parent);
|
|
1568
|
-
if (is_in_selector_schema) exp.selector_stack.pop_back();
|
|
1569
|
-
for (size_t i = 0; i < resolved->length(); i++) {
|
|
1570
|
-
Complex_Selector_Ptr is = resolved->at(i)->first();
|
|
1571
|
-
while (is) {
|
|
1572
|
-
if (is->head()) {
|
|
1573
|
-
is->head(operator()(is->head()));
|
|
1574
|
-
}
|
|
1575
|
-
is = is->tail();
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
return resolved.detach();
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
Compound_Selector_Ptr Eval::operator()(Compound_Selector_Ptr s)
|
|
1582
|
-
{
|
|
1583
|
-
for (size_t i = 0; i < s->length(); i++) {
|
|
1584
|
-
Simple_Selector_Ptr ss = s->at(i);
|
|
1585
|
-
// skip parents here (called via resolve_parent_refs)
|
|
1586
|
-
if (ss == NULL || Cast<Parent_Selector>(ss)) continue;
|
|
1587
|
-
s->at(i) = Cast<Simple_Selector>(ss->perform(this));
|
|
1588
|
-
}
|
|
1589
|
-
return s;
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
Selector_List_Ptr Eval::operator()(Selector_Schema_Ptr s)
|
|
1505
|
+
SelectorList* Eval::operator()(Selector_Schema* s)
|
|
1593
1506
|
{
|
|
1594
1507
|
LOCAL_FLAG(is_in_selector_schema, true);
|
|
1595
1508
|
// the parser will look for a brace to end the selector
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
std::string result_str(sel->to_string(ctx.c_options));
|
|
1599
|
-
ctx.c_options.in_selector = false; // flag temporary only
|
|
1509
|
+
ExpressionObj sel = s->contents()->perform(this);
|
|
1510
|
+
sass::string result_str(sel->to_string(options()));
|
|
1600
1511
|
result_str = unquote(Util::rtrim(result_str));
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
Parser p
|
|
1604
|
-
|
|
1605
|
-
// a
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
auto vec_str_rend = ctx.strings.rend();
|
|
1609
|
-
auto vec_str_rbegin = ctx.strings.rbegin();
|
|
1610
|
-
// remove the first item searching from the back
|
|
1611
|
-
// we cannot assume our item is still the last one
|
|
1612
|
-
// order is not important, so we can optimize this
|
|
1613
|
-
auto it = std::find(vec_str_rbegin, vec_str_rend, temp_cstr);
|
|
1614
|
-
// undefined behavior if not found!
|
|
1615
|
-
if (it != vec_str_rend) {
|
|
1616
|
-
// overwrite with last item
|
|
1617
|
-
*it = ctx.strings.back();
|
|
1618
|
-
// remove last one from vector
|
|
1619
|
-
ctx.strings.pop_back();
|
|
1620
|
-
// free temporary copy
|
|
1621
|
-
free(temp_cstr);
|
|
1622
|
-
}
|
|
1512
|
+
ItplFile* source = SASS_MEMORY_NEW(ItplFile,
|
|
1513
|
+
result_str.c_str(), s->pstate());
|
|
1514
|
+
Parser p(source, ctx, traces);
|
|
1515
|
+
|
|
1516
|
+
// If a schema contains a reference to parent it is already
|
|
1517
|
+
// connected to it, so don't connect implicitly anymore
|
|
1518
|
+
SelectorListObj parsed = p.parseSelectorList(true);
|
|
1623
1519
|
flag_is_in_selector_schema.reset();
|
|
1624
|
-
return
|
|
1520
|
+
return parsed.detach();
|
|
1625
1521
|
}
|
|
1626
1522
|
|
|
1627
|
-
|
|
1523
|
+
Expression* Eval::operator()(Parent_Reference* p)
|
|
1628
1524
|
{
|
|
1629
|
-
if (
|
|
1630
|
-
|
|
1631
|
-
Selector_List_Obj rv = operator()(pr);
|
|
1632
|
-
exp.selector_stack.push_back(rv);
|
|
1633
|
-
return rv.detach();
|
|
1525
|
+
if (SelectorListObj pr = exp.original()) {
|
|
1526
|
+
return operator()(pr);
|
|
1634
1527
|
} else {
|
|
1635
1528
|
return SASS_MEMORY_NEW(Null, p->pstate());
|
|
1636
1529
|
}
|
|
1637
1530
|
}
|
|
1638
1531
|
|
|
1639
|
-
|
|
1532
|
+
SimpleSelector* Eval::operator()(SimpleSelector* s)
|
|
1640
1533
|
{
|
|
1641
1534
|
return s;
|
|
1642
1535
|
}
|
|
1643
1536
|
|
|
1644
|
-
|
|
1645
|
-
// probably the wrong place, but this should ultimately
|
|
1646
|
-
// be fixed by implement superselector correctly for `:not`
|
|
1647
|
-
// first use of "find" (ATM only implemented for selectors)
|
|
1648
|
-
bool hasNotSelector(AST_Node_Obj obj) {
|
|
1649
|
-
if (Wrapped_Selector_Ptr w = Cast<Wrapped_Selector>(obj)) {
|
|
1650
|
-
return w->name() == ":not";
|
|
1651
|
-
}
|
|
1652
|
-
return false;
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
Wrapped_Selector_Ptr Eval::operator()(Wrapped_Selector_Ptr s)
|
|
1537
|
+
PseudoSelector* Eval::operator()(PseudoSelector* pseudo)
|
|
1656
1538
|
{
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
if (exp.selector_stack.back()) {
|
|
1660
|
-
if (s->selector()->find(hasNotSelector)) {
|
|
1661
|
-
s->selector()->clear();
|
|
1662
|
-
s->name(" ");
|
|
1663
|
-
} else if (s->selector()->length() == 1) {
|
|
1664
|
-
Complex_Selector_Ptr cs = s->selector()->at(0);
|
|
1665
|
-
if (cs->tail()) {
|
|
1666
|
-
s->selector()->clear();
|
|
1667
|
-
s->name(" ");
|
|
1668
|
-
}
|
|
1669
|
-
} else if (s->selector()->length() > 1) {
|
|
1670
|
-
s->selector()->clear();
|
|
1671
|
-
s->name(" ");
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
return s;
|
|
1539
|
+
// ToDo: should we eval selector?
|
|
1540
|
+
return pseudo;
|
|
1676
1541
|
};
|
|
1677
1542
|
|
|
1678
1543
|
}
|