sassc 1.8.1 → 1.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/Makefile +10 -6
  4. data/ext/libsass/Readme.md +4 -4
  5. data/ext/libsass/appveyor.yml +16 -1
  6. data/ext/libsass/docs/README.md +1 -1
  7. data/ext/libsass/docs/api-context-example.md +1 -1
  8. data/ext/libsass/docs/api-context.md +1 -1
  9. data/ext/libsass/docs/api-doc.md +1 -1
  10. data/ext/libsass/docs/api-function-example.md +12 -3
  11. data/ext/libsass/docs/api-function-internal.md +4 -4
  12. data/ext/libsass/docs/api-function.md +15 -13
  13. data/ext/libsass/docs/api-importer-internal.md +9 -4
  14. data/ext/libsass/docs/api-value.md +1 -1
  15. data/ext/libsass/docs/build-shared-library.md +3 -3
  16. data/ext/libsass/docs/custom-functions-internal.md +1 -1
  17. data/ext/libsass/docs/{plugins.go → plugins.md} +0 -0
  18. data/ext/libsass/script/ci-build-libsass +25 -36
  19. data/ext/libsass/script/ci-install-deps +3 -8
  20. data/ext/libsass/script/ci-report-coverage +17 -13
  21. data/ext/libsass/src/ast.cpp +102 -7
  22. data/ext/libsass/src/ast.hpp +53 -27
  23. data/ext/libsass/src/ast_def_macros.hpp +8 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +3 -2
  25. data/ext/libsass/src/backtrace.hpp +1 -1
  26. data/ext/libsass/src/bind.cpp +28 -17
  27. data/ext/libsass/src/bind.hpp +1 -1
  28. data/ext/libsass/src/context.cpp +441 -184
  29. data/ext/libsass/src/context.hpp +79 -82
  30. data/ext/libsass/src/debugger.hpp +3 -1
  31. data/ext/libsass/src/emitter.cpp +18 -17
  32. data/ext/libsass/src/emitter.hpp +5 -2
  33. data/ext/libsass/src/error_handling.cpp +78 -7
  34. data/ext/libsass/src/error_handling.hpp +50 -9
  35. data/ext/libsass/src/eval.cpp +100 -36
  36. data/ext/libsass/src/eval.hpp +5 -5
  37. data/ext/libsass/src/expand.cpp +32 -3
  38. data/ext/libsass/src/extend.cpp +1 -1
  39. data/ext/libsass/src/file.cpp +39 -27
  40. data/ext/libsass/src/file.hpp +67 -13
  41. data/ext/libsass/src/functions.cpp +39 -32
  42. data/ext/libsass/src/inspect.cpp +21 -21
  43. data/ext/libsass/src/json.cpp +1 -1
  44. data/ext/libsass/src/lexer.hpp +33 -4
  45. data/ext/libsass/src/output.cpp +11 -11
  46. data/ext/libsass/src/parser.cpp +28 -130
  47. data/ext/libsass/src/parser.hpp +0 -4
  48. data/ext/libsass/src/prelexer.cpp +8 -5
  49. data/ext/libsass/src/prelexer.hpp +1 -3
  50. data/ext/libsass/src/sass_context.cpp +52 -241
  51. data/ext/libsass/src/sass_context.hpp +156 -0
  52. data/ext/libsass/src/sass_functions.cpp +1 -26
  53. data/ext/libsass/src/sass_functions.hpp +32 -0
  54. data/ext/libsass/src/sass_interface.cpp +14 -48
  55. data/ext/libsass/src/sass_values.cpp +3 -77
  56. data/ext/libsass/src/sass_values.hpp +81 -0
  57. data/ext/libsass/src/source_map.cpp +7 -7
  58. data/ext/libsass/src/source_map.hpp +1 -4
  59. data/ext/libsass/src/to_string.cpp +4 -3
  60. data/ext/libsass/src/to_string.hpp +2 -1
  61. data/ext/libsass/src/util.cpp +34 -16
  62. data/ext/libsass/src/util.hpp +10 -8
  63. data/lib/sassc/version.rb +1 -1
  64. data/lib/tasks/libsass.rb +1 -1
  65. data/test/custom_importer_test.rb +6 -4
  66. data/test/engine_test.rb +5 -3
  67. data/test/functions_test.rb +1 -0
  68. data/test/native_test.rb +1 -1
  69. metadata +6 -4
  70. data/ext/libsass/script/coveralls-debug +0 -32
@@ -2,28 +2,69 @@
2
2
  #define SASS_ERROR_HANDLING_H
3
3
 
4
4
  #include <string>
5
-
5
+ #include <sstream>
6
+ #include <stdexcept>
6
7
  #include "position.hpp"
7
8
 
8
9
  namespace Sass {
9
10
 
10
11
  struct Backtrace;
11
12
 
12
- struct Error_Invalid {
13
- enum Type { read, write, syntax, evaluation };
13
+ namespace Exception {
14
+
15
+ const std::string def_msg = "Invalid sass";
16
+
17
+ class Base : public std::runtime_error {
18
+ protected:
19
+ std::string msg;
20
+ public:
21
+ ParserState pstate;
22
+ public:
23
+ Base(ParserState pstate, std::string msg = def_msg);
24
+ virtual const char* what() const throw();
25
+ virtual ~Base() throw() {};
26
+ };
27
+
28
+ class InvalidSass : public Base {
29
+ public:
30
+ InvalidSass(ParserState pstate, std::string msg);
31
+ virtual ~InvalidSass() throw() {};
32
+ };
33
+
34
+ class InvalidParent : public Base {
35
+ protected:
36
+ Selector* parent;
37
+ Selector* selector;
38
+ public:
39
+ InvalidParent(Selector* parent, Selector* selector);
40
+ virtual ~InvalidParent() throw() {};
41
+ };
14
42
 
15
- Type type;
16
- ParserState pstate;
17
- std::string message;
43
+ class InvalidArgumentType : public Base {
44
+ protected:
45
+ std::string fn;
46
+ std::string arg;
47
+ std::string type;
48
+ const Value* value;
49
+ public:
50
+ InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value* value = 0);
51
+ virtual ~InvalidArgumentType() throw() {};
52
+ };
18
53
 
19
- Error_Invalid(Type type, ParserState pstate, std::string message);
54
+ class InvalidSyntax : public Base {
55
+ public:
56
+ InvalidSyntax(ParserState pstate, std::string msg);
57
+ virtual ~InvalidSyntax() throw() {};
58
+ };
20
59
 
21
- };
60
+ }
22
61
 
23
62
  void warn(std::string msg, ParserState pstate);
24
63
  void warn(std::string msg, ParserState pstate, Backtrace* bt);
25
64
 
26
- void deprecated(std::string msg, ParserState pstate);
65
+ void deprecated_function(std::string msg, ParserState pstate);
66
+ void deprecated(std::string msg, std::string msg2, ParserState pstate);
67
+ void deprecated_bind(std::string msg, ParserState pstate);
27
68
  // void deprecated(std::string msg, ParserState pstate, Backtrace* bt);
28
69
 
29
70
  void error(std::string msg, ParserState pstate);
@@ -378,7 +378,7 @@ namespace Sass {
378
378
  Expression* Eval::operator()(Debug* d)
379
379
  {
380
380
  Expression* message = d->value()->perform(this);
381
- To_String to_string(&ctx);
381
+ To_String to_string(&ctx, false, true);
382
382
  Env* env = exp.environment();
383
383
 
384
384
  // try to use generic function
@@ -400,10 +400,13 @@ namespace Sass {
400
400
 
401
401
  }
402
402
 
403
- std::string cwd(ctx.get_cwd());
403
+ std::string cwd(ctx.cwd());
404
404
  std::string result(unquote(message->perform(&to_string)));
405
- std::string rel_path(Sass::File::resolve_relative_path(d->pstate().path, cwd, cwd));
406
- std::cerr << rel_path << ":" << d->pstate().line+1 << " DEBUG: " << result;
405
+ std::string abs_path(Sass::File::rel2abs(d->pstate().path, cwd, cwd));
406
+ std::string rel_path(Sass::File::abs2rel(d->pstate().path, cwd, cwd));
407
+ std::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().path));
408
+
409
+ std::cerr << output_path << ":" << d->pstate().line+1 << " DEBUG: " << result;
407
410
  std::cerr << std::endl;
408
411
  return 0;
409
412
  }
@@ -446,7 +449,7 @@ namespace Sass {
446
449
  // check the evaluated keys aren't duplicates.
447
450
  if (mm->has_duplicate_key()) {
448
451
  To_String to_string(&ctx);
449
- error("Duplicate key \"" + mm->get_duplicate_key()->perform(&to_string) + "\" in map " + mm->perform(&to_string) + ".", mm->pstate());
452
+ error("Duplicate key \"" + mm->get_duplicate_key()->perform(&to_string) + "\" in map " + m->perform(&to_string) + ".", mm->pstate());
450
453
  }
451
454
 
452
455
  mm->is_expanded(true);
@@ -462,7 +465,11 @@ namespace Sass {
462
465
  // if one of the operands is a '/' then make sure it's evaluated
463
466
  Expression* lhs = b->left()->perform(this);
464
467
  lhs->is_delayed(false);
465
- while (typeid(*lhs) == typeid(Binary_Expression)) lhs = lhs->perform(this);
468
+ while (typeid(*lhs) == typeid(Binary_Expression)) {
469
+ Binary_Expression* lhs_ex = static_cast<Binary_Expression*>(lhs);
470
+ if (lhs_ex->type() == Sass_OP::DIV && lhs_ex->is_delayed()) break;
471
+ lhs = Eval::operator()(lhs_ex);
472
+ }
466
473
 
467
474
  switch (op_type) {
468
475
  case Sass_OP::AND:
@@ -520,36 +527,86 @@ namespace Sass {
520
527
  default: break;
521
528
  }
522
529
 
530
+
523
531
  Expression::Concrete_Type l_type = lhs->concrete_type();
524
532
  Expression::Concrete_Type r_type = rhs->concrete_type();
525
533
 
526
- int precision = (int)ctx.precision;
527
- bool compressed = ctx.output_style == COMPRESSED;
534
+ // Is one of the operands an interpolant?
535
+ String_Schema* s1 = dynamic_cast<String_Schema*>(b->left());
536
+ String_Schema* s2 = dynamic_cast<String_Schema*>(b->right());
537
+
538
+ if ((s1 && s1->has_interpolants()) || (s2 && s2->has_interpolants())) {
539
+ std::string sep;
540
+ switch (op_type) {
541
+ case Sass_OP::SUB: sep = "-"; break;
542
+ case Sass_OP::DIV: sep = "/"; break;
543
+ case Sass_OP::ADD: sep = "+"; break;
544
+ case Sass_OP::MUL: sep = "*"; break;
545
+ default: break;
546
+ }
547
+
548
+ // If possible upgrade LHS to a number
549
+ if (op_type == Sass_OP::DIV || op_type == Sass_OP::MUL || op_type == Sass_OP::ADD || op_type == Sass_OP::SUB) {
550
+ if (String_Constant* str = dynamic_cast<String_Constant*>(lhs)) {
551
+ std::string value(str->value());
552
+ const char* start = value.c_str();
553
+ if (Prelexer::sequence < Prelexer::number >(start) != 0) {
554
+ lhs = SASS_MEMORY_NEW(ctx.mem, Textual, lhs->pstate(), Textual::DIMENSION, str->value());
555
+ lhs->is_delayed(false); lhs = lhs->perform(this);
556
+ }
557
+ }
558
+ if (String_Constant* str = dynamic_cast<String_Constant*>(rhs)) {
559
+ std::string value(str->value());
560
+ const char* start = value.c_str();
561
+ if (Prelexer::sequence < Prelexer::number >(start) != 0) {
562
+ rhs = SASS_MEMORY_NEW(ctx.mem, Textual, rhs->pstate(), Textual::DIMENSION, str->value());
563
+ rhs->is_delayed(false); rhs = rhs->perform(this);
564
+ }
565
+ }
566
+ }
567
+
568
+ To_Value to_value(ctx, ctx.mem);
569
+ Value* v_l = dynamic_cast<Value*>(lhs->perform(&to_value));
570
+ Value* v_r = dynamic_cast<Value*>(rhs->perform(&to_value));
571
+ Expression::Concrete_Type l_type = lhs->concrete_type();
572
+ Expression::Concrete_Type r_type = rhs->concrete_type();
573
+
574
+ if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
575
+ return SASS_MEMORY_NEW(ctx.mem, String_Constant, lhs->pstate(),
576
+ v_l->to_string() + " " + sep + " " + v_r->to_string());
577
+ }
578
+ }
579
+
580
+ // ToDo: throw error in op functions
581
+ // ToDo: then catch and re-throw them
582
+ ParserState pstate(b->pstate());
583
+ int precision = (int)ctx.c_options->precision;
584
+ bool compressed = ctx.output_style() == SASS_STYLE_COMPRESSED;
528
585
  if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
529
586
  const Number* l_n = dynamic_cast<const Number*>(lhs);
530
587
  const Number* r_n = dynamic_cast<const Number*>(rhs);
531
- return op_numbers(ctx.mem, op_type, *l_n, *r_n, compressed, precision);
588
+ return op_numbers(ctx.mem, op_type, *l_n, *r_n, compressed, precision, &pstate);
532
589
  }
533
590
  if (l_type == Expression::NUMBER && r_type == Expression::COLOR) {
534
591
  const Number* l_n = dynamic_cast<const Number*>(lhs);
535
592
  const Color* r_c = dynamic_cast<const Color*>(rhs);
536
- return op_number_color(ctx.mem, op_type, *l_n, *r_c, compressed, precision);
593
+ return op_number_color(ctx.mem, op_type, *l_n, *r_c, compressed, precision, &pstate);
537
594
  }
538
595
  if (l_type == Expression::COLOR && r_type == Expression::NUMBER) {
539
596
  const Color* l_c = dynamic_cast<const Color*>(lhs);
540
597
  const Number* r_n = dynamic_cast<const Number*>(rhs);
541
- return op_color_number(ctx.mem, op_type, *l_c, *r_n, compressed, precision);
598
+ return op_color_number(ctx.mem, op_type, *l_c, *r_n, compressed, precision, &pstate);
542
599
  }
543
600
  if (l_type == Expression::COLOR && r_type == Expression::COLOR) {
544
601
  const Color* l_c = dynamic_cast<const Color*>(lhs);
545
602
  const Color* r_c = dynamic_cast<const Color*>(rhs);
546
- return op_colors(ctx.mem, op_type, *l_c, *r_c, compressed, precision);
603
+ return op_colors(ctx.mem, op_type, *l_c, *r_c, compressed, precision, &pstate);
547
604
  }
548
605
 
549
606
  To_Value to_value(ctx, ctx.mem);
550
607
  Value* v_l = dynamic_cast<Value*>(lhs->perform(&to_value));
551
608
  Value* v_r = dynamic_cast<Value*>(rhs->perform(&to_value));
552
- Value* ex = op_strings(ctx.mem, op_type, *v_l, *v_r, compressed, precision);
609
+ Value* ex = op_strings(ctx.mem, op_type, *v_l, *v_r, compressed, precision, &pstate);
553
610
  if (String_Constant* str = dynamic_cast<String_Constant*>(ex))
554
611
  {
555
612
  if (str->concrete_type() != Expression::STRING) return ex;
@@ -651,14 +708,14 @@ namespace Sass {
651
708
  exp.env_stack.push_back(&fn_env);
652
709
 
653
710
  if (func || body) {
654
- bind("function " + c->name(), params, args, ctx, &fn_env, this);
711
+ bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
655
712
  Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
656
713
  exp.backtrace_stack.push_back(&here);
657
714
  // if it's user-defined, eval the body
658
715
  if (body) result = body->perform(this);
659
716
  // if it's native, invoke the underlying CPP function
660
717
  else result = func(fn_env, *env, ctx, def->signature(), c->pstate(), backtrace());
661
- if (!result) error(std::string("function ") + c->name() + " did not return a value", c->pstate());
718
+ if (!result) error(std::string("Function ") + c->name() + " did not return a value", c->pstate());
662
719
  exp.backtrace_stack.pop_back();
663
720
  }
664
721
 
@@ -675,7 +732,8 @@ namespace Sass {
675
732
  }
676
733
 
677
734
  // populates env with default values for params
678
- bind("function " + c->name(), params, args, ctx, &fn_env, this);
735
+ std::string ff(c->name());
736
+ bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
679
737
 
680
738
  Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
681
739
  exp.backtrace_stack.push_back(&here);
@@ -897,7 +955,7 @@ namespace Sass {
897
955
  } else if (List* list = dynamic_cast<List*>(s)) {
898
956
  std::string acc = ""; // ToDo: different output styles
899
957
  std::string sep = list->separator() == SASS_COMMA ? "," : " ";
900
- if (ctx.output_style != COMPRESSED && sep == ",") sep += " ";
958
+ if (ctx.output_style() != SASS_STYLE_COMPRESSED && sep == ",") sep += " ";
901
959
  bool initial = false;
902
960
  for(auto item : list->elements()) {
903
961
  if (item->concrete_type() != Expression::NULL_VAL) {
@@ -914,10 +972,16 @@ namespace Sass {
914
972
  return evacuate_quotes(interpolation(value));
915
973
  } else if (dynamic_cast<Binary_Expression*>(s)) {
916
974
  Expression* ex = s->perform(this);
975
+ // avoid recursive calls if same object gets returned
976
+ // since we will call interpolate again for the result
977
+ if (ex == s) {
978
+ To_String to_string(&ctx);
979
+ return evacuate_quotes(s->perform(&to_string));
980
+ }
917
981
  return evacuate_quotes(interpolation(ex));
918
982
  } else if (dynamic_cast<Function_Call*>(s)) {
919
983
  Expression* ex = s->perform(this);
920
- return evacuate_quotes(interpolation(ex));
984
+ return evacuate_quotes(unquote(interpolation(ex)));
921
985
  } else if (dynamic_cast<Unary_Expression*>(s)) {
922
986
  Expression* ex = s->perform(this);
923
987
  return evacuate_quotes(interpolation(ex));
@@ -1160,15 +1224,15 @@ namespace Sass {
1160
1224
  return *l < *r;
1161
1225
  }
1162
1226
 
1163
- Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, bool compressed, int precision)
1227
+ Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, bool compressed, int precision, ParserState* pstate)
1164
1228
  {
1165
1229
  double lv = l.value();
1166
1230
  double rv = r.value();
1167
1231
  if (op == Sass_OP::DIV && !rv) {
1168
- return SASS_MEMORY_NEW(mem, String_Quoted, l.pstate(), "Infinity");
1232
+ return SASS_MEMORY_NEW(mem, String_Quoted, pstate ? *pstate : l.pstate(), "Infinity");
1169
1233
  }
1170
1234
  if (op == Sass_OP::MOD && !rv) {
1171
- error("division by zero", r.pstate());
1235
+ error("division by zero", pstate ? *pstate : r.pstate());
1172
1236
  }
1173
1237
 
1174
1238
  Number tmp(r);
@@ -1178,10 +1242,10 @@ namespace Sass {
1178
1242
  std::string r_unit(tmp.unit());
1179
1243
  if (l_unit != r_unit && !l_unit.empty() && !r_unit.empty() &&
1180
1244
  (op == Sass_OP::ADD || op == Sass_OP::SUB)) {
1181
- error("Incompatible units: '"+r_unit+"' and '"+l_unit+"'.", l.pstate());
1245
+ error("Incompatible units: '"+r_unit+"' and '"+l_unit+"'.", pstate ? *pstate : r.pstate());
1182
1246
  }
1183
1247
  Number* v = SASS_MEMORY_NEW(mem, Number, l);
1184
- v->pstate(l.pstate());
1248
+ v->pstate(pstate ? *pstate : l.pstate());
1185
1249
  if (l_unit.empty() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) {
1186
1250
  v->numerator_units() = r.numerator_units();
1187
1251
  v->denominator_units() = r.denominator_units();
@@ -1211,7 +1275,7 @@ namespace Sass {
1211
1275
  return v;
1212
1276
  }
1213
1277
 
1214
- Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, bool compressed, int precision)
1278
+ Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, bool compressed, int precision, ParserState* pstate)
1215
1279
  {
1216
1280
  Color r(rh);
1217
1281
  r.disp("");
@@ -1220,7 +1284,7 @@ namespace Sass {
1220
1284
  case Sass_OP::ADD:
1221
1285
  case Sass_OP::MUL: {
1222
1286
  return SASS_MEMORY_NEW(mem, Color,
1223
- l.pstate(),
1287
+ pstate ? *pstate : l.pstate(),
1224
1288
  ops[op](lv, r.r()),
1225
1289
  ops[op](lv, r.g()),
1226
1290
  ops[op](lv, r.b()),
@@ -1231,13 +1295,13 @@ namespace Sass {
1231
1295
  std::string sep(op == Sass_OP::SUB ? "-" : "/");
1232
1296
  std::string color(r.to_string(compressed||!r.sixtuplet(), precision));
1233
1297
  return SASS_MEMORY_NEW(mem, String_Quoted,
1234
- l.pstate(),
1298
+ pstate ? *pstate : l.pstate(),
1235
1299
  l.to_string(compressed, precision)
1236
1300
  + sep
1237
1301
  + color);
1238
1302
  } break;
1239
1303
  case Sass_OP::MOD: {
1240
- error("cannot divide a number by a color", r.pstate());
1304
+ error("cannot divide a number by a color", pstate ? *pstate : r.pstate());
1241
1305
  } break;
1242
1306
  default: break; // caller should ensure that we don't get here
1243
1307
  }
@@ -1245,35 +1309,35 @@ namespace Sass {
1245
1309
  return SASS_MEMORY_NEW(mem, Color, rh);
1246
1310
  }
1247
1311
 
1248
- Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, bool compressed, int precision)
1312
+ Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, bool compressed, int precision, ParserState* pstate)
1249
1313
  {
1250
1314
  double rv = r.value();
1251
- if (op == Sass_OP::DIV && !rv) error("division by zero", r.pstate());
1315
+ if (op == Sass_OP::DIV && !rv) error("division by zero", pstate ? *pstate : r.pstate());
1252
1316
  return SASS_MEMORY_NEW(mem, Color,
1253
- l.pstate(),
1317
+ pstate ? *pstate : l.pstate(),
1254
1318
  ops[op](l.r(), rv),
1255
1319
  ops[op](l.g(), rv),
1256
1320
  ops[op](l.b(), rv),
1257
1321
  l.a());
1258
1322
  }
1259
1323
 
1260
- Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, bool compressed, int precision)
1324
+ Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, bool compressed, int precision, ParserState* pstate)
1261
1325
  {
1262
1326
  if (l.a() != r.a()) {
1263
- error("alpha channels must be equal when combining colors", r.pstate());
1327
+ error("alpha channels must be equal when combining colors", pstate ? *pstate : r.pstate());
1264
1328
  }
1265
1329
  if (op == Sass_OP::DIV && (!r.r() || !r.g() ||!r.b())) {
1266
- error("division by zero", r.pstate());
1330
+ error("division by zero", pstate ? *pstate : r.pstate());
1267
1331
  }
1268
1332
  return SASS_MEMORY_NEW(mem, Color,
1269
- l.pstate(),
1333
+ pstate ? *pstate : l.pstate(),
1270
1334
  ops[op](l.r(), r.r()),
1271
1335
  ops[op](l.g(), r.g()),
1272
1336
  ops[op](l.b(), r.b()),
1273
1337
  l.a());
1274
1338
  }
1275
1339
 
1276
- Value* Eval::op_strings(Memory_Manager& mem, enum Sass_OP op, Value& lhs, Value& rhs, bool compressed, int precision)
1340
+ Value* Eval::op_strings(Memory_Manager& mem, enum Sass_OP op, Value& lhs, Value& rhs, bool compressed, int precision, ParserState* pstate)
1277
1341
  {
1278
1342
  Expression::Concrete_Type ltype = lhs.concrete_type();
1279
1343
  Expression::Concrete_Type rtype = rhs.concrete_type();
@@ -1320,7 +1384,7 @@ namespace Sass {
1320
1384
  switch (op) {
1321
1385
  case Sass_OP::SUB: sep = "-"; break;
1322
1386
  case Sass_OP::DIV: sep = "/"; break;
1323
- default: break;
1387
+ default: break;
1324
1388
  }
1325
1389
  if (ltype == Expression::NULL_VAL) error("Invalid null operation: \"null plus "+quote(unquote(rstr), '"')+"\".", lhs.pstate());
1326
1390
  if (rtype == Expression::NULL_VAL) error("Invalid null operation: \""+quote(unquote(lstr), '"')+" plus null\".", rhs.pstate());
@@ -89,11 +89,11 @@ namespace Sass {
89
89
  static bool eq(Expression*, Expression*);
90
90
  static bool lt(Expression*, Expression*);
91
91
  // -- arithmetic on the combinations that matter
92
- static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, bool compressed = false, int precision = 5);
93
- static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, bool compressed = false, int precision = 5);
94
- static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, bool compressed = false, int precision = 5);
95
- static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, bool compressed = false, int precision = 5);
96
- static Value* op_strings(Memory_Manager&, enum Sass_OP, Value&, Value&, bool compressed = false, int precision = 5);
92
+ static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
93
+ static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
94
+ static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
95
+ static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
96
+ static Value* op_strings(Memory_Manager&, enum Sass_OP, Value&, Value&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
97
97
 
98
98
  private:
99
99
  std::string interpolation(Expression* s, bool into_quotes = false);
@@ -28,6 +28,7 @@ namespace Sass {
28
28
  env_stack.push_back(0);
29
29
  env_stack.push_back(env);
30
30
  block_stack.push_back(0);
31
+ // import_stack.push_back(0);
31
32
  property_stack.push_back(0);
32
33
  selector_stack.push_back(0);
33
34
  backtrace_stack.push_back(0);
@@ -303,19 +304,31 @@ namespace Sass {
303
304
  Statement* Expand::operator()(Import* imp)
304
305
  {
305
306
  Import* result = SASS_MEMORY_NEW(ctx.mem, Import, imp->pstate());
306
- if (imp->media_queries()) {
307
+ if (imp->media_queries() && imp->media_queries()->size()) {
307
308
  Expression* ex = imp->media_queries()->perform(&eval);
308
309
  result->media_queries(dynamic_cast<List*>(ex));
309
310
  }
310
311
  for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
311
312
  result->urls().push_back(imp->urls()[i]->perform(&eval));
312
313
  }
314
+ // all resources have been dropped for Input_Stubs
315
+ // for ( size_t i = 0, S = imp->incs().size(); i < S; ++i) {}
313
316
  return result;
314
317
  }
315
318
 
316
319
  Statement* Expand::operator()(Import_Stub* i)
317
320
  {
318
- append_block(ctx.style_sheets[i->file_name()]);
321
+ // we don't seem to need that actually afterall
322
+ Sass_Import_Entry import = sass_make_import(
323
+ i->imp_path().c_str(),
324
+ i->abs_path().c_str(),
325
+ 0, 0
326
+ );
327
+ ctx.import_stack.push_back(import);
328
+ const std::string& abs_path(i->resource().abs_path);
329
+ append_block(ctx.sheets.at(abs_path).root);
330
+ sass_delete_import(ctx.import_stack.back());
331
+ ctx.import_stack.pop_back();
319
332
  return 0;
320
333
  }
321
334
 
@@ -577,6 +590,21 @@ namespace Sass {
577
590
  Definition* dd = SASS_MEMORY_NEW(ctx.mem, Definition, *d);
578
591
  env->local_frame()[d->name() +
579
592
  (d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
593
+
594
+ if (d->type() == Definition::FUNCTION && (
595
+ d->name() == "calc" ||
596
+ d->name() == "element" ||
597
+ d->name() == "expression" ||
598
+ d->name() == "url"
599
+ )) {
600
+ deprecated(
601
+ "Naming a function \"" + d->name() + "\" is disallowed",
602
+ "This name conflicts with an existing CSS function with special parse rules.",
603
+ d->pstate()
604
+ );
605
+ }
606
+
607
+
580
608
  // set the static link so we can have lexical scoping
581
609
  dd->environment(env);
582
610
  return 0;
@@ -613,7 +641,8 @@ namespace Sass {
613
641
  thunk->environment(env);
614
642
  new_env.local_frame()["@content[m]"] = thunk;
615
643
  }
616
- bind("mixin " + c->name(), params, args, ctx, &new_env, &eval);
644
+
645
+ bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval);
617
646
  append_block(body);
618
647
  backtrace_stack.pop_back();
619
648
  env_stack.pop_back();