sassc 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +13 -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 +1 -0
  9. data/ext/libsass/src/ast.cpp +49 -59
  10. data/ext/libsass/src/ast.hpp +263 -102
  11. data/ext/libsass/src/ast_def_macros.hpp +8 -0
  12. data/ext/libsass/src/ast_fwd_decl.cpp +2 -1
  13. data/ext/libsass/src/ast_fwd_decl.hpp +40 -116
  14. data/ext/libsass/src/ast_helpers.hpp +292 -0
  15. data/ext/libsass/src/ast_sel_cmp.cpp +209 -722
  16. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  17. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  18. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  19. data/ext/libsass/src/ast_selectors.cpp +559 -1001
  20. data/ext/libsass/src/ast_selectors.hpp +311 -367
  21. data/ext/libsass/src/ast_supports.cpp +1 -17
  22. data/ext/libsass/src/ast_values.cpp +216 -29
  23. data/ext/libsass/src/ast_values.hpp +42 -33
  24. data/ext/libsass/src/bind.cpp +1 -1
  25. data/ext/libsass/src/cencode.c +4 -6
  26. data/ext/libsass/src/check_nesting.cpp +5 -6
  27. data/ext/libsass/src/check_nesting.hpp +4 -0
  28. data/ext/libsass/src/color_maps.cpp +11 -10
  29. data/ext/libsass/src/color_maps.hpp +0 -8
  30. data/ext/libsass/src/constants.cpp +5 -0
  31. data/ext/libsass/src/constants.hpp +6 -0
  32. data/ext/libsass/src/context.cpp +30 -60
  33. data/ext/libsass/src/context.hpp +8 -20
  34. data/ext/libsass/src/cssize.cpp +36 -120
  35. data/ext/libsass/src/cssize.hpp +4 -10
  36. data/ext/libsass/src/dart_helpers.hpp +199 -0
  37. data/ext/libsass/src/debugger.hpp +364 -207
  38. data/ext/libsass/src/emitter.cpp +3 -4
  39. data/ext/libsass/src/emitter.hpp +0 -2
  40. data/ext/libsass/src/environment.hpp +5 -0
  41. data/ext/libsass/src/error_handling.cpp +21 -0
  42. data/ext/libsass/src/error_handling.hpp +25 -3
  43. data/ext/libsass/src/eval.cpp +33 -153
  44. data/ext/libsass/src/eval.hpp +11 -13
  45. data/ext/libsass/src/eval_selectors.cpp +75 -0
  46. data/ext/libsass/src/expand.cpp +214 -167
  47. data/ext/libsass/src/expand.hpp +26 -6
  48. data/ext/libsass/src/extender.cpp +1186 -0
  49. data/ext/libsass/src/extender.hpp +399 -0
  50. data/ext/libsass/src/extension.cpp +43 -0
  51. data/ext/libsass/src/extension.hpp +89 -0
  52. data/ext/libsass/src/file.cpp +15 -14
  53. data/ext/libsass/src/file.hpp +5 -12
  54. data/ext/libsass/src/fn_colors.cpp +12 -10
  55. data/ext/libsass/src/fn_lists.cpp +12 -11
  56. data/ext/libsass/src/fn_miscs.cpp +22 -34
  57. data/ext/libsass/src/fn_numbers.cpp +13 -6
  58. data/ext/libsass/src/fn_selectors.cpp +94 -124
  59. data/ext/libsass/src/fn_strings.cpp +16 -14
  60. data/ext/libsass/src/fn_utils.cpp +5 -6
  61. data/ext/libsass/src/fn_utils.hpp +9 -3
  62. data/ext/libsass/src/inspect.cpp +154 -117
  63. data/ext/libsass/src/inspect.hpp +10 -8
  64. data/ext/libsass/src/lexer.cpp +17 -81
  65. data/ext/libsass/src/lexer.hpp +5 -16
  66. data/ext/libsass/src/listize.cpp +22 -36
  67. data/ext/libsass/src/listize.hpp +8 -9
  68. data/ext/libsass/src/memory/SharedPtr.hpp +39 -5
  69. data/ext/libsass/src/operation.hpp +27 -17
  70. data/ext/libsass/src/operators.cpp +1 -0
  71. data/ext/libsass/src/ordered_map.hpp +112 -0
  72. data/ext/libsass/src/output.cpp +30 -49
  73. data/ext/libsass/src/output.hpp +1 -1
  74. data/ext/libsass/src/parser.cpp +211 -381
  75. data/ext/libsass/src/parser.hpp +17 -15
  76. data/ext/libsass/src/parser_selectors.cpp +189 -0
  77. data/ext/libsass/src/permutate.hpp +140 -0
  78. data/ext/libsass/src/position.hpp +1 -1
  79. data/ext/libsass/src/prelexer.cpp +6 -6
  80. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  81. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  82. data/ext/libsass/src/sass.hpp +1 -0
  83. data/ext/libsass/src/sass2scss.cpp +4 -4
  84. data/ext/libsass/src/sass_context.cpp +42 -91
  85. data/ext/libsass/src/sass_context.hpp +2 -2
  86. data/ext/libsass/src/sass_functions.cpp +1 -1
  87. data/ext/libsass/src/sass_values.cpp +0 -1
  88. data/ext/libsass/src/stylesheet.cpp +22 -0
  89. data/ext/libsass/src/stylesheet.hpp +57 -0
  90. data/ext/libsass/src/to_value.cpp +2 -2
  91. data/ext/libsass/src/to_value.hpp +1 -1
  92. data/ext/libsass/src/units.cpp +5 -3
  93. data/ext/libsass/src/util.cpp +10 -12
  94. data/ext/libsass/src/util.hpp +2 -3
  95. data/ext/libsass/src/util_string.cpp +111 -61
  96. data/ext/libsass/src/util_string.hpp +61 -8
  97. data/lib/sassc/engine.rb +5 -3
  98. data/lib/sassc/functions_handler.rb +8 -8
  99. data/lib/sassc/native.rb +1 -1
  100. data/lib/sassc/script.rb +4 -4
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/functions_test.rb +18 -1
  103. data/test/native_test.rb +1 -1
  104. metadata +17 -12
  105. data/ext/libsass/src/extend.cpp +0 -2132
  106. data/ext/libsass/src/extend.hpp +0 -86
  107. data/ext/libsass/src/node.cpp +0 -322
  108. data/ext/libsass/src/node.hpp +0 -118
  109. data/ext/libsass/src/paths.hpp +0 -71
  110. data/ext/libsass/src/sass_util.cpp +0 -152
  111. data/ext/libsass/src/sass_util.hpp +0 -256
  112. data/ext/libsass/src/subset_map.cpp +0 -58
  113. data/ext/libsass/src/subset_map.hpp +0 -76
@@ -2,11 +2,11 @@
2
2
  // __EXTENSIONS__ fix on Solaris.
3
3
  #include "sass.hpp"
4
4
 
5
- #include <cctype>
6
5
  #include "utf8.h"
7
6
  #include "ast.hpp"
8
7
  #include "fn_utils.hpp"
9
8
  #include "fn_strings.hpp"
9
+ #include "util_string.hpp"
10
10
 
11
11
  namespace Sass {
12
12
 
@@ -99,6 +99,9 @@ namespace Sass {
99
99
  String_Constant* i = ARG("$insert", String_Constant);
100
100
  std::string ins = i->value();
101
101
  double index = ARGVAL("$index");
102
+ if (index != (int)index) {
103
+ error("$index: " + std::to_string(index) + " is not an int", pstate, traces);
104
+ }
102
105
  size_t len = UTF_8::code_point_count(str, 0, str.size());
103
106
 
104
107
  if (index > 0 && index <= len) {
@@ -163,6 +166,11 @@ namespace Sass {
163
166
  String_Constant* s = ARG("$string", String_Constant);
164
167
  double start_at = ARGVAL("$start-at");
165
168
  double end_at = ARGVAL("$end-at");
169
+
170
+ if (start_at != (int)start_at) {
171
+ error("$start-at: " + std::to_string(start_at) + " is not an int", pstate, traces);
172
+ }
173
+
166
174
  String_Quoted* ss = Cast<String_Quoted>(s);
167
175
 
168
176
  std::string str(s->value());
@@ -173,6 +181,10 @@ namespace Sass {
173
181
  end_at = -1;
174
182
  }
175
183
 
184
+ if (end_at != (int)end_at) {
185
+ error("$end-at: " + std::to_string(end_at) + " is not an int", pstate, traces);
186
+ }
187
+
176
188
  if (end_at == 0 || (end_at + size) < 0) {
177
189
  if (ss && ss->quote_mark()) newstr = quote("");
178
190
  return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);
@@ -185,7 +197,7 @@ namespace Sass {
185
197
  if (end_at > size) { end_at = (double)size; }
186
198
  if (start_at < 0) {
187
199
  start_at += size + 1;
188
- if (start_at < 0) start_at = 0;
200
+ if (start_at <= 0) start_at = 1;
189
201
  }
190
202
  else if (start_at == 0) { ++ start_at; }
191
203
 
@@ -212,12 +224,7 @@ namespace Sass {
212
224
  {
213
225
  String_Constant* s = ARG("$string", String_Constant);
214
226
  std::string str = s->value();
215
-
216
- for (size_t i = 0, L = str.length(); i < L; ++i) {
217
- if (Sass::Util::isAscii(str[i])) {
218
- str[i] = std::toupper(str[i]);
219
- }
220
- }
227
+ Util::ascii_str_toupper(&str);
221
228
 
222
229
  if (String_Quoted* ss = Cast<String_Quoted>(s)) {
223
230
  String_Quoted* cpy = SASS_MEMORY_COPY(ss);
@@ -233,12 +240,7 @@ namespace Sass {
233
240
  {
234
241
  String_Constant* s = ARG("$string", String_Constant);
235
242
  std::string str = s->value();
236
-
237
- for (size_t i = 0, L = str.length(); i < L; ++i) {
238
- if (Sass::Util::isAscii(str[i])) {
239
- str[i] = std::tolower(str[i]);
240
- }
241
- }
243
+ Util::ascii_str_tolower(&str);
242
244
 
243
245
  if (String_Quoted* ss = Cast<String_Quoted>(s)) {
244
246
  String_Quoted* cpy = SASS_MEMORY_COPY(ss);
@@ -118,7 +118,7 @@ namespace Sass {
118
118
  }
119
119
  }
120
120
 
121
- Selector_List_Obj get_arg_sels(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx) {
121
+ SelectorListObj get_arg_sels(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx) {
122
122
  Expression_Obj exp = ARG(argname, Expression);
123
123
  if (exp->concrete_type() == Expression::NULL_VAL) {
124
124
  std::stringstream msg;
@@ -133,7 +133,7 @@ namespace Sass {
133
133
  return Parser::parse_selector(exp_src.c_str(), ctx, traces, exp->pstate(), pstate.src, /*allow_parent=*/false);
134
134
  }
135
135
 
136
- Compound_Selector_Obj get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx) {
136
+ CompoundSelectorObj get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx) {
137
137
  Expression_Obj exp = ARG(argname, Expression);
138
138
  if (exp->concrete_type() == Expression::NULL_VAL) {
139
139
  std::stringstream msg;
@@ -144,13 +144,12 @@ namespace Sass {
144
144
  str->quote_mark(0);
145
145
  }
146
146
  std::string exp_src = exp->to_string(ctx.c_options);
147
- Selector_List_Obj sel_list = Parser::parse_selector(exp_src.c_str(), ctx, traces, exp->pstate(), pstate.src, /*allow_parent=*/false);
147
+ SelectorListObj sel_list = Parser::parse_selector(exp_src.c_str(), ctx, traces, exp->pstate(), pstate.src, /*allow_parent=*/false);
148
148
  if (sel_list->length() == 0) return {};
149
- Complex_Selector_Obj first = sel_list->first();
150
- if (!first->tail()) return first->head();
151
- return first->tail()->head();
149
+ return sel_list->first()->first();
152
150
  }
153
151
 
152
+
154
153
  }
155
154
 
156
155
  }
@@ -1,5 +1,10 @@
1
1
  #ifndef SASS_FN_UTILS_H
2
2
  #define SASS_FN_UTILS_H
3
+
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
7
+
3
8
  #include "units.hpp"
4
9
  #include "backtrace.hpp"
5
10
  #include "environment.hpp"
@@ -15,7 +20,8 @@ namespace Sass {
15
20
  Signature sig, \
16
21
  ParserState pstate, \
17
22
  Backtraces& traces, \
18
- SelectorStack& selector_stack
23
+ SelectorStack selector_stack, \
24
+ SelectorStack original_stack \
19
25
 
20
26
  typedef const char* Signature;
21
27
  typedef PreValue* (*Native_Function)(FN_PROTOTYPE);
@@ -46,8 +52,8 @@ namespace Sass {
46
52
  double color_num(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces); // colors only
47
53
  double get_arg_r(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, double lo, double hi); // colors only
48
54
  double get_arg_val(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces); // shared
49
- Selector_List_Obj get_arg_sels(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx); // selectors only
50
- Compound_Selector_Obj get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx); // selectors only
55
+ SelectorListObj get_arg_sels(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx); // selectors only
56
+ CompoundSelectorObj get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx); // selectors only
51
57
 
52
58
  }
53
59
 
@@ -67,15 +67,61 @@ namespace Sass {
67
67
  append_scope_closer();
68
68
  }
69
69
 
70
- void Inspect::operator()(Media_Block* media_block)
70
+ void Inspect::operator()(MediaRule* rule)
71
71
  {
72
72
  append_indentation();
73
- append_token("@media", media_block);
73
+ append_token("@media", rule);
74
+ append_mandatory_space();
75
+ if (rule->block()) {
76
+ rule->block()->perform(this);
77
+ }
78
+ }
79
+
80
+ void Inspect::operator()(CssMediaRule* rule)
81
+ {
82
+ if (output_style() == NESTED)
83
+ indentation += rule->tabs();
84
+ append_indentation();
85
+ append_token("@media", rule);
74
86
  append_mandatory_space();
75
87
  in_media_block = true;
76
- media_block->media_queries()->perform(this);
88
+ bool joinIt = false;
89
+ for (auto query : rule->elements()) {
90
+ if (joinIt) {
91
+ append_comma_separator();
92
+ append_optional_space();
93
+ }
94
+ operator()(query);
95
+ joinIt = true;
96
+ }
97
+ if (rule->block()) {
98
+ rule->block()->perform(this);
99
+ }
77
100
  in_media_block = false;
78
- media_block->block()->perform(this);
101
+ if (output_style() == NESTED)
102
+ indentation -= rule->tabs();
103
+ }
104
+
105
+ void Inspect::operator()(CssMediaQuery* query)
106
+ {
107
+ bool joinIt = false;
108
+ if (!query->modifier().empty()) {
109
+ append_string(query->modifier());
110
+ append_mandatory_space();
111
+ }
112
+ if (!query->type().empty()) {
113
+ append_string(query->type());
114
+ joinIt = true;
115
+ }
116
+ for (auto feature : query->features()) {
117
+ if (joinIt) {
118
+ append_mandatory_space();
119
+ append_string("and");
120
+ append_mandatory_space();
121
+ }
122
+ append_string(feature);
123
+ joinIt = true;
124
+ }
79
125
  }
80
126
 
81
127
  void Inspect::operator()(Supports_Block* feature_block)
@@ -134,8 +180,7 @@ namespace Sass {
134
180
  append_colon_separator();
135
181
 
136
182
  if (dec->value()->concrete_type() == Expression::SELECTOR) {
137
- Listize listize;
138
- Expression_Obj ls = dec->value()->perform(&listize);
183
+ Expression_Obj ls = Listize::perform(dec->value());
139
184
  ls->perform(this);
140
185
  } else {
141
186
  dec->value()->perform(this);
@@ -298,7 +343,7 @@ namespace Sass {
298
343
  append_delimiter();
299
344
  }
300
345
 
301
- void Inspect::operator()(Extension* extend)
346
+ void Inspect::operator()(ExtendRule* extend)
302
347
  {
303
348
  append_indentation();
304
349
  append_token("@extend", extend);
@@ -399,7 +444,7 @@ namespace Sass {
399
444
  list->length() == 1 &&
400
445
  !list->from_selector() &&
401
446
  !Cast<List>(list->at(0)) &&
402
- !Cast<Selector_List>(list->at(0))
447
+ !Cast<SelectorList>(list->at(0))
403
448
  ) {
404
449
  append_string(lbracket(list));
405
450
  }
@@ -449,7 +494,7 @@ namespace Sass {
449
494
  list->length() == 1 &&
450
495
  !list->from_selector() &&
451
496
  !Cast<List>(list->at(0)) &&
452
- !Cast<Selector_List>(list->at(0))
497
+ !Cast<SelectorList>(list->at(0))
453
498
  ) {
454
499
  append_string(",");
455
500
  append_string(rbracket(list));
@@ -530,7 +575,7 @@ namespace Sass {
530
575
  ss << std::fixed << n->value();
531
576
 
532
577
  std::string res = ss.str();
533
- int s = res.length();
578
+ size_t s = res.length();
534
579
 
535
580
  // delete trailing zeros
536
581
  for(s = s - 1; s > 0; --s)
@@ -562,6 +607,11 @@ namespace Sass {
562
607
  // add unit now
563
608
  res += n->unit();
564
609
 
610
+ if (opt.output_style == TO_CSS && !n->is_valid_css_unit()) {
611
+ // traces.push_back(Backtrace(nr->pstate()));
612
+ throw Exception::InvalidValue({}, *n);
613
+ }
614
+
565
615
  // output the final token
566
616
  append_token(res, n);
567
617
  }
@@ -879,16 +929,14 @@ namespace Sass {
879
929
  s->contents()->perform(this);
880
930
  }
881
931
 
882
- void Inspect::operator()(Parent_Selector* p)
932
+ void Inspect::operator()(Parent_Reference* p)
883
933
  {
884
- if (p->real()) append_string("&");
934
+ append_string("&");
885
935
  }
886
936
 
887
937
  void Inspect::operator()(Placeholder_Selector* s)
888
938
  {
889
939
  append_token(s->name(), s);
890
- if (s->has_line_break()) append_optional_linefeed();
891
- if (s->has_line_break()) append_indentation();
892
940
 
893
941
  }
894
942
 
@@ -900,15 +948,11 @@ namespace Sass {
900
948
  void Inspect::operator()(Class_Selector* s)
901
949
  {
902
950
  append_token(s->ns_name(), s);
903
- if (s->has_line_break()) append_optional_linefeed();
904
- if (s->has_line_break()) append_indentation();
905
951
  }
906
952
 
907
953
  void Inspect::operator()(Id_Selector* s)
908
954
  {
909
955
  append_token(s->ns_name(), s);
910
- if (s->has_line_break()) append_optional_linefeed();
911
- if (s->has_line_break()) append_indentation();
912
956
  }
913
957
 
914
958
  void Inspect::operator()(Attribute_Selector* s)
@@ -932,109 +976,36 @@ namespace Sass {
932
976
 
933
977
  void Inspect::operator()(Pseudo_Selector* s)
934
978
  {
935
- append_token(s->ns_name(), s);
936
- if (s->expression()) {
937
- append_string("(");
938
- s->expression()->perform(this);
939
- append_string(")");
940
- }
941
- }
942
-
943
- void Inspect::operator()(Wrapped_Selector* s)
944
- {
945
- if (s->name() == " ") {
946
- append_string("");
947
- } else {
948
- bool was = in_wrapped;
949
- in_wrapped = true;
950
- append_token(s->name(), s);
951
- append_string("(");
952
- bool was_comma_array = in_comma_array;
953
- in_comma_array = false;
954
- s->selector()->perform(this);
955
- in_comma_array = was_comma_array;
956
- append_string(")");
957
- in_wrapped = was;
958
- }
959
- }
960
-
961
- void Inspect::operator()(Compound_Selector* s)
962
- {
963
- for (size_t i = 0, L = s->length(); i < L; ++i) {
964
- (*s)[i]->perform(this);
965
- }
966
- if (s->has_line_break()) {
967
- if (output_style() != COMPACT) {
968
- append_optional_linefeed();
969
- }
970
- }
971
- }
972
-
973
- void Inspect::operator()(Complex_Selector* c)
974
- {
975
- Compound_Selector_Obj head = c->head();
976
- Complex_Selector_Obj tail = c->tail();
977
- Complex_Selector::Combinator comb = c->combinator();
978
-
979
- if (comb == Complex_Selector::ANCESTOR_OF && (!head || head->empty())) {
980
- if (tail) tail->perform(this);
981
- return;
982
- }
983
979
 
984
- if (c->has_line_feed()) {
985
- if (!(c->has_parent_ref())) {
986
- append_optional_linefeed();
987
- append_indentation();
980
+ if (s->name() != "") {
981
+ append_string(":");
982
+ if (s->isSyntacticElement()) {
983
+ append_string(":");
988
984
  }
989
- }
990
-
991
- if (head && head->length() != 0) head->perform(this);
992
- bool is_empty = !head || head->length() == 0 || head->is_empty_reference();
993
- bool is_tail = head && !head->is_empty_reference() && tail;
994
- if (output_style() == COMPRESSED && comb != Complex_Selector::ANCESTOR_OF) scheduled_space = 0;
995
-
996
- switch (comb) {
997
- case Complex_Selector::ANCESTOR_OF:
998
- if (is_tail) append_mandatory_space();
999
- break;
1000
- case Complex_Selector::PARENT_OF:
1001
- append_optional_space();
1002
- append_string(">");
1003
- append_optional_space();
1004
- break;
1005
- case Complex_Selector::ADJACENT_TO:
1006
- append_optional_space();
1007
- append_string("+");
1008
- append_optional_space();
1009
- break;
1010
- case Complex_Selector::REFERENCE:
1011
- append_mandatory_space();
1012
- append_string("/");
1013
- if (c->reference()) c->reference()->perform(this);
1014
- append_string("/");
1015
- append_mandatory_space();
1016
- break;
1017
- case Complex_Selector::PRECEDES:
1018
- if (is_empty) append_optional_space();
1019
- else append_mandatory_space();
1020
- append_string("~");
1021
- if (tail) append_mandatory_space();
1022
- else append_optional_space();
1023
- break;
1024
- default: break;
1025
- }
1026
- if (tail && comb != Complex_Selector::ANCESTOR_OF) {
1027
- if (c->has_line_break()) append_optional_linefeed();
1028
- }
1029
- if (tail) tail->perform(this);
1030
- if (!tail && c->has_line_break()) {
1031
- if (output_style() == COMPACT) {
1032
- append_mandatory_space();
985
+ append_token(s->ns_name(), s);
986
+ if (s->selector() || s->argument()) {
987
+ bool was = in_wrapped;
988
+ in_wrapped = true;
989
+ append_string("(");
990
+ if (s->argument()) {
991
+ s->argument()->perform(this);
992
+ }
993
+ if (s->selector() && s->argument()) {
994
+ append_mandatory_space();
995
+ }
996
+ bool was_comma_array = in_comma_array;
997
+ in_comma_array = false;
998
+ if (s->selector()) {
999
+ s->selector()->perform(this);
1000
+ }
1001
+ in_comma_array = was_comma_array;
1002
+ append_string(")");
1003
+ in_wrapped = was;
1033
1004
  }
1034
1005
  }
1035
1006
  }
1036
1007
 
1037
- void Inspect::operator()(Selector_List* g)
1008
+ void Inspect::operator()(SelectorList* g)
1038
1009
  {
1039
1010
 
1040
1011
  if (g->empty()) {
@@ -1049,7 +1020,7 @@ namespace Sass {
1049
1020
  // probably ruby sass eqivalent of element_needs_parens
1050
1021
  if (output_style() == TO_SASS && g->length() == 1 &&
1051
1022
  (!Cast<List>((*g)[0]) &&
1052
- !Cast<Selector_List>((*g)[0]))) {
1023
+ !Cast<SelectorList>((*g)[0]))) {
1053
1024
  append_string("(");
1054
1025
  }
1055
1026
  else if (!in_declaration && in_comma_array) {
@@ -1059,6 +1030,7 @@ namespace Sass {
1059
1030
  if (in_declaration) in_comma_array = true;
1060
1031
 
1061
1032
  for (size_t i = 0, L = g->length(); i < L; ++i) {
1033
+
1062
1034
  if (!in_wrapped && i == 0) append_indentation();
1063
1035
  if ((*g)[i] == nullptr) continue;
1064
1036
  schedule_mapping(g->at(i)->last());
@@ -1075,7 +1047,7 @@ namespace Sass {
1075
1047
  // probably ruby sass eqivalent of element_needs_parens
1076
1048
  if (output_style() == TO_SASS && g->length() == 1 &&
1077
1049
  (!Cast<List>((*g)[0]) &&
1078
- !Cast<Selector_List>((*g)[0]))) {
1050
+ !Cast<SelectorList>((*g)[0]))) {
1079
1051
  append_string(",)");
1080
1052
  }
1081
1053
  else if (!in_declaration && in_comma_array) {
@@ -1083,5 +1055,70 @@ namespace Sass {
1083
1055
  }
1084
1056
 
1085
1057
  }
1058
+ void Inspect::operator()(ComplexSelector* sel)
1059
+ {
1060
+ if (sel->hasPreLineFeed()) {
1061
+ append_optional_linefeed();
1062
+ if (!in_wrapped && output_style() == NESTED) {
1063
+ append_indentation();
1064
+ }
1065
+ }
1066
+ const SelectorComponent* prev = nullptr;
1067
+ for (auto& item : sel->elements()) {
1068
+ if (prev != nullptr) {
1069
+ if (typeid(*item) == typeid(SelectorCombinator) ||
1070
+ typeid(*prev) == typeid(SelectorCombinator)) {
1071
+ append_optional_space();
1072
+ } else {
1073
+ append_mandatory_space();
1074
+ }
1075
+ }
1076
+ item->perform(this);
1077
+ prev = item.ptr();
1078
+ }
1079
+ }
1080
+
1081
+ void Inspect::operator()(SelectorComponent* sel)
1082
+ {
1083
+ // You should probably never call this method directly
1084
+ // But in case anyone does, we will do the upcasting
1085
+ if (auto comp = Cast<CompoundSelector>(sel)) operator()(comp);
1086
+ if (auto comb = Cast<SelectorCombinator>(sel)) operator()(comb);
1087
+ }
1088
+
1089
+ void Inspect::operator()(CompoundSelector* sel)
1090
+ {
1091
+ if (sel->hasRealParent()) {
1092
+ append_string("&");
1093
+ }
1094
+ for (auto& item : sel->elements()) {
1095
+ item->perform(this);
1096
+ }
1097
+ // Add the post line break (from ruby sass)
1098
+ // Dart sass uses another logic for newlines
1099
+ if (sel->hasPostLineBreak()) {
1100
+ if (output_style() != COMPACT) {
1101
+ append_optional_linefeed();
1102
+ }
1103
+ }
1104
+ }
1105
+
1106
+ void Inspect::operator()(SelectorCombinator* sel)
1107
+ {
1108
+ append_optional_space();
1109
+ switch (sel->combinator()) {
1110
+ case SelectorCombinator::Combinator::CHILD: append_string(">"); break;
1111
+ case SelectorCombinator::Combinator::GENERAL: append_string("~"); break;
1112
+ case SelectorCombinator::Combinator::ADJACENT: append_string("+"); break;
1113
+ }
1114
+ append_optional_space();
1115
+ // Add the post line break (from ruby sass)
1116
+ // Dart sass uses another logic for newlines
1117
+ if (sel->hasPostLineBreak()) {
1118
+ if (output_style() != COMPACT) {
1119
+ // append_optional_linefeed();
1120
+ }
1121
+ }
1122
+ }
1086
1123
 
1087
1124
  }