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.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/CHANGELOG.md +18 -0
  4. data/Rakefile +1 -3
  5. data/ext/extconf.rb +13 -5
  6. data/ext/libsass/VERSION +1 -1
  7. data/ext/libsass/include/sass/base.h +2 -1
  8. data/ext/libsass/include/sass/context.h +4 -0
  9. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  10. data/ext/libsass/src/ast.cpp +158 -168
  11. data/ext/libsass/src/ast.hpp +389 -230
  12. data/ext/libsass/src/ast_def_macros.hpp +18 -10
  13. data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
  14. data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
  15. data/ext/libsass/src/ast_helpers.hpp +292 -0
  16. data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
  17. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  18. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  19. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  20. data/ext/libsass/src/ast_selectors.cpp +594 -1026
  21. data/ext/libsass/src/ast_selectors.hpp +339 -385
  22. data/ext/libsass/src/ast_supports.cpp +36 -52
  23. data/ext/libsass/src/ast_supports.hpp +29 -29
  24. data/ext/libsass/src/ast_values.cpp +271 -84
  25. data/ext/libsass/src/ast_values.hpp +116 -107
  26. data/ext/libsass/src/backtrace.cpp +9 -9
  27. data/ext/libsass/src/backtrace.hpp +5 -5
  28. data/ext/libsass/src/base64vlq.cpp +2 -2
  29. data/ext/libsass/src/base64vlq.hpp +1 -1
  30. data/ext/libsass/src/bind.cpp +18 -18
  31. data/ext/libsass/src/bind.hpp +1 -1
  32. data/ext/libsass/src/c2ast.cpp +3 -3
  33. data/ext/libsass/src/c2ast.hpp +1 -1
  34. data/ext/libsass/src/cencode.c +4 -6
  35. data/ext/libsass/src/check_nesting.cpp +40 -41
  36. data/ext/libsass/src/check_nesting.hpp +6 -2
  37. data/ext/libsass/src/color_maps.cpp +14 -13
  38. data/ext/libsass/src/color_maps.hpp +1 -9
  39. data/ext/libsass/src/constants.cpp +5 -0
  40. data/ext/libsass/src/constants.hpp +6 -0
  41. data/ext/libsass/src/context.cpp +92 -119
  42. data/ext/libsass/src/context.hpp +41 -53
  43. data/ext/libsass/src/cssize.cpp +66 -149
  44. data/ext/libsass/src/cssize.hpp +17 -23
  45. data/ext/libsass/src/dart_helpers.hpp +199 -0
  46. data/ext/libsass/src/debugger.hpp +451 -295
  47. data/ext/libsass/src/emitter.cpp +15 -16
  48. data/ext/libsass/src/emitter.hpp +10 -12
  49. data/ext/libsass/src/environment.cpp +27 -27
  50. data/ext/libsass/src/environment.hpp +29 -24
  51. data/ext/libsass/src/error_handling.cpp +62 -41
  52. data/ext/libsass/src/error_handling.hpp +61 -51
  53. data/ext/libsass/src/eval.cpp +167 -281
  54. data/ext/libsass/src/eval.hpp +27 -29
  55. data/ext/libsass/src/eval_selectors.cpp +75 -0
  56. data/ext/libsass/src/expand.cpp +275 -222
  57. data/ext/libsass/src/expand.hpp +36 -16
  58. data/ext/libsass/src/extender.cpp +1188 -0
  59. data/ext/libsass/src/extender.hpp +399 -0
  60. data/ext/libsass/src/extension.cpp +43 -0
  61. data/ext/libsass/src/extension.hpp +89 -0
  62. data/ext/libsass/src/file.cpp +81 -72
  63. data/ext/libsass/src/file.hpp +28 -37
  64. data/ext/libsass/src/fn_colors.cpp +20 -18
  65. data/ext/libsass/src/fn_lists.cpp +30 -29
  66. data/ext/libsass/src/fn_maps.cpp +3 -3
  67. data/ext/libsass/src/fn_miscs.cpp +34 -46
  68. data/ext/libsass/src/fn_numbers.cpp +20 -13
  69. data/ext/libsass/src/fn_selectors.cpp +98 -128
  70. data/ext/libsass/src/fn_strings.cpp +47 -33
  71. data/ext/libsass/src/fn_utils.cpp +31 -29
  72. data/ext/libsass/src/fn_utils.hpp +17 -11
  73. data/ext/libsass/src/inspect.cpp +186 -148
  74. data/ext/libsass/src/inspect.hpp +31 -29
  75. data/ext/libsass/src/lexer.cpp +20 -82
  76. data/ext/libsass/src/lexer.hpp +5 -16
  77. data/ext/libsass/src/listize.cpp +23 -37
  78. data/ext/libsass/src/listize.hpp +8 -9
  79. data/ext/libsass/src/mapping.hpp +1 -0
  80. data/ext/libsass/src/memory/allocator.cpp +48 -0
  81. data/ext/libsass/src/memory/allocator.hpp +138 -0
  82. data/ext/libsass/src/memory/config.hpp +20 -0
  83. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  84. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  85. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  86. data/ext/libsass/src/memory.hpp +12 -0
  87. data/ext/libsass/src/operation.hpp +71 -61
  88. data/ext/libsass/src/operators.cpp +19 -18
  89. data/ext/libsass/src/operators.hpp +11 -11
  90. data/ext/libsass/src/ordered_map.hpp +112 -0
  91. data/ext/libsass/src/output.cpp +45 -64
  92. data/ext/libsass/src/output.hpp +6 -6
  93. data/ext/libsass/src/parser.cpp +512 -700
  94. data/ext/libsass/src/parser.hpp +89 -97
  95. data/ext/libsass/src/parser_selectors.cpp +189 -0
  96. data/ext/libsass/src/permutate.hpp +164 -0
  97. data/ext/libsass/src/plugins.cpp +7 -7
  98. data/ext/libsass/src/plugins.hpp +8 -8
  99. data/ext/libsass/src/position.cpp +7 -26
  100. data/ext/libsass/src/position.hpp +44 -21
  101. data/ext/libsass/src/prelexer.cpp +6 -6
  102. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  103. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  104. data/ext/libsass/src/sass.cpp +16 -15
  105. data/ext/libsass/src/sass.hpp +10 -5
  106. data/ext/libsass/src/sass2scss.cpp +4 -4
  107. data/ext/libsass/src/sass_context.cpp +91 -122
  108. data/ext/libsass/src/sass_context.hpp +2 -2
  109. data/ext/libsass/src/sass_functions.cpp +1 -1
  110. data/ext/libsass/src/sass_values.cpp +8 -11
  111. data/ext/libsass/src/settings.hpp +19 -0
  112. data/ext/libsass/src/source.cpp +69 -0
  113. data/ext/libsass/src/source.hpp +95 -0
  114. data/ext/libsass/src/source_data.hpp +32 -0
  115. data/ext/libsass/src/source_map.cpp +22 -18
  116. data/ext/libsass/src/source_map.hpp +12 -9
  117. data/ext/libsass/src/stylesheet.cpp +22 -0
  118. data/ext/libsass/src/stylesheet.hpp +57 -0
  119. data/ext/libsass/src/to_value.cpp +2 -2
  120. data/ext/libsass/src/to_value.hpp +1 -1
  121. data/ext/libsass/src/units.cpp +24 -22
  122. data/ext/libsass/src/units.hpp +8 -8
  123. data/ext/libsass/src/utf8_string.cpp +9 -10
  124. data/ext/libsass/src/utf8_string.hpp +7 -6
  125. data/ext/libsass/src/util.cpp +48 -50
  126. data/ext/libsass/src/util.hpp +20 -21
  127. data/ext/libsass/src/util_string.cpp +111 -61
  128. data/ext/libsass/src/util_string.hpp +62 -8
  129. data/ext/libsass/src/values.cpp +12 -12
  130. data/lib/sassc/engine.rb +5 -3
  131. data/lib/sassc/functions_handler.rb +8 -8
  132. data/lib/sassc/native.rb +4 -6
  133. data/lib/sassc/script.rb +4 -4
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +18 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +29 -15
  138. data/ext/libsass/src/extend.cpp +0 -2132
  139. data/ext/libsass/src/extend.hpp +0 -86
  140. data/ext/libsass/src/node.cpp +0 -322
  141. data/ext/libsass/src/node.hpp +0 -118
  142. data/ext/libsass/src/paths.hpp +0 -71
  143. data/ext/libsass/src/sass_util.cpp +0 -152
  144. data/ext/libsass/src/sass_util.hpp +0 -256
  145. data/ext/libsass/src/subset_map.cpp +0 -58
  146. data/ext/libsass/src/subset_map.hpp +0 -76
  147. data/lib/sassc/native/lib_c.rb +0 -21
@@ -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 ParserState {
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
- std::vector<Block_Obj> block_stack;
42
- std::vector<Scope> stack;
43
- Media_Block* last_media_block;
44
- const char* source;
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
- Position before_token;
48
- Position after_token;
49
- ParserState pstate;
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(Context& ctx, const ParserState& pstate, Backtraces traces, bool allow_parent = true)
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 Selector_List_Obj parse_selector(const char* src, Context& ctx, Backtraces, ParserState pstate = ParserState("[SELECTOR]"), const char* source = nullptr, bool allow_parent = true);
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 ParserState right before next token
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 incremetal on original object (API wants offset?)
191
- pstate = ParserState(path, source, lexed, before_token, after_token - before_token);
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
- Position bt = before_token;
209
- Position at = after_token;
210
- ParserState op = pstate;
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(std::string msg);
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 std::string& msg,
247
- const std::string& prefix = " after ",
248
- const std::string& middle = ", was: ",
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
- Ruleset_Obj parse_ruleset(Lookahead lookahead);
262
- Selector_List_Obj parse_selector_list(bool chroot);
263
- Complex_Selector_Obj parse_complex_selector(bool chroot);
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
- Compound_Selector_Obj parse_compound_selector();
266
- Simple_Selector_Obj parse_simple_selector();
267
- Wrapped_Selector_Obj parse_negated_selector();
268
- Simple_Selector_Obj parse_pseudo_selector();
269
- Attribute_Selector_Obj parse_attribute_selector();
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
- Expression_Obj parse_map();
278
- Expression_Obj parse_bracket_list();
279
- Expression_Obj parse_list(bool delayed = false);
280
- Expression_Obj parse_comma_list(bool delayed = false);
281
- Expression_Obj parse_space_list();
282
- Expression_Obj parse_disjunction();
283
- Expression_Obj parse_conjunction();
284
- Expression_Obj parse_relation();
285
- Expression_Obj parse_expression();
286
- Expression_Obj parse_operators();
287
- Expression_Obj parse_factor();
288
- Expression_Obj parse_value();
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
- Value_Obj parse_static_value();
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
- For_Obj parse_for_directive();
304
- Each_Obj parse_each_directive();
305
- While_Obj parse_while_directive();
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
- Media_Query_Expression_Obj parse_media_expression();
313
- Supports_Block_Obj parse_supports_directive();
314
- Supports_Condition_Obj parse_supports_condition(bool top_level);
315
- Supports_Condition_Obj parse_supports_negation();
316
- Supports_Condition_Obj parse_supports_operator(bool top_level);
317
- Supports_Condition_Obj parse_supports_interpolation();
318
- Supports_Condition_Obj parse_supports_declaration();
319
- Supports_Condition_Obj parse_supports_condition_in_parens(bool parens_required);
320
- At_Root_Block_Obj parse_at_root_block();
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
- Directive_Obj parse_special_directive();
324
- Directive_Obj parse_prefixed_directive();
325
- Directive_Obj parse_directive();
326
- Warning_Obj parse_warning();
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 std::string& lexed) const;
322
+ Value* color_or_string(const sass::string& lexed) const;
331
323
 
332
324
  // be more like ruby sass
333
- Expression_Obj lex_almost_any_value_token();
334
- Expression_Obj lex_almost_any_value_chars();
335
- Expression_Obj lex_interp_string();
336
- Expression_Obj lex_interp_uri();
337
- Expression_Obj lex_interpolation();
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
- Expression_Obj fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, Operand op);
350
- Expression_Obj fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, std::vector<Operand>& ops, size_t i = 0);
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(std::string message, size_t ln = 0);
353
- void throw_read_error(std::string message, size_t ln = 0);
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
- Expression_Obj lex_interp()
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 [[" << std::string(lexed) << "]]\n";
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
- Expression_Obj itpl = lex_interpolation();
356
+ ExpressionObj itpl = lex_interpolation();
365
357
  if (!itpl.isNull()) schema->append(itpl);
366
358
  while (lex < close >(false)) {
367
- // std::cerr << "LEX [[" << std::string(lexed) << "]]\n";
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
- Expression_Obj itpl = lex_interpolation();
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 ParserState& pstate, const std::string& parsed);
385
- static Number* lexed_dimension(const ParserState& pstate, const std::string& parsed);
386
- static Number* lexed_percentage(const ParserState& pstate, const std::string& parsed);
387
- static Value* lexed_hex_color(const ParserState& pstate, const std::string& parsed);
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 std::string& parsed) { return lexed_number(pstate, parsed); };
390
- Number* lexed_dimension(const std::string& parsed) { return lexed_dimension(pstate, parsed); };
391
- Number* lexed_percentage(const std::string& parsed) { return lexed_percentage(pstate, parsed); };
392
- Value* lexed_hex_color(const std::string& parsed) { return lexed_hex_color(pstate, parsed); };
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