sassc 2.2.1 → 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/.travis.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/Rakefile +1 -3
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +4 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +158 -168
- data/ext/libsass/src/ast.hpp +389 -230
- data/ext/libsass/src/ast_def_macros.hpp +18 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +594 -1026
- data/ext/libsass/src/ast_selectors.hpp +339 -385
- data/ext/libsass/src/ast_supports.cpp +36 -52
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +271 -84
- data/ext/libsass/src/ast_values.hpp +116 -107
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +18 -18
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +40 -41
- data/ext/libsass/src/check_nesting.hpp +6 -2
- data/ext/libsass/src/color_maps.cpp +14 -13
- data/ext/libsass/src/color_maps.hpp +1 -9
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +92 -119
- data/ext/libsass/src/context.hpp +41 -53
- data/ext/libsass/src/cssize.cpp +66 -149
- data/ext/libsass/src/cssize.hpp +17 -23
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +451 -295
- data/ext/libsass/src/emitter.cpp +15 -16
- data/ext/libsass/src/emitter.hpp +10 -12
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +29 -24
- data/ext/libsass/src/error_handling.cpp +62 -41
- data/ext/libsass/src/error_handling.hpp +61 -51
- data/ext/libsass/src/eval.cpp +167 -281
- data/ext/libsass/src/eval.hpp +27 -29
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +275 -222
- data/ext/libsass/src/expand.hpp +36 -16
- 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 +81 -72
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +20 -18
- data/ext/libsass/src/fn_lists.cpp +30 -29
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +34 -46
- data/ext/libsass/src/fn_numbers.cpp +20 -13
- data/ext/libsass/src/fn_selectors.cpp +98 -128
- data/ext/libsass/src/fn_strings.cpp +47 -33
- data/ext/libsass/src/fn_utils.cpp +31 -29
- data/ext/libsass/src/fn_utils.hpp +17 -11
- data/ext/libsass/src/inspect.cpp +186 -148
- data/ext/libsass/src/inspect.hpp +31 -29
- data/ext/libsass/src/lexer.cpp +20 -82
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +23 -37
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/mapping.hpp +1 -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/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +71 -61
- data/ext/libsass/src/operators.cpp +19 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +45 -64
- data/ext/libsass/src/output.hpp +6 -6
- data/ext/libsass/src/parser.cpp +512 -700
- data/ext/libsass/src/parser.hpp +89 -97
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.cpp +16 -15
- data/ext/libsass/src/sass.hpp +10 -5
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +91 -122
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +8 -11
- 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 +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +24 -22
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +48 -50
- data/ext/libsass/src/util.hpp +20 -21
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +62 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +4 -6
- data/lib/sassc/script.rb +4 -4
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +18 -1
- data/test/native_test.rb +4 -4
- metadata +29 -15
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/lib/sassc/native/lib_c.rb +0 -21
data/ext/libsass/src/parser.hpp
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
#ifndef SASS_PARSER_H
|
2
2
|
#define SASS_PARSER_H
|
3
3
|
|
4
|
+
// sass.hpp must go before all system headers to get the
|
5
|
+
// __EXTENSIONS__ fix on Solaris.
|
4
6
|
#include "sass.hpp"
|
5
7
|
|
6
8
|
#include <string>
|
@@ -11,6 +13,7 @@
|
|
11
13
|
#include "context.hpp"
|
12
14
|
#include "position.hpp"
|
13
15
|
#include "prelexer.hpp"
|
16
|
+
#include "source.hpp"
|
14
17
|
|
15
18
|
#ifndef MAX_NESTING
|
16
19
|
// Note that this limit is not an exact science
|
@@ -32,42 +35,31 @@ struct Lookahead {
|
|
32
35
|
|
33
36
|
namespace Sass {
|
34
37
|
|
35
|
-
class Parser : public
|
38
|
+
class Parser : public SourceSpan {
|
36
39
|
public:
|
37
40
|
|
38
41
|
enum Scope { Root, Mixin, Function, Media, Control, Properties, Rules, AtRoot };
|
39
42
|
|
40
43
|
Context& ctx;
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
const char*
|
44
|
+
sass::vector<Block_Obj> block_stack;
|
45
|
+
sass::vector<Scope> stack;
|
46
|
+
SourceDataObj source;
|
47
|
+
const char* begin;
|
45
48
|
const char* position;
|
46
49
|
const char* end;
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
+
Offset before_token;
|
51
|
+
Offset after_token;
|
52
|
+
SourceSpan pstate;
|
50
53
|
Backtraces traces;
|
51
54
|
size_t indentation;
|
52
55
|
size_t nestings;
|
53
56
|
bool allow_parent;
|
54
|
-
|
55
57
|
Token lexed;
|
56
58
|
|
57
|
-
Parser(
|
58
|
-
: ParserState(pstate), ctx(ctx), block_stack(), stack(0), last_media_block(),
|
59
|
-
source(0), position(0), end(0), before_token(pstate), after_token(pstate),
|
60
|
-
pstate(pstate), traces(traces), indentation(0), nestings(0), allow_parent(allow_parent)
|
61
|
-
{
|
62
|
-
stack.push_back(Scope::Root);
|
63
|
-
}
|
59
|
+
Parser(SourceData* source, Context& ctx, Backtraces, bool allow_parent = true);
|
64
60
|
|
65
|
-
// static Parser from_string(const std::string& src, Context& ctx, ParserState pstate = ParserState("[STRING]"));
|
66
|
-
static Parser from_c_str(const char* src, Context& ctx, Backtraces, ParserState pstate = ParserState("[CSTRING]"), const char* source = nullptr, bool allow_parent = true);
|
67
|
-
static Parser from_c_str(const char* beg, const char* end, Context& ctx, Backtraces, ParserState pstate = ParserState("[CSTRING]"), const char* source = nullptr, bool allow_parent = true);
|
68
|
-
static Parser from_token(Token t, Context& ctx, Backtraces, ParserState pstate = ParserState("[TOKEN]"), const char* source = nullptr);
|
69
61
|
// special static parsers to convert strings into certain selectors
|
70
|
-
static
|
62
|
+
static SelectorListObj parse_selector(SourceData* source, Context& ctx, Backtraces, bool allow_parent = true);
|
71
63
|
|
72
64
|
#ifdef __clang__
|
73
65
|
|
@@ -83,7 +75,7 @@ namespace Sass {
|
|
83
75
|
|
84
76
|
|
85
77
|
// skip current token and next whitespace
|
86
|
-
// moves
|
78
|
+
// moves SourceSpan right before next token
|
87
79
|
void advanceToNextToken();
|
88
80
|
|
89
81
|
bool peek_newline(const char* start = 0);
|
@@ -187,8 +179,8 @@ namespace Sass {
|
|
187
179
|
// update after_token position for current token
|
188
180
|
after_token.add(it_before_token, it_after_token);
|
189
181
|
|
190
|
-
// ToDo: could probably do this
|
191
|
-
pstate =
|
182
|
+
// ToDo: could probably do this incremental on original object (API wants offset?)
|
183
|
+
pstate = SourceSpan(source, before_token, after_token - before_token);
|
192
184
|
|
193
185
|
// advance internal char iterator
|
194
186
|
return position = it_after_token;
|
@@ -205,9 +197,9 @@ namespace Sass {
|
|
205
197
|
Token prev = lexed;
|
206
198
|
// store previous pointer
|
207
199
|
const char* oldpos = position;
|
208
|
-
|
209
|
-
|
210
|
-
|
200
|
+
Offset bt = before_token;
|
201
|
+
Offset at = after_token;
|
202
|
+
SourceSpan op = pstate;
|
211
203
|
// throw away comments
|
212
204
|
// update srcmap position
|
213
205
|
lex < Prelexer::css_comments >();
|
@@ -239,13 +231,12 @@ namespace Sass {
|
|
239
231
|
|
240
232
|
#endif
|
241
233
|
|
242
|
-
void error(
|
243
|
-
void error(std::string msg, Position pos);
|
234
|
+
void error(sass::string msg);
|
244
235
|
// generate message with given and expected sample
|
245
236
|
// text before and in the middle are configurable
|
246
|
-
void css_error(const
|
247
|
-
const
|
248
|
-
const
|
237
|
+
void css_error(const sass::string& msg,
|
238
|
+
const sass::string& prefix = " after ",
|
239
|
+
const sass::string& middle = ", was: ",
|
249
240
|
const bool trim = true);
|
250
241
|
void read_bom();
|
251
242
|
|
@@ -258,34 +249,34 @@ namespace Sass {
|
|
258
249
|
Arguments_Obj parse_arguments();
|
259
250
|
Argument_Obj parse_argument();
|
260
251
|
Assignment_Obj parse_assignment();
|
261
|
-
|
262
|
-
|
263
|
-
|
252
|
+
StyleRuleObj parse_ruleset(Lookahead lookahead);
|
253
|
+
SelectorListObj parseSelectorList(bool chroot);
|
254
|
+
ComplexSelectorObj parseComplexSelector(bool chroot);
|
264
255
|
Selector_Schema_Obj parse_selector_schema(const char* end_of_selector, bool chroot);
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
256
|
+
CompoundSelectorObj parseCompoundSelector();
|
257
|
+
SimpleSelectorObj parse_simple_selector();
|
258
|
+
PseudoSelectorObj parse_negated_selector2();
|
259
|
+
Expression* parse_binominal();
|
260
|
+
SimpleSelectorObj parse_pseudo_selector();
|
261
|
+
AttributeSelectorObj parse_attribute_selector();
|
270
262
|
Block_Obj parse_block(bool is_root = false);
|
271
263
|
Block_Obj parse_css_block(bool is_root = false);
|
272
264
|
bool parse_block_nodes(bool is_root = false);
|
273
265
|
bool parse_block_node(bool is_root = false);
|
274
266
|
|
275
|
-
bool parse_number_prefix();
|
276
267
|
Declaration_Obj parse_declaration();
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
268
|
+
ExpressionObj parse_map();
|
269
|
+
ExpressionObj parse_bracket_list();
|
270
|
+
ExpressionObj parse_list(bool delayed = false);
|
271
|
+
ExpressionObj parse_comma_list(bool delayed = false);
|
272
|
+
ExpressionObj parse_space_list();
|
273
|
+
ExpressionObj parse_disjunction();
|
274
|
+
ExpressionObj parse_conjunction();
|
275
|
+
ExpressionObj parse_relation();
|
276
|
+
ExpressionObj parse_expression();
|
277
|
+
ExpressionObj parse_operators();
|
278
|
+
ExpressionObj parse_factor();
|
279
|
+
ExpressionObj parse_value();
|
289
280
|
Function_Call_Obj parse_calc_function();
|
290
281
|
Function_Call_Obj parse_function_call();
|
291
282
|
Function_Call_Obj parse_function_call_schema();
|
@@ -293,81 +284,82 @@ namespace Sass {
|
|
293
284
|
String_Obj parse_url_function_argument();
|
294
285
|
String_Obj parse_interpolated_chunk(Token, bool constant = false, bool css = true);
|
295
286
|
String_Obj parse_string();
|
296
|
-
|
287
|
+
ValueObj parse_static_value();
|
297
288
|
String_Schema_Obj parse_css_variable_value();
|
298
289
|
String_Obj parse_ie_property();
|
299
290
|
String_Obj parse_ie_keyword_arg();
|
300
291
|
String_Schema_Obj parse_value_schema(const char* stop);
|
301
292
|
String_Obj parse_identifier_schema();
|
302
293
|
If_Obj parse_if_directive(bool else_if = false);
|
303
|
-
|
304
|
-
|
305
|
-
|
294
|
+
ForRuleObj parse_for_directive();
|
295
|
+
EachRuleObj parse_each_directive();
|
296
|
+
WhileRuleObj parse_while_directive();
|
297
|
+
MediaRule_Obj parseMediaRule();
|
298
|
+
sass::vector<CssMediaQuery_Obj> parseCssMediaQueries();
|
299
|
+
sass::string parseIdentifier();
|
300
|
+
CssMediaQuery_Obj parseCssMediaQuery();
|
306
301
|
Return_Obj parse_return_directive();
|
307
302
|
Content_Obj parse_content_directive();
|
308
303
|
void parse_charset_directive();
|
309
|
-
Media_Block_Obj parse_media_block();
|
310
304
|
List_Obj parse_media_queries();
|
311
305
|
Media_Query_Obj parse_media_query();
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
306
|
+
Media_Query_ExpressionObj parse_media_expression();
|
307
|
+
SupportsRuleObj parse_supports_directive();
|
308
|
+
SupportsConditionObj parse_supports_condition(bool top_level);
|
309
|
+
SupportsConditionObj parse_supports_negation();
|
310
|
+
SupportsConditionObj parse_supports_operator(bool top_level);
|
311
|
+
SupportsConditionObj parse_supports_interpolation();
|
312
|
+
SupportsConditionObj parse_supports_declaration();
|
313
|
+
SupportsConditionObj parse_supports_condition_in_parens(bool parens_required);
|
314
|
+
AtRootRuleObj parse_at_root_block();
|
321
315
|
At_Root_Query_Obj parse_at_root_query();
|
322
316
|
String_Schema_Obj parse_almost_any_value();
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
Error_Obj parse_error();
|
328
|
-
Debug_Obj parse_debug();
|
317
|
+
AtRuleObj parse_directive();
|
318
|
+
WarningRuleObj parse_warning();
|
319
|
+
ErrorRuleObj parse_error();
|
320
|
+
DebugRuleObj parse_debug();
|
329
321
|
|
330
|
-
Value* color_or_string(const
|
322
|
+
Value* color_or_string(const sass::string& lexed) const;
|
331
323
|
|
332
324
|
// be more like ruby sass
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
325
|
+
ExpressionObj lex_almost_any_value_token();
|
326
|
+
ExpressionObj lex_almost_any_value_chars();
|
327
|
+
ExpressionObj lex_interp_string();
|
328
|
+
ExpressionObj lex_interp_uri();
|
329
|
+
ExpressionObj lex_interpolation();
|
338
330
|
|
339
331
|
// these will throw errors
|
340
332
|
Token lex_variable();
|
341
333
|
Token lex_identifier();
|
342
334
|
|
343
|
-
void parse_block_comments();
|
335
|
+
void parse_block_comments(bool store = true);
|
344
336
|
|
345
337
|
Lookahead lookahead_for_value(const char* start = 0);
|
346
338
|
Lookahead lookahead_for_selector(const char* start = 0);
|
347
339
|
Lookahead lookahead_for_include(const char* start = 0);
|
348
340
|
|
349
|
-
|
350
|
-
|
341
|
+
ExpressionObj fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, Operand op);
|
342
|
+
ExpressionObj fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, sass::vector<Operand>& ops, size_t i = 0);
|
351
343
|
|
352
|
-
void throw_syntax_error(
|
353
|
-
void throw_read_error(
|
344
|
+
void throw_syntax_error(sass::string message, size_t ln = 0);
|
345
|
+
void throw_read_error(sass::string message, size_t ln = 0);
|
354
346
|
|
355
347
|
|
356
348
|
template <Prelexer::prelexer open, Prelexer::prelexer close>
|
357
|
-
|
349
|
+
ExpressionObj lex_interp()
|
358
350
|
{
|
359
351
|
if (lex < open >(false)) {
|
360
352
|
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
|
361
|
-
// std::cerr << "LEX [[" <<
|
353
|
+
// std::cerr << "LEX [[" << sass::string(lexed) << "]]\n";
|
362
354
|
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
|
363
355
|
if (position[0] == '#' && position[1] == '{') {
|
364
|
-
|
356
|
+
ExpressionObj itpl = lex_interpolation();
|
365
357
|
if (!itpl.isNull()) schema->append(itpl);
|
366
358
|
while (lex < close >(false)) {
|
367
|
-
// std::cerr << "LEX [[" <<
|
359
|
+
// std::cerr << "LEX [[" << sass::string(lexed) << "]]\n";
|
368
360
|
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
|
369
361
|
if (position[0] == '#' && position[1] == '{') {
|
370
|
-
|
362
|
+
ExpressionObj itpl = lex_interpolation();
|
371
363
|
if (!itpl.isNull()) schema->append(itpl);
|
372
364
|
} else {
|
373
365
|
return schema;
|
@@ -381,15 +373,15 @@ namespace Sass {
|
|
381
373
|
}
|
382
374
|
|
383
375
|
public:
|
384
|
-
static Number* lexed_number(const
|
385
|
-
static Number* lexed_dimension(const
|
386
|
-
static Number* lexed_percentage(const
|
387
|
-
static Value* lexed_hex_color(const
|
376
|
+
static Number* lexed_number(const SourceSpan& pstate, const sass::string& parsed);
|
377
|
+
static Number* lexed_dimension(const SourceSpan& pstate, const sass::string& parsed);
|
378
|
+
static Number* lexed_percentage(const SourceSpan& pstate, const sass::string& parsed);
|
379
|
+
static Value* lexed_hex_color(const SourceSpan& pstate, const sass::string& parsed);
|
388
380
|
private:
|
389
|
-
Number* lexed_number(const
|
390
|
-
Number* lexed_dimension(const
|
391
|
-
Number* lexed_percentage(const
|
392
|
-
Value* lexed_hex_color(const
|
381
|
+
Number* lexed_number(const sass::string& parsed) { return lexed_number(pstate, parsed); };
|
382
|
+
Number* lexed_dimension(const sass::string& parsed) { return lexed_dimension(pstate, parsed); };
|
383
|
+
Number* lexed_percentage(const sass::string& parsed) { return lexed_percentage(pstate, parsed); };
|
384
|
+
Value* lexed_hex_color(const sass::string& parsed) { return lexed_hex_color(pstate, parsed); };
|
393
385
|
|
394
386
|
static const char* re_attr_sensitive_close(const char* src);
|
395
387
|
static const char* re_attr_insensitive_close(const char* src);
|
@@ -0,0 +1,189 @@
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
3
|
+
#include "sass.hpp"
|
4
|
+
|
5
|
+
#include "parser.hpp"
|
6
|
+
|
7
|
+
namespace Sass {
|
8
|
+
|
9
|
+
using namespace Prelexer;
|
10
|
+
using namespace Constants;
|
11
|
+
|
12
|
+
ComplexSelectorObj Parser::parseComplexSelector(bool chroot)
|
13
|
+
{
|
14
|
+
|
15
|
+
NESTING_GUARD(nestings);
|
16
|
+
|
17
|
+
lex < block_comment >();
|
18
|
+
advanceToNextToken();
|
19
|
+
|
20
|
+
ComplexSelectorObj sel = SASS_MEMORY_NEW(ComplexSelector, pstate);
|
21
|
+
|
22
|
+
if (peek < end_of_file >()) return sel;
|
23
|
+
|
24
|
+
while (true) {
|
25
|
+
|
26
|
+
lex < block_comment >();
|
27
|
+
advanceToNextToken();
|
28
|
+
|
29
|
+
// check for child (+) combinator
|
30
|
+
if (lex < exactly < selector_combinator_child > >()) {
|
31
|
+
sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::CHILD, peek_newline()));
|
32
|
+
}
|
33
|
+
// check for general sibling (~) combinator
|
34
|
+
else if (lex < exactly < selector_combinator_general > >()) {
|
35
|
+
sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::GENERAL, peek_newline()));
|
36
|
+
}
|
37
|
+
// check for adjecant sibling (+) combinator
|
38
|
+
else if (lex < exactly < selector_combinator_adjacent > >()) {
|
39
|
+
sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::ADJACENT, peek_newline()));
|
40
|
+
}
|
41
|
+
// check if we can parse a compound selector
|
42
|
+
else if (CompoundSelectorObj compound = parseCompoundSelector()) {
|
43
|
+
sel->append(compound);
|
44
|
+
}
|
45
|
+
else {
|
46
|
+
break;
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
if (sel->empty()) return {};
|
51
|
+
|
52
|
+
// check if we parsed any parent references
|
53
|
+
sel->chroots(sel->has_real_parent_ref() || chroot);
|
54
|
+
|
55
|
+
sel->update_pstate(pstate);
|
56
|
+
|
57
|
+
return sel;
|
58
|
+
|
59
|
+
}
|
60
|
+
|
61
|
+
SelectorListObj Parser::parseSelectorList(bool chroot)
|
62
|
+
{
|
63
|
+
|
64
|
+
bool reloop;
|
65
|
+
bool had_linefeed = false;
|
66
|
+
NESTING_GUARD(nestings);
|
67
|
+
SelectorListObj list = SASS_MEMORY_NEW(SelectorList, pstate);
|
68
|
+
|
69
|
+
if (peek_css< alternatives < end_of_file, exactly <'{'>, exactly <','> > >()) {
|
70
|
+
css_error("Invalid CSS", " after ", ": expected selector, was ");
|
71
|
+
}
|
72
|
+
|
73
|
+
do {
|
74
|
+
reloop = false;
|
75
|
+
|
76
|
+
had_linefeed = had_linefeed || peek_newline();
|
77
|
+
|
78
|
+
if (peek_css< alternatives < class_char < selector_list_delims > > >())
|
79
|
+
break; // in case there are superfluous commas at the end
|
80
|
+
|
81
|
+
// now parse the complex selector
|
82
|
+
ComplexSelectorObj complex = parseComplexSelector(chroot);
|
83
|
+
if (complex.isNull()) return list.detach();
|
84
|
+
complex->hasPreLineFeed(had_linefeed);
|
85
|
+
|
86
|
+
had_linefeed = false;
|
87
|
+
|
88
|
+
while (peek_css< exactly<','> >())
|
89
|
+
{
|
90
|
+
lex< css_comments >(false);
|
91
|
+
// consume everything up and including the comma separator
|
92
|
+
reloop = lex< exactly<','> >() != 0;
|
93
|
+
// remember line break (also between some commas)
|
94
|
+
had_linefeed = had_linefeed || peek_newline();
|
95
|
+
// remember line break (also between some commas)
|
96
|
+
}
|
97
|
+
list->append(complex);
|
98
|
+
|
99
|
+
} while (reloop);
|
100
|
+
|
101
|
+
while (lex_css< kwd_optional >()) {
|
102
|
+
list->is_optional(true);
|
103
|
+
}
|
104
|
+
|
105
|
+
// update for end position
|
106
|
+
list->update_pstate(pstate);
|
107
|
+
|
108
|
+
return list.detach();
|
109
|
+
}
|
110
|
+
|
111
|
+
// parse one compound selector, which is basically
|
112
|
+
// a list of simple selectors (directly adjacent)
|
113
|
+
// lex them exactly (without skipping white-space)
|
114
|
+
CompoundSelectorObj Parser::parseCompoundSelector()
|
115
|
+
{
|
116
|
+
// init an empty compound selector wrapper
|
117
|
+
CompoundSelectorObj seq = SASS_MEMORY_NEW(CompoundSelector, pstate);
|
118
|
+
|
119
|
+
// skip initial white-space
|
120
|
+
lex < block_comment >();
|
121
|
+
advanceToNextToken();
|
122
|
+
|
123
|
+
if (lex< exactly<'&'> >(false))
|
124
|
+
{
|
125
|
+
// ToDo: check the conditions and try to simplify flag passing
|
126
|
+
if (!allow_parent) error("Parent selectors aren't allowed here.");
|
127
|
+
// Create and append a new parent selector object
|
128
|
+
seq->hasRealParent(true);
|
129
|
+
}
|
130
|
+
|
131
|
+
// parse list
|
132
|
+
while (true)
|
133
|
+
{
|
134
|
+
// remove all block comments
|
135
|
+
// leaves trailing white-space
|
136
|
+
lex < block_comment >();
|
137
|
+
// parse parent selector
|
138
|
+
if (lex< exactly<'&'> >(false))
|
139
|
+
{
|
140
|
+
// parent selector only allowed at start
|
141
|
+
// upcoming Sass may allow also trailing
|
142
|
+
SourceSpan state(pstate);
|
143
|
+
sass::string found("&");
|
144
|
+
if (lex < identifier >()) {
|
145
|
+
found += sass::string(lexed);
|
146
|
+
}
|
147
|
+
sass::string sel(seq->hasRealParent() ? "&" : "");
|
148
|
+
if (!seq->empty()) { sel = seq->last()->to_string({ NESTED, 5 }); }
|
149
|
+
// ToDo: parser should throw parser exceptions
|
150
|
+
error("Invalid CSS after \"" + sel + "\": expected \"{\", was \"" + found + "\"\n\n"
|
151
|
+
"\"" + found + "\" may only be used at the beginning of a compound selector.");
|
152
|
+
}
|
153
|
+
// parse functional
|
154
|
+
else if (match < re_functional >())
|
155
|
+
{
|
156
|
+
seq->append(parse_simple_selector());
|
157
|
+
}
|
158
|
+
|
159
|
+
// parse type selector
|
160
|
+
else if (lex< re_type_selector >(false))
|
161
|
+
{
|
162
|
+
seq->append(SASS_MEMORY_NEW(TypeSelector, pstate, lexed));
|
163
|
+
}
|
164
|
+
// peek for abort conditions
|
165
|
+
else if (peek< spaces >()) break;
|
166
|
+
else if (peek< end_of_file >()) { break; }
|
167
|
+
else if (peek_css < class_char < selector_combinator_ops > >()) break;
|
168
|
+
else if (peek_css < class_char < complex_selector_delims > >()) break;
|
169
|
+
// otherwise parse another simple selector
|
170
|
+
else {
|
171
|
+
SimpleSelectorObj sel = parse_simple_selector();
|
172
|
+
if (!sel) return {};
|
173
|
+
seq->append(sel);
|
174
|
+
}
|
175
|
+
}
|
176
|
+
// EO while true
|
177
|
+
|
178
|
+
if (seq && !peek_css<alternatives<end_of_file,exactly<'{'>>>()) {
|
179
|
+
seq->hasPostLineBreak(peek_newline());
|
180
|
+
}
|
181
|
+
|
182
|
+
// We may have set hasRealParent
|
183
|
+
if (seq && seq->empty() && !seq->hasRealParent()) return {};
|
184
|
+
|
185
|
+
return seq;
|
186
|
+
}
|
187
|
+
|
188
|
+
|
189
|
+
}
|
@@ -0,0 +1,164 @@
|
|
1
|
+
#ifndef SASS_PATHS_H
|
2
|
+
#define SASS_PATHS_H
|
3
|
+
|
4
|
+
#include <vector>
|
5
|
+
|
6
|
+
namespace Sass {
|
7
|
+
|
8
|
+
// Returns a list of all possible paths through the given lists.
|
9
|
+
//
|
10
|
+
// For example, given `[[1, 2], [3, 4], [5, 6]]`, this returns:
|
11
|
+
//
|
12
|
+
// ```
|
13
|
+
// [[1, 3, 5],
|
14
|
+
// [2, 3, 5],
|
15
|
+
// [1, 4, 5],
|
16
|
+
// [2, 4, 5],
|
17
|
+
// [1, 3, 6],
|
18
|
+
// [2, 3, 6],
|
19
|
+
// [1, 4, 6],
|
20
|
+
// [2, 4, 6]]
|
21
|
+
// ```
|
22
|
+
//
|
23
|
+
// Note: called `paths` in dart-sass
|
24
|
+
template <class T>
|
25
|
+
sass::vector<sass::vector<T>> permutate(
|
26
|
+
const sass::vector<sass::vector<T>>& in)
|
27
|
+
{
|
28
|
+
|
29
|
+
size_t L = in.size(), n = 0;
|
30
|
+
|
31
|
+
if (L == 0) return {};
|
32
|
+
// Exit early if any entry is empty
|
33
|
+
for (size_t i = 0; i < L; i += 1) {
|
34
|
+
if (in[i].size() == 0) return {};
|
35
|
+
}
|
36
|
+
|
37
|
+
size_t* state = new size_t[L + 1];
|
38
|
+
sass::vector<sass::vector<T>> out;
|
39
|
+
|
40
|
+
// First initialize all states for every permutation group
|
41
|
+
for (size_t i = 0; i < L; i += 1) {
|
42
|
+
state[i] = in[i].size() - 1;
|
43
|
+
}
|
44
|
+
while (true) {
|
45
|
+
sass::vector<T> perm;
|
46
|
+
// Create one permutation for state
|
47
|
+
for (size_t i = 0; i < L; i += 1) {
|
48
|
+
perm.push_back(in.at(i).at(in[i].size() - state[i] - 1));
|
49
|
+
}
|
50
|
+
// Current group finished
|
51
|
+
if (state[n] == 0) {
|
52
|
+
// Find position of next decrement
|
53
|
+
while (n < L && state[++n] == 0) {}
|
54
|
+
|
55
|
+
if (n == L) {
|
56
|
+
out.push_back(perm);
|
57
|
+
break;
|
58
|
+
}
|
59
|
+
|
60
|
+
state[n] -= 1;
|
61
|
+
|
62
|
+
for (size_t p = 0; p < n; p += 1) {
|
63
|
+
state[p] = in[p].size() - 1;
|
64
|
+
}
|
65
|
+
|
66
|
+
// Restart from front
|
67
|
+
n = 0;
|
68
|
+
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
state[n] -= 1;
|
72
|
+
}
|
73
|
+
out.push_back(perm);
|
74
|
+
}
|
75
|
+
|
76
|
+
delete[] state;
|
77
|
+
return out;
|
78
|
+
}
|
79
|
+
// EO permutate
|
80
|
+
|
81
|
+
// ToDo: this variant is used in resolveParentSelectors
|
82
|
+
// Returns a list of all possible paths through the given lists.
|
83
|
+
//
|
84
|
+
// For example, given `[[1, 2], [3, 4], [5, 6]]`, this returns:
|
85
|
+
//
|
86
|
+
// ```
|
87
|
+
// [[1, 3, 5],
|
88
|
+
// [1, 3, 6],
|
89
|
+
// [1, 4, 5],
|
90
|
+
// [1, 4, 6],
|
91
|
+
// [2, 3, 5],
|
92
|
+
// [2, 3, 6],
|
93
|
+
// [2, 4, 5],
|
94
|
+
// [2, 4, 6]]
|
95
|
+
// ```
|
96
|
+
//
|
97
|
+
template <class T>
|
98
|
+
sass::vector<sass::vector<T>>
|
99
|
+
permutateAlt(const sass::vector<sass::vector<T>>& in) {
|
100
|
+
|
101
|
+
size_t L = in.size();
|
102
|
+
size_t n = in.size() - 1;
|
103
|
+
|
104
|
+
if (L == 0) return {};
|
105
|
+
// Exit early if any entry is empty
|
106
|
+
for (size_t i = 0; i < L; i += 1) {
|
107
|
+
if (in[i].size() == 0) return {};
|
108
|
+
}
|
109
|
+
|
110
|
+
size_t* state = new size_t[L];
|
111
|
+
sass::vector<sass::vector<T>> out;
|
112
|
+
|
113
|
+
// First initialize all states for every permutation group
|
114
|
+
for (size_t i = 0; i < L; i += 1) {
|
115
|
+
state[i] = in[i].size() - 1;
|
116
|
+
}
|
117
|
+
|
118
|
+
while (true) {
|
119
|
+
/*
|
120
|
+
// std::cerr << "PERM: ";
|
121
|
+
for (size_t p = 0; p < L; p++)
|
122
|
+
{ // std::cerr << state[p] << " "; }
|
123
|
+
// std::cerr << "\n";
|
124
|
+
*/
|
125
|
+
sass::vector<T> perm;
|
126
|
+
// Create one permutation for state
|
127
|
+
for (size_t i = 0; i < L; i += 1) {
|
128
|
+
perm.push_back(in.at(i).at(in[i].size() - state[i] - 1));
|
129
|
+
}
|
130
|
+
// Current group finished
|
131
|
+
if (state[n] == 0) {
|
132
|
+
// Find position of next decrement
|
133
|
+
while (n > 0 && state[--n] == 0) {}
|
134
|
+
|
135
|
+
// Check for end condition
|
136
|
+
if (state[n] != 0) {
|
137
|
+
// Decrease next on the left side
|
138
|
+
state[n] -= 1;
|
139
|
+
// Reset all counters to the right
|
140
|
+
for (size_t p = n + 1; p < L; p += 1) {
|
141
|
+
state[p] = in[p].size() - 1;
|
142
|
+
}
|
143
|
+
// Restart from end
|
144
|
+
n = L - 1;
|
145
|
+
}
|
146
|
+
else {
|
147
|
+
out.push_back(perm);
|
148
|
+
break;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
state[n] -= 1;
|
153
|
+
}
|
154
|
+
out.push_back(perm);
|
155
|
+
}
|
156
|
+
|
157
|
+
delete[] state;
|
158
|
+
return out;
|
159
|
+
}
|
160
|
+
// EO permutateAlt
|
161
|
+
|
162
|
+
}
|
163
|
+
|
164
|
+
#endif
|