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
@@ -894,6 +894,11 @@ namespace Sass {
894
894
  tss->name(tss->name() + (*h)[0]->name());
895
895
  (*rh)[rh->length()-1] = tss;
896
896
  for (i = 1; i < L; ++i) *rh << (*h)[i];
897
+ } else if (Selector_Placeholder* ps = dynamic_cast<Selector_Placeholder*>(rh->last())) {
898
+ Selector_Placeholder* pss = new Selector_Placeholder(*ps);
899
+ pss->name(pss->name() + (*h)[0]->name());
900
+ (*rh)[rh->length()-1] = pss;
901
+ for (i = 1; i < L; ++i) *rh << (*h)[i];
897
902
  } else {
898
903
  *last()->head_ += h;
899
904
  }
@@ -978,6 +983,11 @@ namespace Sass {
978
983
  Complex_Selector* parent = (*parents)[i];
979
984
  Complex_Selector* s = parent->cloneFully(ctx);
980
985
  Complex_Selector* ss = this->clone(ctx);
986
+ // this is only if valid if the parent has no trailing op
987
+ // otherwise we cannot append more simple selectors to head
988
+ if (parent->last()->combinator() != ANCESTOR_OF) {
989
+ throw Exception::InvalidParent(parent, ss);
990
+ }
981
991
  ss->tail(tail ? tail->clone(ctx) : 0);
982
992
  Compound_Selector* h = head_->clone(ctx);
983
993
  if (h->length()) h->erase(h->begin());
@@ -1004,7 +1014,7 @@ namespace Sass {
1004
1014
  *retval << cpy->skip_empty_reference();
1005
1015
  }
1006
1016
  }
1007
- // have no parent and not tails
1017
+ // have no parent nor tails
1008
1018
  else {
1009
1019
  Complex_Selector* cpy = this->clone(ctx);
1010
1020
  cpy->head(SASS_MEMORY_NEW(ctx.mem, Compound_Selector, head->pstate()));
@@ -1859,17 +1869,17 @@ namespace Sass {
1859
1869
  // resolved color
1860
1870
  std::string res_name = name;
1861
1871
 
1862
- double r = round(cap_channel<0xff>(r_));
1863
- double g = round(cap_channel<0xff>(g_));
1864
- double b = round(cap_channel<0xff>(b_));
1872
+ double r = Sass::round(cap_channel<0xff>(r_));
1873
+ double g = Sass::round(cap_channel<0xff>(g_));
1874
+ double b = Sass::round(cap_channel<0xff>(b_));
1865
1875
  double a = cap_channel<1> (a_);
1866
1876
 
1867
1877
  // get color from given name (if one was given at all)
1868
1878
  if (name != "" && name_to_color(name)) {
1869
1879
  const Color* n = name_to_color(name);
1870
- r = round(cap_channel<0xff>(n->r()));
1871
- g = round(cap_channel<0xff>(n->g()));
1872
- b = round(cap_channel<0xff>(n->b()));
1880
+ r = Sass::round(cap_channel<0xff>(n->r()));
1881
+ g = Sass::round(cap_channel<0xff>(n->g()));
1882
+ b = Sass::round(cap_channel<0xff>(n->b()));
1873
1883
  a = cap_channel<1> (n->a());
1874
1884
  }
1875
1885
  // otherwise get the possible resolved color name
@@ -2020,6 +2030,91 @@ namespace Sass {
2020
2030
  return message();
2021
2031
  }
2022
2032
 
2033
+ std::string Selector_List::to_string(bool compressed, int precision) const
2034
+ {
2035
+ std::string str("");
2036
+ auto end = this->end();
2037
+ auto start = this->begin();
2038
+ while (start < end && *start) {
2039
+ Complex_Selector* sel = *start;
2040
+ if (!str.empty()) str += ", ";
2041
+ str += sel->to_string(compressed, precision);
2042
+ ++ start;
2043
+ }
2044
+ return str;
2045
+ }
2046
+
2047
+ std::string Compound_Selector::to_string(bool compressed, int precision) const
2048
+ {
2049
+ std::string str("");
2050
+ auto end = this->end();
2051
+ auto start = this->begin();
2052
+ while (start < end && *start) {
2053
+ Simple_Selector* sel = *start;
2054
+ str += sel->to_string(compressed, precision);
2055
+ ++ start;
2056
+ }
2057
+ return str;
2058
+ }
2059
+
2060
+ std::string Complex_Selector::to_string(bool compressed, int precision) const
2061
+ {
2062
+ // first render head and tail if they are available
2063
+ std::string str_head(head() ? head()->to_string(compressed, precision) : "");
2064
+ std::string str_tail(tail() ? tail()->to_string(compressed, precision) : "");
2065
+ std::string str_ref(reference() ? reference()->to_string(compressed, precision) : "");
2066
+ // combinator in between
2067
+ std::string str_op("");
2068
+ // use a switch statement
2069
+ switch (combinator()) {
2070
+ case ANCESTOR_OF: str_op = " "; break;
2071
+ case PARENT_OF: str_op = ">"; break;
2072
+ case PRECEDES: str_op = "~"; break;
2073
+ case ADJACENT_TO: str_op = "+"; break;
2074
+ case REFERENCE: str_op = "/" + str_ref + "/"; break;
2075
+ }
2076
+ // prettify for non ancestors
2077
+ if (combinator() != ANCESTOR_OF) {
2078
+ // no spaces needed for compressed
2079
+ if (compressed == false) {
2080
+ // make sure we add some spaces where needed
2081
+ if (str_tail != "") str_op += " ";
2082
+ if (str_head != "") str_head += " ";
2083
+ }
2084
+ }
2085
+ // is ancestor with no tail
2086
+ else if (str_tail == "") {
2087
+ str_op = ""; // superflous
2088
+ }
2089
+ // now build the final result
2090
+ return str_head + str_op + str_tail;
2091
+ }
2092
+
2093
+ std::string Selector_Schema::to_string(bool compressed, int precision) const
2094
+ {
2095
+ return contents()->to_string(compressed, precision);
2096
+ }
2097
+
2098
+ std::string Parent_Selector::to_string(bool compressed, int precision) const
2099
+ {
2100
+ return "&";
2101
+ }
2102
+
2103
+ std::string Attribute_Selector::to_string(bool compressed, int precision) const
2104
+ {
2105
+ std::string val(value() ? value()->to_string(compressed, precision) : "");
2106
+ return "[" + this->ns_name() + this->matcher() + val + "]";
2107
+ }
2108
+
2109
+ std::string Wrapped_Selector::to_string(bool compressed, int precision) const
2110
+ {
2111
+ // first render the
2112
+ std::string main(this->Simple_Selector::to_string(compressed, precision));
2113
+ std::string wrapped(selector() ? selector()->to_string(compressed, precision) : "");
2114
+ // now build the final result
2115
+ return main + "(" + wrapped + ")";
2116
+ }
2117
+
2023
2118
  //////////////////////////////////////////////////////////////////////////////////////////
2024
2119
  // Additional method on Lists to retrieve values directly or from an encompassed Argument.
2025
2120
  //////////////////////////////////////////////////////////////////////////////////////////
@@ -10,6 +10,7 @@
10
10
  #include <typeinfo>
11
11
  #include <algorithm>
12
12
  #include <unordered_map>
13
+ #include "sass/base.h"
13
14
 
14
15
  #ifdef __clang__
15
16
 
@@ -537,26 +538,32 @@ namespace Sass {
537
538
  // necessary to store a list of each in an Import node.
538
539
  ////////////////////////////////////////////////////////////////////////////
539
540
  class Import : public Statement {
540
- std::vector<std::string> files_;
541
- std::vector<Expression*> urls_;
542
- ADD_PROPERTY(List*, media_queries);
541
+ std::vector<Expression*> urls_;
542
+ std::vector<Include> incs_;
543
+ ADD_PROPERTY(List*, media_queries);
543
544
  public:
544
545
  Import(ParserState pstate)
545
546
  : Statement(pstate),
546
- files_(std::vector<std::string>()),
547
547
  urls_(std::vector<Expression*>()),
548
+ incs_(std::vector<Include>()),
548
549
  media_queries_(0)
549
550
  { statement_type(IMPORT); }
550
- std::vector<std::string>& files() { return files_; }
551
- std::vector<Expression*>& urls() { return urls_; }
551
+ std::vector<Expression*>& urls() { return urls_; }
552
+ std::vector<Include>& incs() { return incs_; }
552
553
  ATTACH_OPERATIONS()
553
554
  };
554
555
 
556
+ // not yet resolved single import
557
+ // so far we only know requested name
555
558
  class Import_Stub : public Statement {
556
- ADD_PROPERTY(std::string, file_name)
559
+ Include resource_;
557
560
  public:
558
- Import_Stub(ParserState pstate, std::string f)
559
- : Statement(pstate), file_name_(f)
561
+ std::string abs_path() { return resource_.abs_path; };
562
+ std::string imp_path() { return resource_.imp_path; };
563
+ Include resource() { return resource_; };
564
+
565
+ Import_Stub(ParserState pstate, Include res)
566
+ : Statement(pstate), resource_(res)
560
567
  { statement_type(IMPORT_STUB); }
561
568
  ATTACH_OPERATIONS()
562
569
  };
@@ -622,6 +629,10 @@ namespace Sass {
622
629
  If(ParserState pstate, Expression* pred, Block* con, Block* alt = 0)
623
630
  : Has_Block(pstate, con), predicate_(pred), alternative_(alt)
624
631
  { statement_type(IF); }
632
+ virtual bool has_content()
633
+ {
634
+ return Has_Block::has_content() || (alternative_ && alternative_->has_content());
635
+ }
625
636
  ATTACH_OPERATIONS()
626
637
  };
627
638
 
@@ -880,9 +891,9 @@ namespace Sass {
880
891
  //////////////////////////////////////////////////////////////////////////
881
892
  class Binary_Expression : public Expression {
882
893
  private:
883
- ADD_PROPERTY(enum Sass_OP, type)
884
- ADD_PROPERTY(Expression*, left)
885
- ADD_PROPERTY(Expression*, right)
894
+ ADD_HASHED(enum Sass_OP, type)
895
+ ADD_HASHED(Expression*, left)
896
+ ADD_HASHED(Expression*, right)
886
897
  size_t hash_;
887
898
  public:
888
899
  Binary_Expression(ParserState pstate,
@@ -949,8 +960,8 @@ namespace Sass {
949
960
  public:
950
961
  enum Type { PLUS, MINUS, NOT };
951
962
  private:
952
- ADD_PROPERTY(Type, type)
953
- ADD_PROPERTY(Expression*, operand)
963
+ ADD_HASHED(Type, type)
964
+ ADD_HASHED(Expression*, operand)
954
965
  size_t hash_;
955
966
  public:
956
967
  Unary_Expression(ParserState pstate, Type t, Expression* o)
@@ -994,8 +1005,8 @@ namespace Sass {
994
1005
  // Individual argument objects for mixin and function calls.
995
1006
  ////////////////////////////////////////////////////////////
996
1007
  class Argument : public Expression {
997
- ADD_PROPERTY(Expression*, value)
998
- ADD_PROPERTY(std::string, name)
1008
+ ADD_HASHED(Expression*, value)
1009
+ ADD_HASHED(std::string, name)
999
1010
  ADD_PROPERTY(bool, is_rest_argument)
1000
1011
  ADD_PROPERTY(bool, is_keyword_argument)
1001
1012
  size_t hash_;
@@ -1061,8 +1072,8 @@ namespace Sass {
1061
1072
  // Function calls.
1062
1073
  //////////////////
1063
1074
  class Function_Call : public Expression {
1064
- ADD_PROPERTY(std::string, name)
1065
- ADD_PROPERTY(Arguments*, arguments)
1075
+ ADD_HASHED(std::string, name)
1076
+ ADD_HASHED(Arguments*, arguments)
1066
1077
  ADD_PROPERTY(void*, cookie)
1067
1078
  size_t hash_;
1068
1079
  public:
@@ -1157,8 +1168,8 @@ namespace Sass {
1157
1168
  public:
1158
1169
  enum Type { NUMBER, PERCENTAGE, DIMENSION, HEX };
1159
1170
  private:
1160
- ADD_PROPERTY(Type, type)
1161
- ADD_PROPERTY(std::string, value)
1171
+ ADD_HASHED(Type, type)
1172
+ ADD_HASHED(std::string, value)
1162
1173
  size_t hash_;
1163
1174
  public:
1164
1175
  Textual(ParserState pstate, Type t, std::string val)
@@ -1196,7 +1207,7 @@ namespace Sass {
1196
1207
  // Numbers, percentages, dimensions, and colors.
1197
1208
  ////////////////////////////////////////////////
1198
1209
  class Number : public Value {
1199
- ADD_PROPERTY(double, value)
1210
+ ADD_HASHED(double, value)
1200
1211
  ADD_PROPERTY(bool, zero)
1201
1212
  std::vector<std::string> numerator_units_;
1202
1213
  std::vector<std::string> denominator_units_;
@@ -1222,6 +1233,10 @@ namespace Sass {
1222
1233
  {
1223
1234
  if (hash_ == 0) {
1224
1235
  hash_ = std::hash<double>()(value_);
1236
+ for (const auto numerator : numerator_units())
1237
+ hash_combine(hash_, std::hash<std::string>()(numerator));
1238
+ for (const auto denominator : denominator_units())
1239
+ hash_combine(hash_, std::hash<std::string>()(denominator));
1225
1240
  }
1226
1241
  return hash_;
1227
1242
  }
@@ -1237,10 +1252,10 @@ namespace Sass {
1237
1252
  // Colors.
1238
1253
  //////////
1239
1254
  class Color : public Value {
1240
- ADD_PROPERTY(double, r)
1241
- ADD_PROPERTY(double, g)
1242
- ADD_PROPERTY(double, b)
1243
- ADD_PROPERTY(double, a)
1255
+ ADD_HASHED(double, r)
1256
+ ADD_HASHED(double, g)
1257
+ ADD_HASHED(double, b)
1258
+ ADD_HASHED(double, a)
1244
1259
  ADD_PROPERTY(bool, sixtuplet)
1245
1260
  ADD_PROPERTY(std::string, disp)
1246
1261
  size_t hash_;
@@ -1301,7 +1316,7 @@ namespace Sass {
1301
1316
  // Booleans.
1302
1317
  ////////////
1303
1318
  class Boolean : public Value {
1304
- ADD_PROPERTY(bool, value)
1319
+ ADD_HASHED(bool, value)
1305
1320
  size_t hash_;
1306
1321
  public:
1307
1322
  Boolean(ParserState pstate, bool val)
@@ -1380,7 +1395,7 @@ namespace Sass {
1380
1395
  class String_Constant : public String {
1381
1396
  ADD_PROPERTY(char, quote_mark)
1382
1397
  ADD_PROPERTY(bool, can_compress_whitespace)
1383
- ADD_PROPERTY(std::string, value)
1398
+ ADD_HASHED(std::string, value)
1384
1399
  protected:
1385
1400
  size_t hash_;
1386
1401
  public:
@@ -1756,6 +1771,7 @@ namespace Sass {
1756
1771
  virtual unsigned long specificity() {
1757
1772
  return Constants::Specificity_Universal;
1758
1773
  }
1774
+ virtual std::string to_string(bool compressed = false, int precision = 5) const = 0;
1759
1775
  };
1760
1776
  inline Selector::~Selector() { }
1761
1777
 
@@ -1770,6 +1786,7 @@ namespace Sass {
1770
1786
  Selector_Schema(ParserState pstate, String* c)
1771
1787
  : Selector(pstate), contents_(c), at_root_(false)
1772
1788
  { }
1789
+ virtual std::string to_string(bool compressed = false, int precision = 5) const;
1773
1790
  ATTACH_OPERATIONS()
1774
1791
  };
1775
1792
 
@@ -1838,6 +1855,8 @@ namespace Sass {
1838
1855
  inline bool operator!=(const Simple_Selector& rhs) const { return !(*this == rhs); }
1839
1856
 
1840
1857
  bool operator<(const Simple_Selector& rhs) const;
1858
+ // default implementation should work for most of the simple selectors (otherwise overload)
1859
+ virtual std::string to_string(bool compressed = false, int precision = 5) const { return this->ns_name(); };
1841
1860
  ATTACH_OPERATIONS();
1842
1861
  };
1843
1862
  inline Simple_Selector::~Simple_Selector() { }
@@ -1861,6 +1880,7 @@ namespace Sass {
1861
1880
  }
1862
1881
  std::string type() { return "selector"; }
1863
1882
  static std::string type_name() { return "selector"; }
1883
+ virtual std::string to_string(bool compressed = false, int precision = 5) const;
1864
1884
  ATTACH_OPERATIONS()
1865
1885
  };
1866
1886
 
@@ -1873,6 +1893,7 @@ namespace Sass {
1873
1893
  : Simple_Selector(pstate, n)
1874
1894
  { has_placeholder(true); }
1875
1895
  // virtual Selector_Placeholder* find_placeholder();
1896
+ virtual ~Selector_Placeholder() {};
1876
1897
  ATTACH_OPERATIONS()
1877
1898
  };
1878
1899
 
@@ -1931,6 +1952,7 @@ namespace Sass {
1931
1952
  bool operator==(const Attribute_Selector& rhs) const;
1932
1953
  bool operator<(const Simple_Selector& rhs) const;
1933
1954
  bool operator<(const Attribute_Selector& rhs) const;
1955
+ virtual std::string to_string(bool compressed = false, int precision = 5) const;
1934
1956
  ATTACH_OPERATIONS()
1935
1957
  };
1936
1958
 
@@ -2005,6 +2027,7 @@ namespace Sass {
2005
2027
  }
2006
2028
  bool operator==(const Simple_Selector& rhs) const;
2007
2029
  bool operator==(const Wrapped_Selector& rhs) const;
2030
+ virtual std::string to_string(bool compressed = false, int precision = 5) const;
2008
2031
  ATTACH_OPERATIONS()
2009
2032
  };
2010
2033
 
@@ -2091,6 +2114,7 @@ namespace Sass {
2091
2114
  Compound_Selector* clone(Context&) const; // does not clone the Simple_Selector*s
2092
2115
 
2093
2116
  Compound_Selector* minus(Compound_Selector* rhs, Context& ctx);
2117
+ virtual std::string to_string(bool compressed = false, int precision = 5) const;
2094
2118
  ATTACH_OPERATIONS()
2095
2119
  };
2096
2120
 
@@ -2239,6 +2263,7 @@ namespace Sass {
2239
2263
  Complex_Selector* clone(Context&) const; // does not clone Compound_Selector*s
2240
2264
  Complex_Selector* cloneFully(Context&) const; // clones Compound_Selector*s
2241
2265
  // std::vector<Compound_Selector*> to_vector();
2266
+ virtual std::string to_string(bool compressed = false, int precision = 5) const;
2242
2267
  ATTACH_OPERATIONS()
2243
2268
  };
2244
2269
 
@@ -2284,6 +2309,7 @@ namespace Sass {
2284
2309
  virtual bool operator==(const Selector_List& rhs) const;
2285
2310
  // Selector Lists can be compared to comma lists
2286
2311
  virtual bool operator==(const Expression& rhs) const;
2312
+ virtual std::string to_string(bool compressed = false, int precision = 5) const;
2287
2313
  ATTACH_OPERATIONS()
2288
2314
  };
2289
2315
 
@@ -44,4 +44,12 @@ public:\
44
44
  type name(type name##__) { return name##_ = name##__; }\
45
45
  private:
46
46
 
47
+ #define ADD_HASHED(type, name)\
48
+ protected:\
49
+ type name##_;\
50
+ public:\
51
+ type name() const { return name##_; }\
52
+ type name(type name##__) { hash_ = 0; return name##_ = name##__; }\
53
+ private:
54
+
47
55
  #endif
@@ -6,8 +6,6 @@
6
6
  /////////////////////////////////////////////
7
7
  namespace Sass {
8
8
 
9
- enum Output_Style { NESTED, EXPANDED, COMPACT, COMPRESSED, FORMATTED };
10
-
11
9
  class AST_Node;
12
10
  // statements
13
11
  class Statement;
@@ -85,6 +83,9 @@ namespace Sass {
85
83
  class Complex_Selector;
86
84
  class Selector_List;
87
85
 
86
+ // common classes
87
+ class Context;
88
+
88
89
  }
89
90
 
90
91
  #endif
@@ -33,7 +33,7 @@ namespace Sass {
33
33
  while (this_point->parent) {
34
34
 
35
35
  // make path relative to the current directory
36
- std::string rel_path(Sass::File::resolve_relative_path(this_point->pstate.path, cwd, cwd));
36
+ std::string rel_path(Sass::File::abs2rel(this_point->pstate.path, cwd, cwd));
37
37
 
38
38
  if (warning) {
39
39
  ss << std::endl
@@ -9,9 +9,10 @@
9
9
 
10
10
  namespace Sass {
11
11
 
12
- void bind(std::string callee, Parameters* ps, Arguments* as, Context& ctx, Env* env, Eval* eval)
12
+ void bind(std::string type, std::string name, Parameters* ps, Arguments* as, Context* ctx, Env* env, Eval* eval)
13
13
  {
14
- Listize listize(ctx);
14
+ std::string callee(type + " " + name);
15
+ Listize listize(*ctx);
15
16
  std::map<std::string, Parameter*> param_map;
16
17
 
17
18
  for (size_t i = 0, L = as->length(); i < L; ++i) {
@@ -49,9 +50,9 @@ namespace Sass {
49
50
  }
50
51
  }
51
52
  std::stringstream msg;
52
- msg << callee << " only takes " << LP << " arguments; "
53
- << "given " << LA;
54
- error(msg.str(), as->pstate());
53
+ msg << "wrong number of arguments (" << LA << " for " << LP << ")";
54
+ msg << " for `" << name << "'";
55
+ return error(msg.str(), as->pstate());
55
56
  }
56
57
  Parameter* p = (*ps)[ip];
57
58
 
@@ -72,14 +73,14 @@ namespace Sass {
72
73
  // otherwise we will not be able to fetch it again
73
74
  else {
74
75
  // create a new list object for wrapped items
75
- List* arglist = SASS_MEMORY_NEW(ctx.mem, List,
76
+ List* arglist = SASS_MEMORY_NEW(ctx->mem, List,
76
77
  p->pstate(),
77
78
  0,
78
79
  rest->separator(),
79
80
  true);
80
81
  // wrap each item from list as an argument
81
82
  for (Expression* item : rest->elements()) {
82
- (*arglist) << SASS_MEMORY_NEW(ctx.mem, Argument,
83
+ (*arglist) << SASS_MEMORY_NEW(ctx->mem, Argument,
83
84
  item->pstate(),
84
85
  item,
85
86
  "",
@@ -97,12 +98,12 @@ namespace Sass {
97
98
  } else if (a->is_keyword_argument()) {
98
99
 
99
100
  // expand keyword arguments into their parameters
100
- List* arglist = SASS_MEMORY_NEW(ctx.mem, List, p->pstate(), 0, SASS_COMMA, true);
101
+ List* arglist = SASS_MEMORY_NEW(ctx->mem, List, p->pstate(), 0, SASS_COMMA, true);
101
102
  env->local_frame()[p->name()] = arglist;
102
103
  Map* argmap = static_cast<Map*>(a->value());
103
104
  for (auto key : argmap->keys()) {
104
105
  std::string name = unquote(static_cast<String_Constant*>(key)->value());
105
- (*arglist) << SASS_MEMORY_NEW(ctx.mem, Argument,
106
+ (*arglist) << SASS_MEMORY_NEW(ctx->mem, Argument,
106
107
  key->pstate(),
107
108
  argmap->at(key),
108
109
  "$" + name,
@@ -113,7 +114,7 @@ namespace Sass {
113
114
  } else {
114
115
 
115
116
  // create a new list object for wrapped items
116
- List* arglist = SASS_MEMORY_NEW(ctx.mem, List,
117
+ List* arglist = SASS_MEMORY_NEW(ctx->mem, List,
117
118
  p->pstate(),
118
119
  0,
119
120
  SASS_COMMA,
@@ -131,11 +132,11 @@ namespace Sass {
131
132
  for (size_t i = 0, L = ls->size(); i < L; ++i) {
132
133
  // already have a wrapped argument
133
134
  if (Argument* arg = dynamic_cast<Argument*>((*ls)[i])) {
134
- (*arglist) << SASS_MEMORY_NEW(ctx.mem, Argument, *arg);
135
+ (*arglist) << SASS_MEMORY_NEW(ctx->mem, Argument, *arg);
135
136
  }
136
137
  // wrap all other value types into Argument
137
138
  else {
138
- (*arglist) << SASS_MEMORY_NEW(ctx.mem, Argument,
139
+ (*arglist) << SASS_MEMORY_NEW(ctx->mem, Argument,
139
140
  (*ls)[i]->pstate(),
140
141
  (*ls)[i],
141
142
  "",
@@ -146,11 +147,11 @@ namespace Sass {
146
147
  }
147
148
  // already have a wrapped argument
148
149
  else if (Argument* arg = dynamic_cast<Argument*>(a->value())) {
149
- (*arglist) << SASS_MEMORY_NEW(ctx.mem, Argument, *arg);
150
+ (*arglist) << SASS_MEMORY_NEW(ctx->mem, Argument, *arg);
150
151
  }
151
152
  // wrap all other value types into Argument
152
153
  else {
153
- (*arglist) << SASS_MEMORY_NEW(ctx.mem, Argument,
154
+ (*arglist) << SASS_MEMORY_NEW(ctx->mem, Argument,
154
155
  a->pstate(),
155
156
  a->value(),
156
157
  a->name(),
@@ -183,11 +184,21 @@ namespace Sass {
183
184
  // empty rest arg - treat all args as default values
184
185
  if (!arglist->length()) {
185
186
  break;
187
+ } else {
188
+ if (arglist->length() + ia > LP && !ps->has_rest_parameter()) {
189
+ int arg_count = (arglist->length() + LA - 1);
190
+ std::stringstream msg;
191
+ msg << callee << " takes " << LP;
192
+ msg << (LP == 1 ? " argument" : " arguments");
193
+ msg << " but " << arg_count;
194
+ msg << (arg_count == 1 ? " was passed" : " were passed.");
195
+ deprecated_bind(msg.str(), as->pstate());
196
+ }
186
197
  }
187
198
  // otherwise move one of the rest args into the param, converting to argument if necessary
188
199
  if (!(a = dynamic_cast<Argument*>((*arglist)[0]))) {
189
200
  Expression* a_to_convert = (*arglist)[0];
190
- a = SASS_MEMORY_NEW(ctx.mem, Argument,
201
+ a = SASS_MEMORY_NEW(ctx->mem, Argument,
191
202
  a_to_convert->pstate(),
192
203
  a_to_convert,
193
204
  "",
@@ -256,14 +267,14 @@ namespace Sass {
256
267
  // That's only okay if they have default values, or were already bound by
257
268
  // named arguments, or if it's a single rest-param.
258
269
  for (size_t i = ip; i < LP; ++i) {
259
- To_String to_string(&ctx);
270
+ To_String to_string(ctx);
260
271
  Parameter* leftover = (*ps)[i];
261
272
  // cerr << "env for default params:" << endl;
262
273
  // env->print();
263
274
  // cerr << "********" << endl;
264
275
  if (!env->has_local(leftover->name())) {
265
276
  if (leftover->is_rest_parameter()) {
266
- env->local_frame()[leftover->name()] = SASS_MEMORY_NEW(ctx.mem, List,
277
+ env->local_frame()[leftover->name()] = SASS_MEMORY_NEW(ctx->mem, List,
267
278
  leftover->pstate(),
268
279
  0,
269
280
  SASS_COMMA,