sassc 2.2.1 → 2.3.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 (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
  }