sassc 2.0.1 → 2.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -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 "operators.hpp"
|
3
6
|
|
4
7
|
namespace Sass {
|
@@ -54,13 +57,24 @@ namespace Sass {
|
|
54
57
|
bool lte(Expression_Obj lhs, Expression_Obj rhs) { return cmp(lhs, rhs, Sass_OP::LTE) || eq(lhs, rhs); }
|
55
58
|
bool gte(Expression_Obj lhs, Expression_Obj rhs) { return !cmp(lhs, rhs, Sass_OP::GTE) || eq(lhs, rhs); }
|
56
59
|
|
60
|
+
/* colour math deprecation warning */
|
61
|
+
void op_color_deprecation(enum Sass_OP op, std::string lsh, std::string rhs, const ParserState& pstate)
|
62
|
+
{
|
63
|
+
deprecated(
|
64
|
+
"The operation `" + lsh + " " + sass_op_to_name(op) + " " + rhs +
|
65
|
+
"` is deprecated and will be an error in future versions.",
|
66
|
+
"Consider using Sass's color functions instead.\n"
|
67
|
+
"https://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions",
|
68
|
+
/*with_column=*/false, pstate);
|
69
|
+
}
|
70
|
+
|
57
71
|
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
58
|
-
|
72
|
+
Value* op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
59
73
|
{
|
60
74
|
enum Sass_OP op = operand.operand;
|
61
75
|
|
62
|
-
|
63
|
-
|
76
|
+
String_Quoted* lqstr = Cast<String_Quoted>(&lhs);
|
77
|
+
String_Quoted* rqstr = Cast<String_Quoted>(&rhs);
|
64
78
|
|
65
79
|
std::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt));
|
66
80
|
std::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt));
|
@@ -104,16 +118,21 @@ namespace Sass {
|
|
104
118
|
return SASS_MEMORY_NEW(String_Constant, pstate, lstr + sep + rstr);
|
105
119
|
}
|
106
120
|
|
121
|
+
/* ToDo: allow to operate also with hsla colors */
|
107
122
|
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
108
|
-
|
123
|
+
Value* op_colors(enum Sass_OP op, const Color_RGBA& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
109
124
|
{
|
125
|
+
|
110
126
|
if (lhs.a() != rhs.a()) {
|
111
127
|
throw Exception::AlphaChannelsNotEqual(&lhs, &rhs, op);
|
112
128
|
}
|
113
|
-
if (op == Sass_OP::DIV && (!rhs.r() || !rhs.g() || !rhs.b())) {
|
129
|
+
if ((op == Sass_OP::DIV || op == Sass_OP::MOD) && (!rhs.r() || !rhs.g() || !rhs.b())) {
|
114
130
|
throw Exception::ZeroDivisionError(lhs, rhs);
|
115
131
|
}
|
116
|
-
|
132
|
+
|
133
|
+
op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);
|
134
|
+
|
135
|
+
return SASS_MEMORY_NEW(Color_RGBA,
|
117
136
|
pstate,
|
118
137
|
ops[op](lhs.r(), rhs.r()),
|
119
138
|
ops[op](lhs.g(), rhs.g()),
|
@@ -122,20 +141,20 @@ namespace Sass {
|
|
122
141
|
}
|
123
142
|
|
124
143
|
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
125
|
-
|
144
|
+
Value* op_numbers(enum Sass_OP op, const Number& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
126
145
|
{
|
127
146
|
double lval = lhs.value();
|
128
147
|
double rval = rhs.value();
|
129
148
|
|
149
|
+
if (op == Sass_OP::MOD && rval == 0) {
|
150
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, "NaN");
|
151
|
+
}
|
152
|
+
|
130
153
|
if (op == Sass_OP::DIV && rval == 0) {
|
131
154
|
std::string result(lval ? "Infinity" : "NaN");
|
132
155
|
return SASS_MEMORY_NEW(String_Quoted, pstate, result);
|
133
156
|
}
|
134
157
|
|
135
|
-
if (op == Sass_OP::MOD && rval == 0) {
|
136
|
-
throw Exception::ZeroDivisionError(lhs, rhs);
|
137
|
-
}
|
138
|
-
|
139
158
|
size_t l_n_units = lhs.numerators.size();
|
140
159
|
size_t l_d_units = lhs.numerators.size();
|
141
160
|
size_t r_n_units = rhs.denominators.size();
|
@@ -145,7 +164,7 @@ namespace Sass {
|
|
145
164
|
if (l_n_units + l_d_units <= 1 && r_n_units + r_d_units <= 1) {
|
146
165
|
if (lhs.numerators == rhs.numerators) {
|
147
166
|
if (lhs.denominators == rhs.denominators) {
|
148
|
-
|
167
|
+
Number* v = SASS_MEMORY_COPY(&lhs);
|
149
168
|
v->value(ops[op](lval, rval));
|
150
169
|
return v;
|
151
170
|
}
|
@@ -192,13 +211,15 @@ namespace Sass {
|
|
192
211
|
}
|
193
212
|
|
194
213
|
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
195
|
-
|
214
|
+
Value* op_number_color(enum Sass_OP op, const Number& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
196
215
|
{
|
197
216
|
double lval = lhs.value();
|
217
|
+
|
198
218
|
switch (op) {
|
199
219
|
case Sass_OP::ADD:
|
200
220
|
case Sass_OP::MUL: {
|
201
|
-
|
221
|
+
op_color_deprecation(op, lhs.to_string(), rhs.to_string(opt), pstate);
|
222
|
+
return SASS_MEMORY_NEW(Color_RGBA,
|
202
223
|
pstate,
|
203
224
|
ops[op](lval, rhs.r()),
|
204
225
|
ops[op](lval, rhs.g()),
|
@@ -208,6 +229,7 @@ namespace Sass {
|
|
208
229
|
case Sass_OP::SUB:
|
209
230
|
case Sass_OP::DIV: {
|
210
231
|
std::string color(rhs.to_string(opt));
|
232
|
+
op_color_deprecation(op, lhs.to_string(), color, pstate);
|
211
233
|
return SASS_MEMORY_NEW(String_Quoted,
|
212
234
|
pstate,
|
213
235
|
lhs.to_string(opt)
|
@@ -220,14 +242,18 @@ namespace Sass {
|
|
220
242
|
}
|
221
243
|
|
222
244
|
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
223
|
-
|
245
|
+
Value* op_color_number(enum Sass_OP op, const Color_RGBA& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
224
246
|
{
|
225
247
|
double rval = rhs.value();
|
226
|
-
|
248
|
+
|
249
|
+
if ((op == Sass_OP::DIV || op == Sass_OP::DIV) && rval == 0) {
|
227
250
|
// comparison of Fixnum with Float failed?
|
228
251
|
throw Exception::ZeroDivisionError(lhs, rhs);
|
229
252
|
}
|
230
|
-
|
253
|
+
|
254
|
+
op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);
|
255
|
+
|
256
|
+
return SASS_MEMORY_NEW(Color_RGBA,
|
231
257
|
pstate,
|
232
258
|
ops[op](lhs.r(), rval),
|
233
259
|
ops[op](lhs.g(), rval),
|
@@ -17,11 +17,11 @@ namespace Sass {
|
|
17
17
|
bool lte(Expression_Obj, Expression_Obj);
|
18
18
|
bool gte(Expression_Obj, Expression_Obj);
|
19
19
|
// arithmetic for all the combinations that matter
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
Value* op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
21
|
+
Value* op_colors(enum Sass_OP, const Color_RGBA&, const Color_RGBA&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
22
|
+
Value* op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
23
|
+
Value* op_number_color(enum Sass_OP, const Number&, const Color_RGBA&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
24
|
+
Value* op_color_number(enum Sass_OP, const Color_RGBA&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
25
25
|
|
26
26
|
};
|
27
27
|
|
data/ext/libsass/src/output.cpp
CHANGED
@@ -1,6 +1,10 @@
|
|
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 "ast.hpp"
|
3
6
|
#include "output.hpp"
|
7
|
+
#include "util.hpp"
|
4
8
|
|
5
9
|
namespace Sass {
|
6
10
|
|
@@ -12,12 +16,12 @@ namespace Sass {
|
|
12
16
|
|
13
17
|
Output::~Output() { }
|
14
18
|
|
15
|
-
void Output::fallback_impl(
|
19
|
+
void Output::fallback_impl(AST_Node* n)
|
16
20
|
{
|
17
21
|
return n->perform(this);
|
18
22
|
}
|
19
23
|
|
20
|
-
void Output::operator()(
|
24
|
+
void Output::operator()(Number* n)
|
21
25
|
{
|
22
26
|
// check for a valid unit here
|
23
27
|
// includes result for reporting
|
@@ -31,12 +35,12 @@ namespace Sass {
|
|
31
35
|
append_token(res, n);
|
32
36
|
}
|
33
37
|
|
34
|
-
void Output::operator()(
|
38
|
+
void Output::operator()(Import* imp)
|
35
39
|
{
|
36
40
|
top_nodes.push_back(imp);
|
37
41
|
}
|
38
42
|
|
39
|
-
void Output::operator()(
|
43
|
+
void Output::operator()(Map* m)
|
40
44
|
{
|
41
45
|
// should be handle in check_expression
|
42
46
|
throw Exception::InvalidValue({}, *m);
|
@@ -86,9 +90,8 @@ namespace Sass {
|
|
86
90
|
|
87
91
|
}
|
88
92
|
|
89
|
-
void Output::operator()(
|
93
|
+
void Output::operator()(Comment* c)
|
90
94
|
{
|
91
|
-
std::string txt = c->text()->to_string(opt);
|
92
95
|
// if (indentation && txt == "/**/") return;
|
93
96
|
bool important = c->is_important();
|
94
97
|
if (output_style() != COMPRESSED || important) {
|
@@ -108,7 +111,7 @@ namespace Sass {
|
|
108
111
|
}
|
109
112
|
}
|
110
113
|
|
111
|
-
void Output::operator()(
|
114
|
+
void Output::operator()(Ruleset* r)
|
112
115
|
{
|
113
116
|
Selector_Obj s = r->selector();
|
114
117
|
Block_Obj b = r->block();
|
@@ -142,19 +145,19 @@ namespace Sass {
|
|
142
145
|
Statement_Obj stm = b->at(i);
|
143
146
|
bool bPrintExpression = true;
|
144
147
|
// Check print conditions
|
145
|
-
if (
|
146
|
-
if (
|
148
|
+
if (Declaration* dec = Cast<Declaration>(stm)) {
|
149
|
+
if (String_Constant* valConst = Cast<String_Constant>(dec->value())) {
|
147
150
|
std::string val(valConst->value());
|
148
|
-
if (
|
151
|
+
if (String_Quoted* qstr = Cast<String_Quoted>(valConst)) {
|
149
152
|
if (!qstr->quote_mark() && val.empty()) {
|
150
153
|
bPrintExpression = false;
|
151
154
|
}
|
152
155
|
}
|
153
156
|
}
|
154
|
-
else if (
|
157
|
+
else if (List* list = Cast<List>(dec->value())) {
|
155
158
|
bool all_invisible = true;
|
156
159
|
for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
|
157
|
-
|
160
|
+
Expression* item = list->at(list_i);
|
158
161
|
if (!item->is_invisible()) all_invisible = false;
|
159
162
|
}
|
160
163
|
if (all_invisible && !list->is_bracketed()) bPrintExpression = false;
|
@@ -169,7 +172,7 @@ namespace Sass {
|
|
169
172
|
append_scope_closer(b);
|
170
173
|
|
171
174
|
}
|
172
|
-
void Output::operator()(
|
175
|
+
void Output::operator()(Keyframe_Rule* r)
|
173
176
|
{
|
174
177
|
Block_Obj b = r->block();
|
175
178
|
Selector_Obj v = r->name();
|
@@ -192,7 +195,7 @@ namespace Sass {
|
|
192
195
|
append_scope_closer();
|
193
196
|
}
|
194
197
|
|
195
|
-
void Output::operator()(
|
198
|
+
void Output::operator()(Supports_Block* f)
|
196
199
|
{
|
197
200
|
if (f->is_invisible()) return;
|
198
201
|
|
@@ -229,7 +232,7 @@ namespace Sass {
|
|
229
232
|
|
230
233
|
}
|
231
234
|
|
232
|
-
void Output::operator()(
|
235
|
+
void Output::operator()(Media_Block* m)
|
233
236
|
{
|
234
237
|
if (m->is_invisible()) return;
|
235
238
|
|
@@ -266,7 +269,7 @@ namespace Sass {
|
|
266
269
|
append_scope_closer();
|
267
270
|
}
|
268
271
|
|
269
|
-
void Output::operator()(
|
272
|
+
void Output::operator()(Directive* a)
|
270
273
|
{
|
271
274
|
std::string kwd = a->keyword();
|
272
275
|
Selector_Obj s = a->selector();
|
@@ -309,7 +312,7 @@ namespace Sass {
|
|
309
312
|
append_scope_closer();
|
310
313
|
}
|
311
314
|
|
312
|
-
void Output::operator()(
|
315
|
+
void Output::operator()(String_Quoted* s)
|
313
316
|
{
|
314
317
|
if (s->quote_mark()) {
|
315
318
|
append_token(quote(s->value(), s->quote_mark()), s);
|
@@ -320,7 +323,7 @@ namespace Sass {
|
|
320
323
|
}
|
321
324
|
}
|
322
325
|
|
323
|
-
void Output::operator()(
|
326
|
+
void Output::operator()(String_Constant* s)
|
324
327
|
{
|
325
328
|
std::string value(s->value());
|
326
329
|
if (s->can_compress_whitespace() && output_style() == COMPRESSED) {
|
data/ext/libsass/src/output.hpp
CHANGED
@@ -11,13 +11,6 @@
|
|
11
11
|
namespace Sass {
|
12
12
|
class Context;
|
13
13
|
|
14
|
-
// Refactor to make it generic to find linefeed (look behind)
|
15
|
-
inline bool ends_with(std::string const & value, std::string const & ending)
|
16
|
-
{
|
17
|
-
if (ending.size() > value.size()) return false;
|
18
|
-
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
19
|
-
}
|
20
|
-
|
21
14
|
class Output : public Inspect {
|
22
15
|
protected:
|
23
16
|
using Inspect::operator();
|
@@ -28,24 +21,24 @@ namespace Sass {
|
|
28
21
|
|
29
22
|
protected:
|
30
23
|
std::string charset;
|
31
|
-
std::vector<
|
24
|
+
std::vector<AST_Node*> top_nodes;
|
32
25
|
|
33
26
|
public:
|
34
27
|
OutputBuffer get_buffer(void);
|
35
28
|
|
36
|
-
virtual void operator()(
|
37
|
-
virtual void operator()(
|
38
|
-
virtual void operator()(
|
39
|
-
virtual void operator()(
|
40
|
-
virtual void operator()(
|
41
|
-
virtual void operator()(
|
42
|
-
virtual void operator()(
|
43
|
-
virtual void operator()(
|
44
|
-
virtual void operator()(
|
45
|
-
virtual void operator()(
|
46
|
-
virtual void operator()(
|
47
|
-
|
48
|
-
void fallback_impl(
|
29
|
+
virtual void operator()(Map*);
|
30
|
+
virtual void operator()(Ruleset*);
|
31
|
+
virtual void operator()(Supports_Block*);
|
32
|
+
virtual void operator()(Media_Block*);
|
33
|
+
virtual void operator()(Directive*);
|
34
|
+
virtual void operator()(Keyframe_Rule*);
|
35
|
+
virtual void operator()(Import*);
|
36
|
+
virtual void operator()(Comment*);
|
37
|
+
virtual void operator()(Number*);
|
38
|
+
virtual void operator()(String_Quoted*);
|
39
|
+
virtual void operator()(String_Constant*);
|
40
|
+
|
41
|
+
void fallback_impl(AST_Node* n);
|
49
42
|
|
50
43
|
};
|
51
44
|
|
data/ext/libsass/src/parser.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 "parser.hpp"
|
3
6
|
#include "file.hpp"
|
4
7
|
#include "inspect.hpp"
|
@@ -8,6 +11,7 @@
|
|
8
11
|
#include "color_maps.hpp"
|
9
12
|
#include "sass/functions.h"
|
10
13
|
#include "error_handling.hpp"
|
14
|
+
#include "util_string.hpp"
|
11
15
|
|
12
16
|
// Notes about delayed: some ast nodes can have delayed evaluation so
|
13
17
|
// they can preserve their original semantics if needed. This is most
|
@@ -30,11 +34,11 @@ namespace Sass {
|
|
30
34
|
using namespace Constants;
|
31
35
|
using namespace Prelexer;
|
32
36
|
|
33
|
-
Parser Parser::from_c_str(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source)
|
37
|
+
Parser Parser::from_c_str(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
|
34
38
|
{
|
35
39
|
pstate.offset.column = 0;
|
36
40
|
pstate.offset.line = 0;
|
37
|
-
Parser p(ctx, pstate, traces);
|
41
|
+
Parser p(ctx, pstate, traces, allow_parent);
|
38
42
|
p.source = source ? source : beg;
|
39
43
|
p.position = beg ? beg : p.source;
|
40
44
|
p.end = p.position + strlen(p.position);
|
@@ -44,11 +48,11 @@ namespace Sass {
|
|
44
48
|
return p;
|
45
49
|
}
|
46
50
|
|
47
|
-
Parser Parser::from_c_str(const char* beg, const char* end, Context& ctx, Backtraces traces, ParserState pstate, const char* source)
|
51
|
+
Parser Parser::from_c_str(const char* beg, const char* end, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
|
48
52
|
{
|
49
53
|
pstate.offset.column = 0;
|
50
54
|
pstate.offset.line = 0;
|
51
|
-
Parser p(ctx, pstate, traces);
|
55
|
+
Parser p(ctx, pstate, traces, allow_parent);
|
52
56
|
p.source = source ? source : beg;
|
53
57
|
p.position = beg ? beg : p.source;
|
54
58
|
p.end = end ? end : p.position + strlen(p.position);
|
@@ -66,10 +70,9 @@ namespace Sass {
|
|
66
70
|
pstate.offset.line = 0;
|
67
71
|
}
|
68
72
|
|
69
|
-
Selector_List_Obj Parser::parse_selector(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source)
|
73
|
+
Selector_List_Obj Parser::parse_selector(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
|
70
74
|
{
|
71
|
-
Parser p = Parser::from_c_str(beg, ctx, traces, pstate, source);
|
72
|
-
// ToDo: ruby sass errors on parent references
|
75
|
+
Parser p = Parser::from_c_str(beg, ctx, traces, pstate, source, allow_parent);
|
73
76
|
// ToDo: remap the source-map entries somehow
|
74
77
|
return p.parse_selector_list(false);
|
75
78
|
}
|
@@ -333,11 +336,11 @@ namespace Sass {
|
|
333
336
|
do {
|
334
337
|
while (lex< block_comment >());
|
335
338
|
if (lex< quoted_string >()) {
|
336
|
-
to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed),
|
339
|
+
to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed), {}));
|
337
340
|
}
|
338
341
|
else if (lex< uri_prefix >()) {
|
339
342
|
Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
|
340
|
-
Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, "url", args);
|
343
|
+
Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, std::string("url"), args);
|
341
344
|
|
342
345
|
if (lex< quoted_string >()) {
|
343
346
|
Expression_Obj quoted_url = parse_string();
|
@@ -479,7 +482,7 @@ namespace Sass {
|
|
479
482
|
bool is_arglist = false;
|
480
483
|
bool is_keyword = false;
|
481
484
|
Expression_Obj val = parse_space_list();
|
482
|
-
|
485
|
+
List* l = Cast<List>(val);
|
483
486
|
if (lex_css< exactly< ellipsis > >()) {
|
484
487
|
if (val->concrete_type() == Expression::MAP || (
|
485
488
|
(l != NULL && l->separator() == SASS_HASH)
|
@@ -556,7 +559,7 @@ namespace Sass {
|
|
556
559
|
lex< optional_spaces >();
|
557
560
|
const char* i = position;
|
558
561
|
// selector schema re-uses string schema implementation
|
559
|
-
|
562
|
+
String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
|
560
563
|
// the selector schema is pretty much just a wrapper for the string schema
|
561
564
|
Selector_Schema_Obj selector_schema = SASS_MEMORY_NEW(Selector_Schema, pstate, schema);
|
562
565
|
selector_schema->connect_parent(chroot == false);
|
@@ -645,13 +648,27 @@ namespace Sass {
|
|
645
648
|
// normalize underscores to hyphens
|
646
649
|
std::string name(Util::normalize_underscores(lexed));
|
647
650
|
// create the initial mixin call object
|
648
|
-
Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name,
|
651
|
+
Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, {}, {}, {});
|
649
652
|
// parse mandatory arguments
|
650
653
|
call->arguments(parse_arguments());
|
654
|
+
// parse using and optional block parameters
|
655
|
+
bool has_parameters = lex< kwd_using >() != nullptr;
|
656
|
+
|
657
|
+
if (has_parameters) {
|
658
|
+
if (!peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \"(\", was ");
|
659
|
+
} else {
|
660
|
+
if (peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \";\", was ");
|
661
|
+
}
|
662
|
+
|
663
|
+
if (has_parameters) call->block_parameters(parse_parameters());
|
664
|
+
|
651
665
|
// parse optional block
|
652
666
|
if (peek < exactly <'{'> >()) {
|
653
667
|
call->block(parse_block());
|
654
668
|
}
|
669
|
+
else if (has_parameters) {
|
670
|
+
css_error("Invalid CSS", " after ", ": expected \"{\", was ");
|
671
|
+
}
|
655
672
|
// return ast node
|
656
673
|
return call.detach();
|
657
674
|
}
|
@@ -706,7 +723,7 @@ namespace Sass {
|
|
706
723
|
}
|
707
724
|
// update for end position
|
708
725
|
group->update_pstate(pstate);
|
709
|
-
if (sel) sel->
|
726
|
+
if (sel) sel->mutable_last()->has_line_break(false);
|
710
727
|
return group.detach();
|
711
728
|
}
|
712
729
|
// EO parse_selector_list
|
@@ -719,12 +736,12 @@ namespace Sass {
|
|
719
736
|
{
|
720
737
|
|
721
738
|
NESTING_GUARD(nestings);
|
722
|
-
String_Obj reference
|
739
|
+
String_Obj reference;
|
723
740
|
lex < block_comment >();
|
724
741
|
advanceToNextToken();
|
725
742
|
Complex_Selector_Obj sel = SASS_MEMORY_NEW(Complex_Selector, pstate);
|
726
743
|
|
727
|
-
if (peek < end_of_file >()) return
|
744
|
+
if (peek < end_of_file >()) return {};
|
728
745
|
|
729
746
|
// parse the left hand side
|
730
747
|
Compound_Selector_Obj lhs;
|
@@ -743,12 +760,12 @@ namespace Sass {
|
|
743
760
|
else if (lex< sequence < exactly<'/'>, negate < exactly < '*' > > > >()) {
|
744
761
|
// comments are allowed, but not spaces?
|
745
762
|
combinator = Complex_Selector::REFERENCE;
|
746
|
-
if (!lex < re_reference_combinator >()) return
|
763
|
+
if (!lex < re_reference_combinator >()) return {};
|
747
764
|
reference = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
|
748
|
-
if (!lex < exactly < '/' > >()) return
|
765
|
+
if (!lex < exactly < '/' > >()) return {}; // ToDo: error msg?
|
749
766
|
}
|
750
767
|
|
751
|
-
if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return
|
768
|
+
if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return {};
|
752
769
|
|
753
770
|
// lex < block_comment >();
|
754
771
|
sel->head(lhs);
|
@@ -771,7 +788,7 @@ namespace Sass {
|
|
771
788
|
if (!sel->has_parent_ref() && !chroot) {
|
772
789
|
// create the objects to wrap parent selector reference
|
773
790
|
Compound_Selector_Obj head = SASS_MEMORY_NEW(Compound_Selector, pstate);
|
774
|
-
|
791
|
+
Parent_Selector* parent = SASS_MEMORY_NEW(Parent_Selector, pstate, false);
|
775
792
|
parent->media_block(last_media_block);
|
776
793
|
head->media_block(last_media_block);
|
777
794
|
// add simple selector
|
@@ -818,6 +835,7 @@ namespace Sass {
|
|
818
835
|
// parse parent selector
|
819
836
|
else if (lex< exactly<'&'> >(false))
|
820
837
|
{
|
838
|
+
if (!allow_parent) error("Parent selectors aren't allowed here.");
|
821
839
|
// this produces a linefeed!?
|
822
840
|
seq->has_parent_reference(true);
|
823
841
|
seq->append(SASS_MEMORY_NEW(Parent_Selector, pstate));
|
@@ -837,7 +855,7 @@ namespace Sass {
|
|
837
855
|
// parse type selector
|
838
856
|
else if (lex< re_type_selector >(false))
|
839
857
|
{
|
840
|
-
seq->append(SASS_MEMORY_NEW(
|
858
|
+
seq->append(SASS_MEMORY_NEW(Type_Selector, pstate, lexed));
|
841
859
|
}
|
842
860
|
// peek for abort conditions
|
843
861
|
else if (peek< spaces >()) break;
|
@@ -847,7 +865,7 @@ namespace Sass {
|
|
847
865
|
// otherwise parse another simple selector
|
848
866
|
else {
|
849
867
|
Simple_Selector_Obj sel = parse_simple_selector();
|
850
|
-
if (!sel) return
|
868
|
+
if (!sel) return {};
|
851
869
|
seq->append(sel);
|
852
870
|
}
|
853
871
|
}
|
@@ -872,7 +890,7 @@ namespace Sass {
|
|
872
890
|
return SASS_MEMORY_NEW(Id_Selector, pstate, lexed);
|
873
891
|
}
|
874
892
|
else if (lex< alternatives < variable, number, static_reference_combinator > >()) {
|
875
|
-
return SASS_MEMORY_NEW(
|
893
|
+
return SASS_MEMORY_NEW(Type_Selector, pstate, lexed);
|
876
894
|
}
|
877
895
|
else if (peek< pseudo_not >()) {
|
878
896
|
return parse_negated_selector();
|
@@ -887,7 +905,7 @@ namespace Sass {
|
|
887
905
|
return parse_attribute_selector();
|
888
906
|
}
|
889
907
|
else if (lex< placeholder >()) {
|
890
|
-
|
908
|
+
Placeholder_Selector* sel = SASS_MEMORY_NEW(Placeholder_Selector, pstate, lexed);
|
891
909
|
sel->media_block(last_media_block);
|
892
910
|
return sel;
|
893
911
|
}
|
@@ -895,7 +913,7 @@ namespace Sass {
|
|
895
913
|
css_error("Invalid CSS", " after ", ": expected selector, was ");
|
896
914
|
}
|
897
915
|
// failed
|
898
|
-
return
|
916
|
+
return {};
|
899
917
|
}
|
900
918
|
|
901
919
|
Wrapped_Selector_Obj Parser::parse_negated_selector()
|
@@ -915,7 +933,7 @@ namespace Sass {
|
|
915
933
|
// it can contain more selectors inside parentheses
|
916
934
|
Simple_Selector_Obj Parser::parse_pseudo_selector() {
|
917
935
|
if (lex< sequence<
|
918
|
-
|
936
|
+
pseudo_prefix,
|
919
937
|
// we keep the space within the name, strange enough
|
920
938
|
// ToDo: refactor output to schedule the space for it
|
921
939
|
// or do we really want to keep the real white-space?
|
@@ -966,7 +984,7 @@ namespace Sass {
|
|
966
984
|
css_error("Invalid CSS", " after ", ": expected \")\", was ");
|
967
985
|
|
968
986
|
// unreachable statement
|
969
|
-
return
|
987
|
+
return {};
|
970
988
|
}
|
971
989
|
|
972
990
|
const char* Parser::re_attr_sensitive_close(const char* src)
|
@@ -985,11 +1003,11 @@ namespace Sass {
|
|
985
1003
|
if (!lex_css< attribute_name >()) error("invalid attribute name in attribute selector");
|
986
1004
|
std::string name(lexed);
|
987
1005
|
if (lex_css< re_attr_sensitive_close >()) {
|
988
|
-
return SASS_MEMORY_NEW(Attribute_Selector, p, name, "",
|
1006
|
+
return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", {}, {});
|
989
1007
|
}
|
990
1008
|
else if (lex_css< re_attr_insensitive_close >()) {
|
991
1009
|
char modifier = lexed.begin[0];
|
992
|
-
return SASS_MEMORY_NEW(Attribute_Selector, p, name, "",
|
1010
|
+
return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", {}, modifier);
|
993
1011
|
}
|
994
1012
|
if (!lex_css< alternatives< exact_match, class_match, dash_match,
|
995
1013
|
prefix_match, suffix_match, substring_match > >()) {
|
@@ -997,7 +1015,7 @@ namespace Sass {
|
|
997
1015
|
}
|
998
1016
|
std::string matcher(lexed);
|
999
1017
|
|
1000
|
-
String_Obj value
|
1018
|
+
String_Obj value;
|
1001
1019
|
if (lex_css< identifier >()) {
|
1002
1020
|
value = SASS_MEMORY_NEW(String_Constant, p, lexed);
|
1003
1021
|
}
|
@@ -1016,7 +1034,7 @@ namespace Sass {
|
|
1016
1034
|
return SASS_MEMORY_NEW(Attribute_Selector, p, name, matcher, value, modifier);
|
1017
1035
|
}
|
1018
1036
|
error("unterminated attribute selector for " + name);
|
1019
|
-
return
|
1037
|
+
return {}; // to satisfy compilers (error must not return)
|
1020
1038
|
}
|
1021
1039
|
|
1022
1040
|
/* parse block comment and add to block */
|
@@ -1072,7 +1090,7 @@ namespace Sass {
|
|
1072
1090
|
}
|
1073
1091
|
else {
|
1074
1092
|
value = parse_list(DELAYED);
|
1075
|
-
if (
|
1093
|
+
if (List* list = Cast<List>(value)) {
|
1076
1094
|
if (!list->is_bracketed() && list->length() == 0 && !peek< exactly <'{'> >()) {
|
1077
1095
|
css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
|
1078
1096
|
}
|
@@ -1478,7 +1496,7 @@ namespace Sass {
|
|
1478
1496
|
}
|
1479
1497
|
else if (lex< identifier_schema >()) {
|
1480
1498
|
String_Obj string = parse_identifier_schema();
|
1481
|
-
if (
|
1499
|
+
if (String_Schema* schema = Cast<String_Schema>(string)) {
|
1482
1500
|
if (lex < exactly < '(' > >()) {
|
1483
1501
|
schema->append(parse_list());
|
1484
1502
|
lex < exactly < ')' > >();
|
@@ -1493,29 +1511,29 @@ namespace Sass {
|
|
1493
1511
|
return parse_function_call();
|
1494
1512
|
}
|
1495
1513
|
else if (lex< exactly<'+'> >()) {
|
1496
|
-
|
1514
|
+
Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::PLUS, parse_factor());
|
1497
1515
|
if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
|
1498
1516
|
return ex;
|
1499
1517
|
}
|
1500
1518
|
else if (lex< exactly<'-'> >()) {
|
1501
|
-
|
1519
|
+
Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_factor());
|
1502
1520
|
if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
|
1503
1521
|
return ex;
|
1504
1522
|
}
|
1505
1523
|
else if (lex< exactly<'/'> >()) {
|
1506
|
-
|
1524
|
+
Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::SLASH, parse_factor());
|
1507
1525
|
if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
|
1508
1526
|
return ex;
|
1509
1527
|
}
|
1510
1528
|
else if (lex< sequence< kwd_not > >()) {
|
1511
|
-
|
1529
|
+
Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::NOT, parse_factor());
|
1512
1530
|
if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
|
1513
1531
|
return ex;
|
1514
1532
|
}
|
1515
1533
|
// this whole branch is never hit via spec tests
|
1516
1534
|
else if (peek < sequence < one_plus < alternatives < css_whitespace, exactly<'-'>, exactly<'+'> > >, number > >()) {
|
1517
1535
|
if (parse_number_prefix()) return parse_value(); // prefix is positive
|
1518
|
-
|
1536
|
+
Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_value());
|
1519
1537
|
if (ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
|
1520
1538
|
return ex;
|
1521
1539
|
}
|
@@ -1533,9 +1551,9 @@ namespace Sass {
|
|
1533
1551
|
(L > 2 && parsed.substr(0, 3) == "-0.") );
|
1534
1552
|
}
|
1535
1553
|
|
1536
|
-
|
1554
|
+
Number* Parser::lexed_number(const ParserState& pstate, const std::string& parsed)
|
1537
1555
|
{
|
1538
|
-
|
1556
|
+
Number* nr = SASS_MEMORY_NEW(Number,
|
1539
1557
|
pstate,
|
1540
1558
|
sass_strtod(parsed.c_str()),
|
1541
1559
|
"",
|
@@ -1545,9 +1563,9 @@ namespace Sass {
|
|
1545
1563
|
return nr;
|
1546
1564
|
}
|
1547
1565
|
|
1548
|
-
|
1566
|
+
Number* Parser::lexed_percentage(const ParserState& pstate, const std::string& parsed)
|
1549
1567
|
{
|
1550
|
-
|
1568
|
+
Number* nr = SASS_MEMORY_NEW(Number,
|
1551
1569
|
pstate,
|
1552
1570
|
sass_strtod(parsed.c_str()),
|
1553
1571
|
"%",
|
@@ -1557,7 +1575,7 @@ namespace Sass {
|
|
1557
1575
|
return nr;
|
1558
1576
|
}
|
1559
1577
|
|
1560
|
-
|
1578
|
+
Number* Parser::lexed_dimension(const ParserState& pstate, const std::string& parsed)
|
1561
1579
|
{
|
1562
1580
|
size_t L = parsed.length();
|
1563
1581
|
size_t num_pos = parsed.find_first_not_of(" \n\r\t");
|
@@ -1568,7 +1586,7 @@ namespace Sass {
|
|
1568
1586
|
}
|
1569
1587
|
if (unit_pos == std::string::npos) unit_pos = L;
|
1570
1588
|
const std::string& num = parsed.substr(num_pos, unit_pos - num_pos);
|
1571
|
-
|
1589
|
+
Number* nr = SASS_MEMORY_NEW(Number,
|
1572
1590
|
pstate,
|
1573
1591
|
sass_strtod(num.c_str()),
|
1574
1592
|
Token(number(parsed.c_str())),
|
@@ -1578,9 +1596,9 @@ namespace Sass {
|
|
1578
1596
|
return nr;
|
1579
1597
|
}
|
1580
1598
|
|
1581
|
-
|
1599
|
+
Value* Parser::lexed_hex_color(const ParserState& pstate, const std::string& parsed)
|
1582
1600
|
{
|
1583
|
-
|
1601
|
+
Color_RGBA* color = NULL;
|
1584
1602
|
if (parsed[0] != '#') {
|
1585
1603
|
return SASS_MEMORY_NEW(String_Quoted, pstate, parsed);
|
1586
1604
|
}
|
@@ -1590,7 +1608,7 @@ namespace Sass {
|
|
1590
1608
|
std::string r(2, parsed[1]);
|
1591
1609
|
std::string g(2, parsed[2]);
|
1592
1610
|
std::string b(2, parsed[3]);
|
1593
|
-
color = SASS_MEMORY_NEW(
|
1611
|
+
color = SASS_MEMORY_NEW(Color_RGBA,
|
1594
1612
|
pstate,
|
1595
1613
|
static_cast<double>(strtol(r.c_str(), NULL, 16)),
|
1596
1614
|
static_cast<double>(strtol(g.c_str(), NULL, 16)),
|
@@ -1598,11 +1616,24 @@ namespace Sass {
|
|
1598
1616
|
1, // alpha channel
|
1599
1617
|
parsed);
|
1600
1618
|
}
|
1619
|
+
else if (parsed.length() == 5) {
|
1620
|
+
std::string r(2, parsed[1]);
|
1621
|
+
std::string g(2, parsed[2]);
|
1622
|
+
std::string b(2, parsed[3]);
|
1623
|
+
std::string a(2, parsed[4]);
|
1624
|
+
color = SASS_MEMORY_NEW(Color_RGBA,
|
1625
|
+
pstate,
|
1626
|
+
static_cast<double>(strtol(r.c_str(), NULL, 16)),
|
1627
|
+
static_cast<double>(strtol(g.c_str(), NULL, 16)),
|
1628
|
+
static_cast<double>(strtol(b.c_str(), NULL, 16)),
|
1629
|
+
static_cast<double>(strtol(a.c_str(), NULL, 16)) / 255,
|
1630
|
+
parsed);
|
1631
|
+
}
|
1601
1632
|
else if (parsed.length() == 7) {
|
1602
1633
|
std::string r(parsed.substr(1,2));
|
1603
1634
|
std::string g(parsed.substr(3,2));
|
1604
1635
|
std::string b(parsed.substr(5,2));
|
1605
|
-
color = SASS_MEMORY_NEW(
|
1636
|
+
color = SASS_MEMORY_NEW(Color_RGBA,
|
1606
1637
|
pstate,
|
1607
1638
|
static_cast<double>(strtol(r.c_str(), NULL, 16)),
|
1608
1639
|
static_cast<double>(strtol(g.c_str(), NULL, 16)),
|
@@ -1615,7 +1646,7 @@ namespace Sass {
|
|
1615
1646
|
std::string g(parsed.substr(3,2));
|
1616
1647
|
std::string b(parsed.substr(5,2));
|
1617
1648
|
std::string a(parsed.substr(7,2));
|
1618
|
-
color = SASS_MEMORY_NEW(
|
1649
|
+
color = SASS_MEMORY_NEW(Color_RGBA,
|
1619
1650
|
pstate,
|
1620
1651
|
static_cast<double>(strtol(r.c_str(), NULL, 16)),
|
1621
1652
|
static_cast<double>(strtol(g.c_str(), NULL, 16)),
|
@@ -1628,6 +1659,19 @@ namespace Sass {
|
|
1628
1659
|
return color;
|
1629
1660
|
}
|
1630
1661
|
|
1662
|
+
Value* Parser::color_or_string(const std::string& lexed) const
|
1663
|
+
{
|
1664
|
+
if (auto color = name_to_color(lexed)) {
|
1665
|
+
auto c = SASS_MEMORY_NEW(Color_RGBA, color);
|
1666
|
+
c->is_delayed(true);
|
1667
|
+
c->pstate(pstate);
|
1668
|
+
c->disp(lexed);
|
1669
|
+
return c;
|
1670
|
+
} else {
|
1671
|
+
return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
|
1672
|
+
}
|
1673
|
+
}
|
1674
|
+
|
1631
1675
|
// parse one value for a list
|
1632
1676
|
Expression_Obj Parser::parse_value()
|
1633
1677
|
{
|
@@ -1637,7 +1681,7 @@ namespace Sass {
|
|
1637
1681
|
if (match< ampersand >()) {
|
1638
1682
|
warning("In Sass, \"&&\" means two copies of the parent selector. You probably want to use \"and\" instead.", pstate);
|
1639
1683
|
}
|
1640
|
-
return SASS_MEMORY_NEW(
|
1684
|
+
return SASS_MEMORY_NEW(Parent_Reference, pstate); }
|
1641
1685
|
|
1642
1686
|
if (lex< kwd_important >())
|
1643
1687
|
{ return SASS_MEMORY_NEW(String_Constant, pstate, "!important"); }
|
@@ -1670,7 +1714,7 @@ namespace Sass {
|
|
1670
1714
|
{ return SASS_MEMORY_NEW(Null, pstate); }
|
1671
1715
|
|
1672
1716
|
if (lex< identifier >()) {
|
1673
|
-
return
|
1717
|
+
return color_or_string(lexed);
|
1674
1718
|
}
|
1675
1719
|
|
1676
1720
|
if (lex< percentage >())
|
@@ -1681,17 +1725,7 @@ namespace Sass {
|
|
1681
1725
|
{ return lexed_hex_color(lexed); }
|
1682
1726
|
|
1683
1727
|
if (lex< hexa >())
|
1684
|
-
{
|
1685
|
-
std::string s = lexed.to_string();
|
1686
|
-
|
1687
|
-
deprecated(
|
1688
|
-
"The value \""+s+"\" is currently parsed as a string, but it will be parsed as a color in",
|
1689
|
-
"future versions of Sass. Use \"unquote('"+s+"')\" to continue parsing it as a string.",
|
1690
|
-
true, pstate
|
1691
|
-
);
|
1692
|
-
|
1693
|
-
return SASS_MEMORY_NEW(String_Quoted, pstate, lexed);
|
1694
|
-
}
|
1728
|
+
{ return lexed_hex_color(lexed); }
|
1695
1729
|
|
1696
1730
|
if (lex< sequence < exactly <'#'>, identifier > >())
|
1697
1731
|
{ return SASS_MEMORY_NEW(String_Quoted, pstate, lexed); }
|
@@ -1710,14 +1744,10 @@ namespace Sass {
|
|
1710
1744
|
if (lex< variable >())
|
1711
1745
|
{ return SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)); }
|
1712
1746
|
|
1713
|
-
// Special case handling for `%` proceeding an interpolant.
|
1714
|
-
if (lex< sequence< exactly<'%'>, optional< percentage > > >())
|
1715
|
-
{ return SASS_MEMORY_NEW(String_Constant, pstate, lexed); }
|
1716
|
-
|
1717
1747
|
css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
|
1718
1748
|
|
1719
1749
|
// unreachable statement
|
1720
|
-
return
|
1750
|
+
return {};
|
1721
1751
|
}
|
1722
1752
|
|
1723
1753
|
// this parses interpolation inside other strings
|
@@ -1730,7 +1760,7 @@ namespace Sass {
|
|
1730
1760
|
find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);
|
1731
1761
|
|
1732
1762
|
if (!p) {
|
1733
|
-
|
1763
|
+
String_Quoted* str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end), 0, false, false, true, css);
|
1734
1764
|
if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*');
|
1735
1765
|
return str_quoted;
|
1736
1766
|
}
|
@@ -1774,74 +1804,66 @@ namespace Sass {
|
|
1774
1804
|
return schema.detach();
|
1775
1805
|
}
|
1776
1806
|
|
1777
|
-
String_Schema_Obj Parser::parse_css_variable_value(
|
1807
|
+
String_Schema_Obj Parser::parse_css_variable_value()
|
1778
1808
|
{
|
1779
1809
|
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
{
|
1795
|
-
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
|
1796
|
-
if (
|
1797
|
-
(top_level && lex< css_variable_top_level_value >(false)) ||
|
1798
|
-
(!top_level && lex< css_variable_value >(false))
|
1799
|
-
) {
|
1800
|
-
Token str(lexed);
|
1801
|
-
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, str));
|
1802
|
-
}
|
1803
|
-
else if (Expression_Obj tok = lex_interpolation()) {
|
1804
|
-
if (String_Schema_Ptr s = Cast<String_Schema>(tok)) {
|
1805
|
-
schema->concat(s);
|
1806
|
-
} else {
|
1807
|
-
schema->append(tok);
|
1808
|
-
}
|
1809
|
-
}
|
1810
|
-
else if (lex< quoted_string >()) {
|
1811
|
-
Expression_Obj tok = parse_string();
|
1812
|
-
if (String_Schema_Ptr s = Cast<String_Schema>(tok)) {
|
1813
|
-
schema->concat(s);
|
1814
|
-
} else {
|
1815
|
-
schema->append(tok);
|
1816
|
-
}
|
1817
|
-
}
|
1818
|
-
else {
|
1819
|
-
if (peek< alternatives< exactly<'('>, exactly<'['>, exactly<'{'> > >()) {
|
1820
|
-
if (lex< exactly<'('> >()) {
|
1821
|
-
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string("(")));
|
1822
|
-
if (String_Schema_Obj tok = parse_css_variable_value(false)) schema->concat(tok);
|
1823
|
-
if (!lex< exactly<')'> >()) css_error("Invalid CSS", " after ", ": expected \")\", was ");
|
1824
|
-
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(")")));
|
1810
|
+
std::vector<char> brackets;
|
1811
|
+
while (true) {
|
1812
|
+
if (
|
1813
|
+
(brackets.empty() && lex< css_variable_top_level_value >(false)) ||
|
1814
|
+
(!brackets.empty() && lex< css_variable_value >(false))
|
1815
|
+
) {
|
1816
|
+
Token str(lexed);
|
1817
|
+
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, str));
|
1818
|
+
} else if (Expression_Obj tok = lex_interpolation()) {
|
1819
|
+
if (String_Schema* s = Cast<String_Schema>(tok)) {
|
1820
|
+
if (s->empty()) break;
|
1821
|
+
schema->concat(s);
|
1822
|
+
} else {
|
1823
|
+
schema->append(tok);
|
1825
1824
|
}
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1825
|
+
} else if (lex< quoted_string >()) {
|
1826
|
+
Expression_Obj tok = parse_string();
|
1827
|
+
if (tok.isNull()) break;
|
1828
|
+
if (String_Schema* s = Cast<String_Schema>(tok)) {
|
1829
|
+
if (s->empty()) break;
|
1830
|
+
schema->concat(s);
|
1831
|
+
} else {
|
1832
|
+
schema->append(tok);
|
1831
1833
|
}
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1834
|
+
} else if (lex< alternatives< exactly<'('>, exactly<'['>, exactly<'{'> > >()) {
|
1835
|
+
const char opening_bracket = *(position - 1);
|
1836
|
+
brackets.push_back(opening_bracket);
|
1837
|
+
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(1, opening_bracket)));
|
1838
|
+
} else if (const char *match = peek< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >()) {
|
1839
|
+
if (brackets.empty()) break;
|
1840
|
+
const char closing_bracket = *(match - 1);
|
1841
|
+
if (brackets.back() != Util::opening_bracket_for(closing_bracket)) {
|
1842
|
+
std::string message = ": expected \"";
|
1843
|
+
message += Util::closing_bracket_for(brackets.back());
|
1844
|
+
message += "\", was ";
|
1845
|
+
css_error("Invalid CSS", " after ", message);
|
1837
1846
|
}
|
1847
|
+
lex< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >();
|
1848
|
+
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(1, closing_bracket)));
|
1849
|
+
brackets.pop_back();
|
1850
|
+
} else {
|
1851
|
+
break;
|
1838
1852
|
}
|
1839
1853
|
}
|
1840
1854
|
|
1841
|
-
|
1855
|
+
if (!brackets.empty()) {
|
1856
|
+
std::string message = ": expected \"";
|
1857
|
+
message += Util::closing_bracket_for(brackets.back());
|
1858
|
+
message += "\", was ";
|
1859
|
+
css_error("Invalid CSS", " after ", message);
|
1860
|
+
}
|
1861
|
+
|
1862
|
+
if (schema->empty()) error("Custom property values may not be empty.");
|
1863
|
+
return schema.detach();
|
1842
1864
|
}
|
1843
1865
|
|
1844
|
-
|
1866
|
+
Value_Obj Parser::parse_static_value()
|
1845
1867
|
{
|
1846
1868
|
lex< static_value >();
|
1847
1869
|
Token str(lexed);
|
@@ -1852,8 +1874,7 @@ namespace Sass {
|
|
1852
1874
|
--str.end;
|
1853
1875
|
--position;
|
1854
1876
|
|
1855
|
-
|
1856
|
-
return str_node;
|
1877
|
+
return color_or_string(str.time_wspace());;
|
1857
1878
|
}
|
1858
1879
|
|
1859
1880
|
String_Obj Parser::parse_string()
|
@@ -1872,7 +1893,7 @@ namespace Sass {
|
|
1872
1893
|
return SASS_MEMORY_NEW(String_Quoted, pstate, std::string(str.begin, str.end));
|
1873
1894
|
}
|
1874
1895
|
|
1875
|
-
|
1896
|
+
String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
|
1876
1897
|
while (i < str.end) {
|
1877
1898
|
p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, str.end);
|
1878
1899
|
if (p) {
|
@@ -1907,7 +1928,7 @@ namespace Sass {
|
|
1907
1928
|
|
1908
1929
|
String_Obj Parser::parse_ie_keyword_arg()
|
1909
1930
|
{
|
1910
|
-
|
1931
|
+
String_Schema_Obj kwd_arg = SASS_MEMORY_NEW(String_Schema, pstate, 3);
|
1911
1932
|
if (lex< variable >()) {
|
1912
1933
|
kwd_arg->append(SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)));
|
1913
1934
|
} else {
|
@@ -1962,7 +1983,7 @@ namespace Sass {
|
|
1962
1983
|
if (lex< re_static_expression >()) {
|
1963
1984
|
ex = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
|
1964
1985
|
} else {
|
1965
|
-
ex = parse_list();
|
1986
|
+
ex = parse_list(true);
|
1966
1987
|
}
|
1967
1988
|
ex->is_interpolant(true);
|
1968
1989
|
schema->append(ex);
|
@@ -1986,7 +2007,7 @@ namespace Sass {
|
|
1986
2007
|
}
|
1987
2008
|
if (peek < exactly < '-' > >()) break;
|
1988
2009
|
}
|
1989
|
-
else if (lex<
|
2010
|
+
else if (lex< identifier >()) {
|
1990
2011
|
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
|
1991
2012
|
if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
|
1992
2013
|
// need_space = true;
|
@@ -2128,7 +2149,7 @@ namespace Sass {
|
|
2128
2149
|
uri = url_string->to_string({ NESTED, 5 });
|
2129
2150
|
}
|
2130
2151
|
|
2131
|
-
if (
|
2152
|
+
if (String_Schema* schema = Cast<String_Schema>(url_string)) {
|
2132
2153
|
String_Schema_Obj res = SASS_MEMORY_NEW(String_Schema, pstate);
|
2133
2154
|
res->append(SASS_MEMORY_NEW(String_Constant, pstate, prefix));
|
2134
2155
|
res->append(schema);
|
@@ -2155,6 +2176,7 @@ namespace Sass {
|
|
2155
2176
|
while (pp && peek< exactly< hash_lbrace > >(pp)) {
|
2156
2177
|
pp = sequence< interpolant, real_uri_value >(pp);
|
2157
2178
|
}
|
2179
|
+
if (!pp) return {};
|
2158
2180
|
position = pp;
|
2159
2181
|
return parse_interpolated_chunk(Token(p, position));
|
2160
2182
|
}
|
@@ -2163,7 +2185,7 @@ namespace Sass {
|
|
2163
2185
|
return SASS_MEMORY_NEW(String_Constant, pstate, res);
|
2164
2186
|
}
|
2165
2187
|
|
2166
|
-
return
|
2188
|
+
return {};
|
2167
2189
|
}
|
2168
2190
|
|
2169
2191
|
Function_Call_Obj Parser::parse_function_call()
|
@@ -2179,18 +2201,21 @@ namespace Sass {
|
|
2179
2201
|
return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);
|
2180
2202
|
}
|
2181
2203
|
|
2182
|
-
|
2204
|
+
Function_Call_Obj Parser::parse_function_call_schema()
|
2183
2205
|
{
|
2184
2206
|
String_Obj name = parse_identifier_schema();
|
2185
2207
|
ParserState source_position_of_call = pstate;
|
2186
2208
|
Arguments_Obj args = parse_arguments();
|
2187
2209
|
|
2188
|
-
return SASS_MEMORY_NEW(
|
2210
|
+
return SASS_MEMORY_NEW(Function_Call, source_position_of_call, name, args);
|
2189
2211
|
}
|
2190
2212
|
|
2191
2213
|
Content_Obj Parser::parse_content_directive()
|
2192
2214
|
{
|
2193
|
-
|
2215
|
+
ParserState call_pos = pstate;
|
2216
|
+
Arguments_Obj args = parse_arguments();
|
2217
|
+
|
2218
|
+
return SASS_MEMORY_NEW(Content, call_pos, args);
|
2194
2219
|
}
|
2195
2220
|
|
2196
2221
|
If_Obj Parser::parse_if_directive(bool else_if)
|
@@ -2200,7 +2225,7 @@ namespace Sass {
|
|
2200
2225
|
bool root = block_stack.back()->is_root();
|
2201
2226
|
Expression_Obj predicate = parse_list();
|
2202
2227
|
Block_Obj block = parse_block(root);
|
2203
|
-
Block_Obj alternative
|
2228
|
+
Block_Obj alternative;
|
2204
2229
|
|
2205
2230
|
// only throw away comment if we parse a case
|
2206
2231
|
// we want all other comments to be parsed
|
@@ -2285,7 +2310,7 @@ namespace Sass {
|
|
2285
2310
|
stack.push_back(Scope::Control);
|
2286
2311
|
bool root = block_stack.back()->is_root();
|
2287
2312
|
// create the initial while call object
|
2288
|
-
While_Obj call = SASS_MEMORY_NEW(While, pstate,
|
2313
|
+
While_Obj call = SASS_MEMORY_NEW(While, pstate, {}, {});
|
2289
2314
|
// parse mandatory predicate
|
2290
2315
|
Expression_Obj predicate = parse_list();
|
2291
2316
|
List_Obj l = Cast<List>(predicate);
|
@@ -2305,7 +2330,7 @@ namespace Sass {
|
|
2305
2330
|
Media_Block_Obj Parser::parse_media_block()
|
2306
2331
|
{
|
2307
2332
|
stack.push_back(Scope::Media);
|
2308
|
-
Media_Block_Obj media_block = SASS_MEMORY_NEW(Media_Block, pstate,
|
2333
|
+
Media_Block_Obj media_block = SASS_MEMORY_NEW(Media_Block, pstate, {}, {});
|
2309
2334
|
|
2310
2335
|
media_block->media_queries(parse_media_queries());
|
2311
2336
|
|
@@ -2327,7 +2352,7 @@ namespace Sass {
|
|
2327
2352
|
return queries.detach();
|
2328
2353
|
}
|
2329
2354
|
|
2330
|
-
//
|
2355
|
+
// Expression* Parser::parse_media_query()
|
2331
2356
|
Media_Query_Obj Parser::parse_media_query()
|
2332
2357
|
{
|
2333
2358
|
advanceToNextToken();
|
@@ -2341,7 +2366,7 @@ namespace Sass {
|
|
2341
2366
|
|
2342
2367
|
while (lex_css < kwd_and >()) media_query->append(parse_media_expression());
|
2343
2368
|
if (lex < identifier_schema >()) {
|
2344
|
-
|
2369
|
+
String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
|
2345
2370
|
schema->append(media_query->media_type());
|
2346
2371
|
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
|
2347
2372
|
schema->append(parse_identifier_schema());
|
@@ -2358,7 +2383,7 @@ namespace Sass {
|
|
2358
2383
|
{
|
2359
2384
|
if (lex < identifier_schema >()) {
|
2360
2385
|
String_Obj ss = parse_identifier_schema();
|
2361
|
-
return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss,
|
2386
|
+
return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss, {}, true);
|
2362
2387
|
}
|
2363
2388
|
if (!lex_css< exactly<'('> >()) {
|
2364
2389
|
error("media query expression must begin with '('");
|
@@ -2368,7 +2393,7 @@ namespace Sass {
|
|
2368
2393
|
error("media feature required in media query expression");
|
2369
2394
|
}
|
2370
2395
|
feature = parse_expression();
|
2371
|
-
Expression_Obj expression
|
2396
|
+
Expression_Obj expression;
|
2372
2397
|
if (lex_css< exactly<':'> >()) {
|
2373
2398
|
expression = parse_list(DELAYED);
|
2374
2399
|
}
|
@@ -2382,10 +2407,7 @@ namespace Sass {
|
|
2382
2407
|
// these are very similar to media blocks
|
2383
2408
|
Supports_Block_Obj Parser::parse_supports_directive()
|
2384
2409
|
{
|
2385
|
-
Supports_Condition_Obj cond = parse_supports_condition();
|
2386
|
-
if (!cond) {
|
2387
|
-
css_error("Invalid CSS", " after ", ": expected @supports condition (e.g. (display: flexbox)), was ", false);
|
2388
|
-
}
|
2410
|
+
Supports_Condition_Obj cond = parse_supports_condition(/*top_level=*/true);
|
2389
2411
|
// create the ast node object for the support queries
|
2390
2412
|
Supports_Block_Obj query = SASS_MEMORY_NEW(Supports_Block, pstate, cond);
|
2391
2413
|
// additional block is mandatory
|
@@ -2397,27 +2419,27 @@ namespace Sass {
|
|
2397
2419
|
|
2398
2420
|
// parse one query operation
|
2399
2421
|
// may encounter nested queries
|
2400
|
-
Supports_Condition_Obj Parser::parse_supports_condition()
|
2422
|
+
Supports_Condition_Obj Parser::parse_supports_condition(bool top_level)
|
2401
2423
|
{
|
2402
2424
|
lex < css_whitespace >();
|
2403
2425
|
Supports_Condition_Obj cond;
|
2404
2426
|
if ((cond = parse_supports_negation())) return cond;
|
2405
|
-
if ((cond = parse_supports_operator())) return cond;
|
2427
|
+
if ((cond = parse_supports_operator(top_level))) return cond;
|
2406
2428
|
if ((cond = parse_supports_interpolation())) return cond;
|
2407
2429
|
return cond;
|
2408
2430
|
}
|
2409
2431
|
|
2410
2432
|
Supports_Condition_Obj Parser::parse_supports_negation()
|
2411
2433
|
{
|
2412
|
-
if (!lex < kwd_not >()) return
|
2413
|
-
Supports_Condition_Obj cond = parse_supports_condition_in_parens();
|
2434
|
+
if (!lex < kwd_not >()) return {};
|
2435
|
+
Supports_Condition_Obj cond = parse_supports_condition_in_parens(/*parens_required=*/true);
|
2414
2436
|
return SASS_MEMORY_NEW(Supports_Negation, pstate, cond);
|
2415
2437
|
}
|
2416
2438
|
|
2417
|
-
Supports_Condition_Obj Parser::parse_supports_operator()
|
2439
|
+
Supports_Condition_Obj Parser::parse_supports_operator(bool top_level)
|
2418
2440
|
{
|
2419
|
-
Supports_Condition_Obj cond = parse_supports_condition_in_parens();
|
2420
|
-
if (cond.isNull()) return
|
2441
|
+
Supports_Condition_Obj cond = parse_supports_condition_in_parens(/*parens_required=*/top_level);
|
2442
|
+
if (cond.isNull()) return {};
|
2421
2443
|
|
2422
2444
|
while (true) {
|
2423
2445
|
Supports_Operator::Operand op = Supports_Operator::OR;
|
@@ -2425,9 +2447,9 @@ namespace Sass {
|
|
2425
2447
|
else if(!lex < kwd_or >()) { break; }
|
2426
2448
|
|
2427
2449
|
lex < css_whitespace >();
|
2428
|
-
Supports_Condition_Obj right = parse_supports_condition_in_parens();
|
2450
|
+
Supports_Condition_Obj right = parse_supports_condition_in_parens(/*parens_required=*/true);
|
2429
2451
|
|
2430
|
-
//
|
2452
|
+
// Supports_Condition* cc = SASS_MEMORY_NEW(Supports_Condition, *static_cast<Supports_Condition*>(cond));
|
2431
2453
|
cond = SASS_MEMORY_NEW(Supports_Operator, pstate, cond, right, op);
|
2432
2454
|
}
|
2433
2455
|
return cond;
|
@@ -2435,10 +2457,10 @@ namespace Sass {
|
|
2435
2457
|
|
2436
2458
|
Supports_Condition_Obj Parser::parse_supports_interpolation()
|
2437
2459
|
{
|
2438
|
-
if (!lex < interpolant >()) return
|
2460
|
+
if (!lex < interpolant >()) return {};
|
2439
2461
|
|
2440
2462
|
String_Obj interp = parse_interpolated_chunk(lexed);
|
2441
|
-
if (!interp) return
|
2463
|
+
if (!interp) return {};
|
2442
2464
|
|
2443
2465
|
return SASS_MEMORY_NEW(Supports_Interpolation, pstate, interp);
|
2444
2466
|
}
|
@@ -2447,10 +2469,10 @@ namespace Sass {
|
|
2447
2469
|
// look like declarations their semantics differ significantly
|
2448
2470
|
Supports_Condition_Obj Parser::parse_supports_declaration()
|
2449
2471
|
{
|
2450
|
-
|
2472
|
+
Supports_Condition* cond;
|
2451
2473
|
// parse something declaration like
|
2452
2474
|
Expression_Obj feature = parse_expression();
|
2453
|
-
Expression_Obj expression
|
2475
|
+
Expression_Obj expression;
|
2454
2476
|
if (lex_css< exactly<':'> >()) {
|
2455
2477
|
expression = parse_list(DELAYED);
|
2456
2478
|
}
|
@@ -2463,21 +2485,24 @@ namespace Sass {
|
|
2463
2485
|
return cond;
|
2464
2486
|
}
|
2465
2487
|
|
2466
|
-
Supports_Condition_Obj Parser::parse_supports_condition_in_parens()
|
2488
|
+
Supports_Condition_Obj Parser::parse_supports_condition_in_parens(bool parens_required)
|
2467
2489
|
{
|
2468
2490
|
Supports_Condition_Obj interp = parse_supports_interpolation();
|
2469
2491
|
if (interp != 0) return interp;
|
2470
2492
|
|
2471
|
-
if (!lex < exactly <'('> >())
|
2493
|
+
if (!lex < exactly <'('> >()) {
|
2494
|
+
if (parens_required) {
|
2495
|
+
css_error("Invalid CSS", " after ", ": expected @supports condition (e.g. (display: flexbox)), was ", /*trim=*/false);
|
2496
|
+
} else {
|
2497
|
+
return {};
|
2498
|
+
}
|
2499
|
+
}
|
2472
2500
|
lex < css_whitespace >();
|
2473
2501
|
|
2474
|
-
Supports_Condition_Obj cond = parse_supports_condition();
|
2475
|
-
if (cond
|
2476
|
-
|
2477
|
-
|
2478
|
-
cond = parse_supports_declaration();
|
2479
|
-
if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration");
|
2480
|
-
}
|
2502
|
+
Supports_Condition_Obj cond = parse_supports_condition(/*top_level=*/false);
|
2503
|
+
if (cond.isNull()) cond = parse_supports_declaration();
|
2504
|
+
if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration");
|
2505
|
+
|
2481
2506
|
lex < css_whitespace >();
|
2482
2507
|
return cond;
|
2483
2508
|
}
|
@@ -2486,7 +2511,7 @@ namespace Sass {
|
|
2486
2511
|
{
|
2487
2512
|
stack.push_back(Scope::AtRoot);
|
2488
2513
|
ParserState at_source_position = pstate;
|
2489
|
-
Block_Obj body
|
2514
|
+
Block_Obj body;
|
2490
2515
|
At_Root_Query_Obj expr;
|
2491
2516
|
Lookahead lookahead_result;
|
2492
2517
|
if (lex_css< exactly<'('> >()) {
|
@@ -2541,7 +2566,7 @@ namespace Sass {
|
|
2541
2566
|
|
2542
2567
|
// this whole branch is never hit via spec tests
|
2543
2568
|
|
2544
|
-
|
2569
|
+
Directive* at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd);
|
2545
2570
|
Lookahead lookahead = lookahead_for_include(position);
|
2546
2571
|
if (lookahead.found && !lookahead.has_interpolants) {
|
2547
2572
|
at_rule->selector(parse_selector_list(false));
|
@@ -2612,7 +2637,7 @@ namespace Sass {
|
|
2612
2637
|
if (lex < interpolant >(true) != NULL) {
|
2613
2638
|
return parse_interpolated_chunk(lexed, true);
|
2614
2639
|
}
|
2615
|
-
return
|
2640
|
+
return {};
|
2616
2641
|
}
|
2617
2642
|
|
2618
2643
|
Expression_Obj Parser::lex_interp_uri()
|
@@ -2678,30 +2703,32 @@ namespace Sass {
|
|
2678
2703
|
if (match) {
|
2679
2704
|
return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
|
2680
2705
|
}
|
2681
|
-
return
|
2706
|
+
return {};
|
2682
2707
|
}
|
2683
2708
|
|
2684
2709
|
Expression_Obj Parser::lex_almost_any_value_token()
|
2685
2710
|
{
|
2686
2711
|
Expression_Obj rv;
|
2687
|
-
if (*position == 0) return
|
2712
|
+
if (*position == 0) return {};
|
2688
2713
|
if ((rv = lex_almost_any_value_chars())) return rv;
|
2689
2714
|
// if ((rv = lex_block_comment())) return rv;
|
2690
2715
|
// if ((rv = lex_single_line_comment())) return rv;
|
2691
2716
|
if ((rv = lex_interp_string())) return rv;
|
2692
2717
|
if ((rv = lex_interp_uri())) return rv;
|
2693
2718
|
if ((rv = lex_interpolation())) return rv;
|
2694
|
-
|
2719
|
+
if (lex< alternatives< hex, hex0 > >())
|
2720
|
+
{ return lexed_hex_color(lexed); }
|
2721
|
+
return rv;
|
2695
2722
|
}
|
2696
2723
|
|
2697
2724
|
String_Schema_Obj Parser::parse_almost_any_value()
|
2698
2725
|
{
|
2699
2726
|
|
2700
2727
|
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
|
2701
|
-
if (*position == 0) return
|
2728
|
+
if (*position == 0) return {};
|
2702
2729
|
lex < spaces >(false);
|
2703
2730
|
Expression_Obj token = lex_almost_any_value_token();
|
2704
|
-
if (!token) return
|
2731
|
+
if (!token) return {};
|
2705
2732
|
schema->append(token);
|
2706
2733
|
if (*position == 0) {
|
2707
2734
|
schema->rtrim();
|
@@ -2777,6 +2804,7 @@ namespace Sass {
|
|
2777
2804
|
>(p)
|
2778
2805
|
) {
|
2779
2806
|
bool could_be_property = peek< sequence< exactly<'-'>, exactly<'-'> > >(p) != 0;
|
2807
|
+
bool could_be_escaped = false;
|
2780
2808
|
while (p < q) {
|
2781
2809
|
// did we have interpolations?
|
2782
2810
|
if (*p == '#' && *(p+1) == '{') {
|
@@ -2785,9 +2813,10 @@ namespace Sass {
|
|
2785
2813
|
}
|
2786
2814
|
// A property that's ambiguous with a nested selector is interpreted as a
|
2787
2815
|
// custom property.
|
2788
|
-
if (*p == ':') {
|
2816
|
+
if (*p == ':' && !could_be_escaped) {
|
2789
2817
|
rv.is_custom_property = could_be_property || p+1 == q || peek< space >(p+1);
|
2790
2818
|
}
|
2819
|
+
could_be_escaped = *p == '\\';
|
2791
2820
|
++ p;
|
2792
2821
|
}
|
2793
2822
|
// store anyway }
|
@@ -2981,7 +3010,7 @@ namespace Sass {
|
|
2981
3010
|
|
2982
3011
|
Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, std::vector<Operand>& ops, size_t i)
|
2983
3012
|
{
|
2984
|
-
if (
|
3013
|
+
if (String_Schema* schema = Cast<String_Schema>(base)) {
|
2985
3014
|
// return schema;
|
2986
3015
|
if (schema->has_interpolants()) {
|
2987
3016
|
if (i + 1 < operands.size() && (
|
@@ -3004,7 +3033,7 @@ namespace Sass {
|
|
3004
3033
|
}
|
3005
3034
|
|
3006
3035
|
for (size_t S = operands.size(); i < S; ++i) {
|
3007
|
-
if (
|
3036
|
+
if (String_Schema* schema = Cast<String_Schema>(operands[i])) {
|
3008
3037
|
if (schema->has_interpolants()) {
|
3009
3038
|
if (i + 1 < S) {
|
3010
3039
|
// this whole branch is never hit via spec tests
|
@@ -3021,13 +3050,13 @@ namespace Sass {
|
|
3021
3050
|
} else {
|
3022
3051
|
base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]);
|
3023
3052
|
}
|
3024
|
-
|
3053
|
+
Binary_Expression* b = Cast<Binary_Expression>(base.ptr());
|
3025
3054
|
if (b && ops[i].operand == Sass_OP::DIV && b->left()->is_delayed() && b->right()->is_delayed()) {
|
3026
3055
|
base->is_delayed(true);
|
3027
3056
|
}
|
3028
3057
|
}
|
3029
3058
|
// nested binary expression are never to be delayed
|
3030
|
-
if (
|
3059
|
+
if (Binary_Expression* b = Cast<Binary_Expression>(base)) {
|
3031
3060
|
if (Cast<Binary_Expression>(b->left())) base->set_delayed(false);
|
3032
3061
|
if (Cast<Binary_Expression>(b->right())) base->set_delayed(false);
|
3033
3062
|
}
|
@@ -3038,8 +3067,11 @@ namespace Sass {
|
|
3038
3067
|
{
|
3039
3068
|
Position p(pos.line ? pos : before_token);
|
3040
3069
|
ParserState pstate(path, source, p, Offset(0, 0));
|
3070
|
+
// `pstate.src` may not outlive stack unwind so we must copy it.
|
3071
|
+
char *src_copy = sass_copy_c_string(pstate.src);
|
3072
|
+
pstate.src = src_copy;
|
3041
3073
|
traces.push_back(Backtrace(pstate));
|
3042
|
-
throw Exception::InvalidSass(pstate, traces, msg);
|
3074
|
+
throw Exception::InvalidSass(pstate, traces, msg, src_copy);
|
3043
3075
|
}
|
3044
3076
|
|
3045
3077
|
void Parser::error(std::string msg)
|