sassc 1.10.1 → 1.11.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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -2
  3. data/ext/libsass/.github/CONTRIBUTING.md +65 -0
  4. data/ext/libsass/.github/ISSUE_TEMPLATE.md +29 -0
  5. data/ext/libsass/Makefile +8 -3
  6. data/ext/libsass/Makefile.conf +28 -22
  7. data/ext/libsass/Readme.md +14 -7
  8. data/ext/libsass/configure.ac +5 -8
  9. data/ext/libsass/docs/api-context-internal.md +3 -0
  10. data/ext/libsass/docs/api-context.md +7 -0
  11. data/ext/libsass/docs/api-doc.md +4 -0
  12. data/ext/libsass/docs/api-importer.md +2 -0
  13. data/ext/libsass/docs/api-value-example.md +55 -0
  14. data/ext/libsass/docs/api-value.md +49 -22
  15. data/ext/libsass/docs/implementations.md +4 -0
  16. data/ext/libsass/include/sass/base.h +5 -4
  17. data/ext/libsass/include/sass/context.h +3 -0
  18. data/ext/libsass/include/sass/values.h +28 -27
  19. data/ext/libsass/include/sass/version.h +1 -1
  20. data/ext/libsass/include/sass2scss.h +1 -1
  21. data/ext/libsass/script/ci-build-libsass +3 -3
  22. data/ext/libsass/script/ci-install-deps +12 -3
  23. data/ext/libsass/src/ast.cpp +321 -212
  24. data/ext/libsass/src/ast.hpp +273 -165
  25. data/ext/libsass/src/ast_factory.hpp +4 -5
  26. data/ext/libsass/src/ast_fwd_decl.hpp +8 -7
  27. data/ext/libsass/src/bind.cpp +2 -7
  28. data/ext/libsass/src/bind.hpp +0 -1
  29. data/ext/libsass/src/check_nesting.cpp +379 -0
  30. data/ext/libsass/src/check_nesting.hpp +60 -0
  31. data/ext/libsass/src/constants.cpp +7 -6
  32. data/ext/libsass/src/constants.hpp +2 -1
  33. data/ext/libsass/src/context.cpp +7 -1
  34. data/ext/libsass/src/context.hpp +1 -1
  35. data/ext/libsass/src/cssize.cpp +76 -32
  36. data/ext/libsass/src/cssize.hpp +7 -8
  37. data/ext/libsass/src/debugger.hpp +70 -40
  38. data/ext/libsass/src/error_handling.cpp +15 -2
  39. data/ext/libsass/src/error_handling.hpp +19 -0
  40. data/ext/libsass/src/eval.cpp +107 -161
  41. data/ext/libsass/src/eval.hpp +12 -8
  42. data/ext/libsass/src/expand.cpp +81 -74
  43. data/ext/libsass/src/expand.hpp +13 -12
  44. data/ext/libsass/src/extend.cpp +149 -142
  45. data/ext/libsass/src/extend.hpp +10 -3
  46. data/ext/libsass/src/file.cpp +2 -1
  47. data/ext/libsass/src/functions.cpp +96 -59
  48. data/ext/libsass/src/functions.hpp +2 -2
  49. data/ext/libsass/src/inspect.cpp +33 -45
  50. data/ext/libsass/src/inspect.hpp +7 -7
  51. data/ext/libsass/src/json.cpp +17 -5
  52. data/ext/libsass/src/lexer.cpp +3 -3
  53. data/ext/libsass/src/listize.cpp +10 -10
  54. data/ext/libsass/src/listize.hpp +3 -3
  55. data/ext/libsass/src/node.cpp +30 -30
  56. data/ext/libsass/src/node.hpp +13 -13
  57. data/ext/libsass/src/operation.hpp +21 -19
  58. data/ext/libsass/src/output.cpp +48 -103
  59. data/ext/libsass/src/output.hpp +0 -1
  60. data/ext/libsass/src/parser.cpp +161 -133
  61. data/ext/libsass/src/parser.hpp +10 -7
  62. data/ext/libsass/src/remove_placeholders.cpp +6 -6
  63. data/ext/libsass/src/remove_placeholders.hpp +1 -1
  64. data/ext/libsass/src/sass.cpp +21 -0
  65. data/ext/libsass/src/sass.hpp +8 -1
  66. data/ext/libsass/src/sass2scss.cpp +14 -3
  67. data/ext/libsass/src/sass_context.cpp +69 -24
  68. data/ext/libsass/src/sass_context.hpp +3 -0
  69. data/ext/libsass/src/source_map.cpp +22 -10
  70. data/ext/libsass/src/to_value.cpp +2 -2
  71. data/ext/libsass/src/to_value.hpp +1 -1
  72. data/ext/libsass/src/units.hpp +3 -1
  73. data/ext/libsass/src/util.cpp +20 -16
  74. data/ext/libsass/src/util.hpp +2 -1
  75. data/ext/libsass/win/libsass.targets +2 -0
  76. data/ext/libsass/win/libsass.vcxproj.filters +6 -0
  77. data/lib/sassc/engine.rb +5 -0
  78. data/lib/sassc/native/native_functions_api.rb +13 -1
  79. data/lib/sassc/script/value_conversion.rb +11 -1
  80. data/lib/sassc/script/value_conversion/list.rb +23 -0
  81. data/lib/sassc/version.rb +1 -1
  82. data/test/engine_test.rb +18 -2
  83. data/test/functions_test.rb +30 -0
  84. data/test/native_test.rb +1 -1
  85. metadata +8 -3
@@ -2,6 +2,7 @@
2
2
  #define SASS_EXTEND_H
3
3
 
4
4
  #include <string>
5
+ #include <set>
5
6
 
6
7
  #include "ast.hpp"
7
8
  #include "operation.hpp"
@@ -12,7 +13,7 @@ namespace Sass {
12
13
  class Context;
13
14
  class Node;
14
15
 
15
- typedef Subset_Map<std::string, std::pair<Complex_Selector*, Compound_Selector*> > ExtensionSubsetMap;
16
+ typedef Subset_Map<std::string, std::pair<Sequence_Selector*, SimpleSequence_Selector*> > ExtensionSubsetMap;
16
17
 
17
18
  class Extend : public Operation_CRTP<void, Extend> {
18
19
 
@@ -23,11 +24,17 @@ namespace Sass {
23
24
 
24
25
  public:
25
26
  static Node subweave(Node& one, Node& two, Context& ctx);
26
- static Selector_List* extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool& extendedSomething);
27
- static Selector_List* extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace = false) {
27
+ static CommaSequence_Selector* extendSelectorList(CommaSequence_Selector* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool& extendedSomething, std::set<SimpleSequence_Selector>& seen);
28
+ static CommaSequence_Selector* extendSelectorList(CommaSequence_Selector* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool& extendedSomething);
29
+ static CommaSequence_Selector* extendSelectorList(CommaSequence_Selector* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace = false) {
28
30
  bool extendedSomething = false;
29
31
  return extendSelectorList(pSelectorList, ctx, subset_map, isReplace, extendedSomething);
30
32
  }
33
+ static CommaSequence_Selector* extendSelectorList(CommaSequence_Selector* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, std::set<SimpleSequence_Selector>& seen) {
34
+ bool isReplace = false;
35
+ bool extendedSomething = false;
36
+ return extendSelectorList(pSelectorList, ctx, subset_map, isReplace, extendedSomething, seen);
37
+ }
31
38
  Extend(Context&, ExtensionSubsetMap&);
32
39
  ~Extend() { }
33
40
 
@@ -196,6 +196,7 @@ namespace Sass {
196
196
  bool is_slash = pos + 2 == L && (l[pos+1] == '/' || l[pos+1] == '\\');
197
197
  bool is_self = pos + 3 == L && (l[pos+1] == '.');
198
198
  if (!is_self && !is_slash) r = r.substr(3);
199
+ else if (pos == std::string::npos) break;
199
200
  l = l.substr(0, pos == std::string::npos ? pos : pos + 1);
200
201
  }
201
202
 
@@ -217,7 +218,7 @@ namespace Sass {
217
218
  // create an absolute path by resolving relative paths with cwd
218
219
  std::string rel2abs(const std::string& path, const std::string& base, const std::string& cwd)
219
220
  {
220
- return make_canonical_path(join_paths(join_paths(cwd, base), path));
221
+ return make_canonical_path(join_paths(join_paths(cwd + "/", base + "/"), path));
221
222
  }
222
223
 
223
224
  // create a path that is relative to the given base directory
@@ -155,7 +155,7 @@ namespace Sass {
155
155
  T* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx);
156
156
 
157
157
  template <>
158
- Selector_List* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
158
+ CommaSequence_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
159
159
  Expression* exp = ARG(argname, Expression);
160
160
  if (exp->concrete_type() == Expression::NULL_VAL) {
161
161
  std::stringstream msg;
@@ -171,7 +171,7 @@ namespace Sass {
171
171
  }
172
172
 
173
173
  template <>
174
- Complex_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
174
+ Sequence_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
175
175
  Expression* exp = ARG(argname, Expression);
176
176
  if (exp->concrete_type() == Expression::NULL_VAL) {
177
177
  std::stringstream msg;
@@ -183,12 +183,12 @@ namespace Sass {
183
183
  str->quote_mark(0);
184
184
  }
185
185
  std::string exp_src = exp->to_string(ctx.c_options) + "{";
186
- Selector_List* sel_list = Parser::parse_selector(exp_src.c_str(), ctx);
186
+ CommaSequence_Selector* sel_list = Parser::parse_selector(exp_src.c_str(), ctx);
187
187
  return (sel_list->length() > 0) ? sel_list->first() : 0;
188
188
  }
189
189
 
190
190
  template <>
191
- Compound_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
191
+ SimpleSequence_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
192
192
  Expression* exp = ARG(argname, Expression);
193
193
  if (exp->concrete_type() == Expression::NULL_VAL) {
194
194
  std::stringstream msg;
@@ -199,7 +199,7 @@ namespace Sass {
199
199
  str->quote_mark(0);
200
200
  }
201
201
  std::string exp_src = exp->to_string(ctx.c_options) + "{";
202
- Selector_List* sel_list = Parser::parse_selector(exp_src.c_str(), ctx);
202
+ CommaSequence_Selector* sel_list = Parser::parse_selector(exp_src.c_str(), ctx);
203
203
  return (sel_list->length() > 0) ? sel_list->first()->tail()->head() : 0;
204
204
  }
205
205
 
@@ -385,6 +385,12 @@ namespace Sass {
385
385
  while (h < 0) h += 1;
386
386
  while (h > 1) h -= 1;
387
387
 
388
+ // if saturation is exacly zero, we loose
389
+ // information for hue, since it will evaluate
390
+ // to zero if converted back from rgb. Setting
391
+ // saturation to a very tiny number solves this.
392
+ if (s == 0) s = 1e-10;
393
+
388
394
  // Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color.
389
395
  double m2;
390
396
  if (l <= 0.5) m2 = l*(s+1.0);
@@ -819,7 +825,7 @@ namespace Sass {
819
825
  }
820
826
  if (hsl) {
821
827
  HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b());
822
- if (h) hsl_struct.h = static_cast<double>(((static_cast<int>(h->value()) % 360) + 360) % 360) / 360.0;
828
+ if (h) hsl_struct.h = std::fmod(h->value(), 360.0);
823
829
  if (s) hsl_struct.s = ARGR("$saturation", Number, 0, 100)->value();
824
830
  if (l) hsl_struct.l = ARGR("$lightness", Number, 0, 100)->value();
825
831
  double alpha = a ? ARGR("$alpha", Number, 0, 1.0)->value() : color->a();
@@ -880,7 +886,7 @@ namespace Sass {
880
886
  if (String_Quoted* string_quoted = dynamic_cast<String_Quoted*>(arg)) {
881
887
  String_Constant* result = SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, string_quoted->value());
882
888
  // remember if the string was quoted (color tokens)
883
- result->sass_fix_1291(string_quoted->quote_mark() != 0);
889
+ result->is_delayed(true); // delay colors
884
890
  return result;
885
891
  }
886
892
  else if (dynamic_cast<String_Constant*>(arg)) {
@@ -910,7 +916,6 @@ namespace Sass {
910
916
  // all other nodes must be converted to a string node
911
917
  std::string str(quote(arg->to_string(ctx.c_options), String_Constant::double_quote()));
912
918
  String_Quoted* result = SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, str);
913
- result->is_delayed(true);
914
919
  result->quote_mark('*');
915
920
  return result;
916
921
  }
@@ -1015,8 +1020,14 @@ namespace Sass {
1015
1020
  std::string str = unquote(s->value());
1016
1021
 
1017
1022
  size_t size = utf8::distance(str.begin(), str.end());
1018
- if (end_at <= size * -1.0) { end_at += size; }
1019
- if (end_at < 0) { end_at += size + 1; }
1023
+ if (end_at <= size * -1.0 && size > 1) {
1024
+ end_at += size;
1025
+ if (end_at == 0) end_at = 1;
1026
+ }
1027
+ if (end_at < 0) {
1028
+ end_at += size + 1;
1029
+ if (end_at == 0) end_at = 1;
1030
+ }
1020
1031
  if (end_at > size) { end_at = (double)size; }
1021
1032
  if (start_at < 0) { start_at += size + 1; }
1022
1033
  else if (start_at == 0) { ++ start_at; }
@@ -1212,7 +1223,7 @@ namespace Sass {
1212
1223
  Signature length_sig = "length($list)";
1213
1224
  BUILT_IN(length)
1214
1225
  {
1215
- if (Selector_List* sl = dynamic_cast<Selector_List*>(env["$list"])) {
1226
+ if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(env["$list"])) {
1216
1227
  return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)sl->length());
1217
1228
  }
1218
1229
  Expression* v = ARG("$list", Expression);
@@ -1221,9 +1232,9 @@ namespace Sass {
1221
1232
  return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)(map ? map->length() : 1));
1222
1233
  }
1223
1234
  if (v->concrete_type() == Expression::SELECTOR) {
1224
- if (Compound_Selector* h = dynamic_cast<Compound_Selector*>(v)) {
1235
+ if (SimpleSequence_Selector* h = dynamic_cast<SimpleSequence_Selector*>(v)) {
1225
1236
  return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)h->length());
1226
- } else if (Selector_List* ls = dynamic_cast<Selector_List*>(v)) {
1237
+ } else if (CommaSequence_Selector* ls = dynamic_cast<CommaSequence_Selector*>(v)) {
1227
1238
  return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)ls->length());
1228
1239
  } else {
1229
1240
  return SASS_MEMORY_NEW(ctx.mem, Number, pstate, 1);
@@ -1241,7 +1252,7 @@ namespace Sass {
1241
1252
  {
1242
1253
  Number* n = ARG("$n", Number);
1243
1254
  Map* m = dynamic_cast<Map*>(env["$list"]);
1244
- if (Selector_List* sl = dynamic_cast<Selector_List*>(env["$list"])) {
1255
+ if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(env["$list"])) {
1245
1256
  size_t len = m ? m->length() : sl->length();
1246
1257
  bool empty = m ? m->empty() : sl->empty();
1247
1258
  if (empty) error("argument `$list` of `" + std::string(sig) + "` must not be empty", pstate);
@@ -1271,13 +1282,16 @@ namespace Sass {
1271
1282
  return l;
1272
1283
  }
1273
1284
  else {
1274
- return l->value_at_index(static_cast<int>(index));
1285
+ Expression* rv = l->value_at_index(static_cast<int>(index));
1286
+ rv->set_delayed(false);
1287
+ return rv;
1275
1288
  }
1276
1289
  }
1277
1290
 
1278
1291
  Signature set_nth_sig = "set-nth($list, $n, $value)";
1279
1292
  BUILT_IN(set_nth)
1280
1293
  {
1294
+ Map* m = dynamic_cast<Map*>(env["$list"]);
1281
1295
  List* l = dynamic_cast<List*>(env["$list"]);
1282
1296
  Number* n = ARG("$n", Number);
1283
1297
  Expression* v = ARG("$value", Expression);
@@ -1285,6 +1299,9 @@ namespace Sass {
1285
1299
  l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1286
1300
  *l << ARG("$list", Expression);
1287
1301
  }
1302
+ if (m) {
1303
+ l = m->to_list(ctx, pstate);
1304
+ }
1288
1305
  if (l->empty()) error("argument `$list` of `" + std::string(sig) + "` must not be empty", pstate);
1289
1306
  double index = std::floor(n->value() < 0 ? l->length() + n->value() : n->value() - 1);
1290
1307
  if (index < 0 || index > l->length() - 1) error("index out of bounds for `" + std::string(sig) + "`", pstate);
@@ -1298,12 +1315,16 @@ namespace Sass {
1298
1315
  Signature index_sig = "index($list, $value)";
1299
1316
  BUILT_IN(index)
1300
1317
  {
1318
+ Map* m = dynamic_cast<Map*>(env["$list"]);
1301
1319
  List* l = dynamic_cast<List*>(env["$list"]);
1302
1320
  Expression* v = ARG("$value", Expression);
1303
1321
  if (!l) {
1304
1322
  l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1305
1323
  *l << ARG("$list", Expression);
1306
1324
  }
1325
+ if (m) {
1326
+ l = m->to_list(ctx, pstate);
1327
+ }
1307
1328
  for (size_t i = 0, L = l->length(); i < L; ++i) {
1308
1329
  if (Eval::eq(l->value_at_index(i), v)) return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)(i+1));
1309
1330
  }
@@ -1313,6 +1334,8 @@ namespace Sass {
1313
1334
  Signature join_sig = "join($list1, $list2, $separator: auto)";
1314
1335
  BUILT_IN(join)
1315
1336
  {
1337
+ Map* m1 = dynamic_cast<Map*>(env["$list1"]);
1338
+ Map* m2 = dynamic_cast<Map*>(env["$list2"]);
1316
1339
  List* l1 = dynamic_cast<List*>(env["$list1"]);
1317
1340
  List* l2 = dynamic_cast<List*>(env["$list2"]);
1318
1341
  String_Constant* sep = ARG("$separator", String_Constant);
@@ -1326,6 +1349,13 @@ namespace Sass {
1326
1349
  l2 = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1327
1350
  *l2 << ARG("$list2", Expression);
1328
1351
  }
1352
+ if (m1) {
1353
+ l1 = m1->to_list(ctx, pstate);
1354
+ sep_val = SASS_COMMA;
1355
+ }
1356
+ if (m2) {
1357
+ l2 = m2->to_list(ctx, pstate);
1358
+ }
1329
1359
  size_t len = l1->length() + l2->length();
1330
1360
  std::string sep_str = unquote(sep->value());
1331
1361
  if (sep_str == "space") sep_val = SASS_SPACE;
@@ -1340,9 +1370,10 @@ namespace Sass {
1340
1370
  Signature append_sig = "append($list, $val, $separator: auto)";
1341
1371
  BUILT_IN(append)
1342
1372
  {
1373
+ Map* m = dynamic_cast<Map*>(env["$list"]);
1343
1374
  List* l = dynamic_cast<List*>(env["$list"]);
1344
1375
  Expression* v = ARG("$val", Expression);
1345
- if (Selector_List* sl = dynamic_cast<Selector_List*>(env["$list"])) {
1376
+ if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(env["$list"])) {
1346
1377
  Listize listize(ctx.mem);
1347
1378
  l = dynamic_cast<List*>(sl->perform(&listize));
1348
1379
  }
@@ -1351,6 +1382,9 @@ namespace Sass {
1351
1382
  l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1352
1383
  *l << ARG("$list", Expression);
1353
1384
  }
1385
+ if (m) {
1386
+ l = m->to_list(ctx, pstate);
1387
+ }
1354
1388
  List* result = SASS_MEMORY_NEW(ctx.mem, List, pstate, l->length() + 1, l->separator());
1355
1389
  std::string sep_str(unquote(sep->value()));
1356
1390
  if (sep_str == "space") result->separator(SASS_SPACE);
@@ -1380,9 +1414,14 @@ namespace Sass {
1380
1414
  size_t shortest = 0;
1381
1415
  for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1382
1416
  List* ith = dynamic_cast<List*>(arglist->value_at_index(i));
1417
+ Map* mith = dynamic_cast<Map*>(arglist->value_at_index(i));
1383
1418
  if (!ith) {
1384
- ith = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1385
- *ith << arglist->value_at_index(i);
1419
+ if (mith) {
1420
+ ith = mith->to_list(ctx, pstate);
1421
+ } else {
1422
+ ith = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1423
+ *ith << arglist->value_at_index(i);
1424
+ }
1386
1425
  if (arglist->is_arglist()) {
1387
1426
  ((Argument*)(*arglist)[i])->value(ith);
1388
1427
  } else {
@@ -1636,7 +1675,7 @@ namespace Sass {
1636
1675
  }
1637
1676
  }
1638
1677
  Function_Call* func = SASS_MEMORY_NEW(ctx.mem, Function_Call, pstate, name, args);
1639
- Expand expand(ctx, &d_env, backtrace);
1678
+ Expand expand(ctx, &d_env, backtrace, &selector_stack);
1640
1679
  return func->perform(&expand.eval);
1641
1680
 
1642
1681
  }
@@ -1654,14 +1693,12 @@ namespace Sass {
1654
1693
  // { return ARG("$condition", Expression)->is_false() ? ARG("$if-false", Expression) : ARG("$if-true", Expression); }
1655
1694
  BUILT_IN(sass_if)
1656
1695
  {
1657
- Expand expand(ctx, &d_env, backtrace);
1696
+ Expand expand(ctx, &d_env, backtrace, &selector_stack);
1658
1697
  bool is_true = !ARG("$condition", Expression)->perform(&expand.eval)->is_false();
1659
- if (is_true) {
1660
- return ARG("$if-true", Expression)->perform(&expand.eval);
1661
- }
1662
- else {
1663
- return ARG("$if-false", Expression)->perform(&expand.eval);
1664
- }
1698
+ Expression* res = ARG(is_true ? "$if-true" : "$if-false", Expression);
1699
+ res = res->perform(&expand.eval);
1700
+ res->set_delayed(false); // clone?
1701
+ return res;
1665
1702
  }
1666
1703
 
1667
1704
  ////////////////
@@ -1716,7 +1753,7 @@ namespace Sass {
1716
1753
  error("$selectors: At least one selector must be passed", pstate);
1717
1754
 
1718
1755
  // Parse args into vector of selectors
1719
- std::vector<Selector_List*> parsedSelectors;
1756
+ std::vector<CommaSequence_Selector*> parsedSelectors;
1720
1757
  for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1721
1758
  Expression* exp = dynamic_cast<Expression*>(arglist->value_at_index(i));
1722
1759
  if (exp->concrete_type() == Expression::NULL_VAL) {
@@ -1729,7 +1766,7 @@ namespace Sass {
1729
1766
  str->quote_mark(0);
1730
1767
  }
1731
1768
  std::string exp_src = exp->to_string(ctx.c_options) + "{";
1732
- Selector_List* sel = Parser::parse_selector(exp_src.c_str(), ctx);
1769
+ CommaSequence_Selector* sel = Parser::parse_selector(exp_src.c_str(), ctx);
1733
1770
  parsedSelectors.push_back(sel);
1734
1771
  }
1735
1772
 
@@ -1739,14 +1776,14 @@ namespace Sass {
1739
1776
  }
1740
1777
 
1741
1778
  // Set the first element as the `result`, keep appending to as we go down the parsedSelector vector.
1742
- std::vector<Selector_List*>::iterator itr = parsedSelectors.begin();
1743
- Selector_List* result = *itr;
1779
+ std::vector<CommaSequence_Selector*>::iterator itr = parsedSelectors.begin();
1780
+ CommaSequence_Selector* result = *itr;
1744
1781
  ++itr;
1745
1782
 
1746
1783
  for(;itr != parsedSelectors.end(); ++itr) {
1747
- Selector_List* child = *itr;
1748
- std::vector<Complex_Selector*> exploded;
1749
- Selector_List* rv = child->parentize(result, ctx);
1784
+ CommaSequence_Selector* child = *itr;
1785
+ std::vector<Sequence_Selector*> exploded;
1786
+ CommaSequence_Selector* rv = child->resolve_parent_refs(ctx, result);
1750
1787
  for (size_t m = 0, mLen = rv->length(); m < mLen; ++m) {
1751
1788
  exploded.push_back((*rv)[m]);
1752
1789
  }
@@ -1767,7 +1804,7 @@ namespace Sass {
1767
1804
  error("$selectors: At least one selector must be passed", pstate);
1768
1805
 
1769
1806
  // Parse args into vector of selectors
1770
- std::vector<Selector_List*> parsedSelectors;
1807
+ std::vector<CommaSequence_Selector*> parsedSelectors;
1771
1808
  for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1772
1809
  Expression* exp = dynamic_cast<Expression*>(arglist->value_at_index(i));
1773
1810
  if (exp->concrete_type() == Expression::NULL_VAL) {
@@ -1780,7 +1817,7 @@ namespace Sass {
1780
1817
  str->quote_mark(0);
1781
1818
  }
1782
1819
  std::string exp_src = exp->to_string() + "{";
1783
- Selector_List* sel = Parser::parse_selector(exp_src.c_str(), ctx);
1820
+ CommaSequence_Selector* sel = Parser::parse_selector(exp_src.c_str(), ctx);
1784
1821
  parsedSelectors.push_back(sel);
1785
1822
  }
1786
1823
 
@@ -1790,13 +1827,13 @@ namespace Sass {
1790
1827
  }
1791
1828
 
1792
1829
  // Set the first element as the `result`, keep appending to as we go down the parsedSelector vector.
1793
- std::vector<Selector_List*>::iterator itr = parsedSelectors.begin();
1794
- Selector_List* result = *itr;
1830
+ std::vector<CommaSequence_Selector*>::iterator itr = parsedSelectors.begin();
1831
+ CommaSequence_Selector* result = *itr;
1795
1832
  ++itr;
1796
1833
 
1797
1834
  for(;itr != parsedSelectors.end(); ++itr) {
1798
- Selector_List* child = *itr;
1799
- std::vector<Complex_Selector*> newElements;
1835
+ CommaSequence_Selector* child = *itr;
1836
+ std::vector<Sequence_Selector*> newElements;
1800
1837
 
1801
1838
  // For every COMPLEX_SELECTOR in `result`
1802
1839
  // For every COMPLEX_SELECTOR in `child`
@@ -1807,12 +1844,12 @@ namespace Sass {
1807
1844
  // Replace result->elements with newElements
1808
1845
  for (size_t i = 0, resultLen = result->length(); i < resultLen; ++i) {
1809
1846
  for (size_t j = 0, childLen = child->length(); j < childLen; ++j) {
1810
- Complex_Selector* parentSeqClone = (*result)[i]->cloneFully(ctx);
1811
- Complex_Selector* childSeq = (*child)[j];
1812
- Complex_Selector* base = childSeq->tail();
1847
+ Sequence_Selector* parentSeqClone = (*result)[i]->cloneFully(ctx);
1848
+ Sequence_Selector* childSeq = (*child)[j];
1849
+ Sequence_Selector* base = childSeq->tail();
1813
1850
 
1814
1851
  // Must be a simple sequence
1815
- if( childSeq->combinator() != Complex_Selector::Combinator::ANCESTOR_OF ) {
1852
+ if( childSeq->combinator() != Sequence_Selector::Combinator::ANCESTOR_OF ) {
1816
1853
  std::string msg("Can't append `");
1817
1854
  msg += childSeq->to_string();
1818
1855
  msg += "` to `";
@@ -1822,7 +1859,7 @@ namespace Sass {
1822
1859
  }
1823
1860
 
1824
1861
  // Cannot be a Universal selector
1825
- Type_Selector* pType = dynamic_cast<Type_Selector*>(childSeq->head()->first());
1862
+ Element_Selector* pType = dynamic_cast<Element_Selector*>(childSeq->head()->first());
1826
1863
  if(pType && pType->name() == "*") {
1827
1864
  std::string msg("Can't append `");
1828
1865
  msg += childSeq->to_string();
@@ -1854,10 +1891,10 @@ namespace Sass {
1854
1891
  Signature selector_unify_sig = "selector-unify($selector1, $selector2)";
1855
1892
  BUILT_IN(selector_unify)
1856
1893
  {
1857
- Selector_List* selector1 = ARGSEL("$selector1", Selector_List, p_contextualize);
1858
- Selector_List* selector2 = ARGSEL("$selector2", Selector_List, p_contextualize);
1894
+ CommaSequence_Selector* selector1 = ARGSEL("$selector1", CommaSequence_Selector, p_contextualize);
1895
+ CommaSequence_Selector* selector2 = ARGSEL("$selector2", CommaSequence_Selector, p_contextualize);
1859
1896
 
1860
- Selector_List* result = selector1->unify_with(selector2, ctx);
1897
+ CommaSequence_Selector* result = selector1->unify_with(selector2, ctx);
1861
1898
  Listize listize(ctx.mem);
1862
1899
  return result->perform(&listize);
1863
1900
  }
@@ -1865,7 +1902,7 @@ namespace Sass {
1865
1902
  Signature simple_selectors_sig = "simple-selectors($selector)";
1866
1903
  BUILT_IN(simple_selectors)
1867
1904
  {
1868
- Compound_Selector* sel = ARGSEL("$selector", Compound_Selector, p_contextualize);
1905
+ SimpleSequence_Selector* sel = ARGSEL("$selector", SimpleSequence_Selector, p_contextualize);
1869
1906
 
1870
1907
  List* l = SASS_MEMORY_NEW(ctx.mem, List, sel->pstate(), sel->length(), SASS_COMMA);
1871
1908
 
@@ -1882,14 +1919,14 @@ namespace Sass {
1882
1919
  Signature selector_extend_sig = "selector-extend($selector, $extendee, $extender)";
1883
1920
  BUILT_IN(selector_extend)
1884
1921
  {
1885
- Selector_List* selector = ARGSEL("$selector", Selector_List, p_contextualize);
1886
- Selector_List* extendee = ARGSEL("$extendee", Selector_List, p_contextualize);
1887
- Selector_List* extender = ARGSEL("$extender", Selector_List, p_contextualize);
1922
+ CommaSequence_Selector* selector = ARGSEL("$selector", CommaSequence_Selector, p_contextualize);
1923
+ CommaSequence_Selector* extendee = ARGSEL("$extendee", CommaSequence_Selector, p_contextualize);
1924
+ CommaSequence_Selector* extender = ARGSEL("$extender", CommaSequence_Selector, p_contextualize);
1888
1925
 
1889
1926
  ExtensionSubsetMap subset_map;
1890
1927
  extender->populate_extends(extendee, ctx, subset_map);
1891
1928
 
1892
- Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, false);
1929
+ CommaSequence_Selector* result = Extend::extendSelectorList(selector, ctx, subset_map, false);
1893
1930
 
1894
1931
  Listize listize(ctx.mem);
1895
1932
  return result->perform(&listize);
@@ -1898,14 +1935,14 @@ namespace Sass {
1898
1935
  Signature selector_replace_sig = "selector-replace($selector, $original, $replacement)";
1899
1936
  BUILT_IN(selector_replace)
1900
1937
  {
1901
- Selector_List* selector = ARGSEL("$selector", Selector_List, p_contextualize);
1902
- Selector_List* original = ARGSEL("$original", Selector_List, p_contextualize);
1903
- Selector_List* replacement = ARGSEL("$replacement", Selector_List, p_contextualize);
1938
+ CommaSequence_Selector* selector = ARGSEL("$selector", CommaSequence_Selector, p_contextualize);
1939
+ CommaSequence_Selector* original = ARGSEL("$original", CommaSequence_Selector, p_contextualize);
1940
+ CommaSequence_Selector* replacement = ARGSEL("$replacement", CommaSequence_Selector, p_contextualize);
1904
1941
 
1905
1942
  ExtensionSubsetMap subset_map;
1906
1943
  replacement->populate_extends(original, ctx, subset_map);
1907
1944
 
1908
- Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, true);
1945
+ CommaSequence_Selector* result = Extend::extendSelectorList(selector, ctx, subset_map, true);
1909
1946
 
1910
1947
  Listize listize(ctx.mem);
1911
1948
  return result->perform(&listize);
@@ -1914,7 +1951,7 @@ namespace Sass {
1914
1951
  Signature selector_parse_sig = "selector-parse($selector)";
1915
1952
  BUILT_IN(selector_parse)
1916
1953
  {
1917
- Selector_List* sel = ARGSEL("$selector", Selector_List, p_contextualize);
1954
+ CommaSequence_Selector* sel = ARGSEL("$selector", CommaSequence_Selector, p_contextualize);
1918
1955
 
1919
1956
  Listize listize(ctx.mem);
1920
1957
  return sel->perform(&listize);
@@ -1923,8 +1960,8 @@ namespace Sass {
1923
1960
  Signature is_superselector_sig = "is-superselector($super, $sub)";
1924
1961
  BUILT_IN(is_superselector)
1925
1962
  {
1926
- Selector_List* sel_sup = ARGSEL("$super", Selector_List, p_contextualize);
1927
- Selector_List* sel_sub = ARGSEL("$sub", Selector_List, p_contextualize);
1963
+ CommaSequence_Selector* sel_sup = ARGSEL("$super", CommaSequence_Selector, p_contextualize);
1964
+ CommaSequence_Selector* sel_sub = ARGSEL("$sub", CommaSequence_Selector, p_contextualize);
1928
1965
  bool result = sel_sup->is_superselector_of(sel_sub);
1929
1966
  return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, result);
1930
1967
  }