sassc 1.8.3 → 1.8.4

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/.editorconfig +1 -1
  4. data/ext/libsass/.gitignore +1 -0
  5. data/ext/libsass/LICENSE +1 -1
  6. data/ext/libsass/Makefile +20 -14
  7. data/ext/libsass/Makefile.conf +0 -1
  8. data/ext/libsass/Readme.md +3 -1
  9. data/ext/libsass/appveyor.yml +19 -11
  10. data/ext/libsass/docs/api-importer-example.md +2 -1235
  11. data/ext/libsass/docs/build-with-autotools.md +10 -0
  12. data/ext/libsass/docs/build-with-makefiles.md +18 -0
  13. data/ext/libsass/include/sass/base.h +4 -1
  14. data/ext/libsass/include/sass/values.h +2 -1
  15. data/ext/libsass/src/ast.cpp +279 -346
  16. data/ext/libsass/src/ast.hpp +234 -60
  17. data/ext/libsass/src/base64vlq.cpp +1 -0
  18. data/ext/libsass/src/bind.cpp +35 -45
  19. data/ext/libsass/src/bind.hpp +1 -0
  20. data/ext/libsass/src/color_maps.cpp +1 -0
  21. data/ext/libsass/src/constants.cpp +4 -1
  22. data/ext/libsass/src/constants.hpp +2 -1
  23. data/ext/libsass/src/context.cpp +41 -31
  24. data/ext/libsass/src/context.hpp +10 -10
  25. data/ext/libsass/src/cssize.cpp +7 -4
  26. data/ext/libsass/src/cssize.hpp +1 -3
  27. data/ext/libsass/src/debugger.hpp +73 -14
  28. data/ext/libsass/src/emitter.cpp +37 -25
  29. data/ext/libsass/src/emitter.hpp +10 -9
  30. data/ext/libsass/src/environment.cpp +16 -5
  31. data/ext/libsass/src/environment.hpp +5 -3
  32. data/ext/libsass/src/error_handling.cpp +91 -14
  33. data/ext/libsass/src/error_handling.hpp +105 -4
  34. data/ext/libsass/src/eval.cpp +519 -330
  35. data/ext/libsass/src/eval.hpp +12 -13
  36. data/ext/libsass/src/expand.cpp +92 -56
  37. data/ext/libsass/src/expand.hpp +5 -3
  38. data/ext/libsass/src/extend.cpp +60 -51
  39. data/ext/libsass/src/extend.hpp +1 -3
  40. data/ext/libsass/src/file.cpp +37 -27
  41. data/ext/libsass/src/functions.cpp +78 -62
  42. data/ext/libsass/src/functions.hpp +1 -0
  43. data/ext/libsass/src/inspect.cpp +293 -64
  44. data/ext/libsass/src/inspect.hpp +2 -0
  45. data/ext/libsass/src/lexer.cpp +1 -0
  46. data/ext/libsass/src/listize.cpp +14 -15
  47. data/ext/libsass/src/listize.hpp +3 -5
  48. data/ext/libsass/src/memory_manager.cpp +1 -0
  49. data/ext/libsass/src/node.cpp +2 -3
  50. data/ext/libsass/src/operation.hpp +70 -71
  51. data/ext/libsass/src/output.cpp +28 -32
  52. data/ext/libsass/src/output.hpp +1 -2
  53. data/ext/libsass/src/parser.cpp +402 -183
  54. data/ext/libsass/src/parser.hpp +19 -9
  55. data/ext/libsass/src/plugins.cpp +1 -0
  56. data/ext/libsass/src/position.cpp +1 -0
  57. data/ext/libsass/src/prelexer.cpp +134 -56
  58. data/ext/libsass/src/prelexer.hpp +51 -3
  59. data/ext/libsass/src/remove_placeholders.cpp +35 -9
  60. data/ext/libsass/src/remove_placeholders.hpp +4 -3
  61. data/ext/libsass/src/sass.cpp +1 -0
  62. data/ext/libsass/src/sass.hpp +129 -0
  63. data/ext/libsass/src/sass_context.cpp +31 -14
  64. data/ext/libsass/src/sass_context.hpp +2 -31
  65. data/ext/libsass/src/sass_functions.cpp +1 -0
  66. data/ext/libsass/src/sass_interface.cpp +5 -6
  67. data/ext/libsass/src/sass_util.cpp +1 -2
  68. data/ext/libsass/src/sass_util.hpp +5 -5
  69. data/ext/libsass/src/sass_values.cpp +13 -10
  70. data/ext/libsass/src/source_map.cpp +4 -3
  71. data/ext/libsass/src/source_map.hpp +2 -2
  72. data/ext/libsass/src/subset_map.hpp +0 -1
  73. data/ext/libsass/src/to_c.cpp +1 -0
  74. data/ext/libsass/src/to_c.hpp +1 -3
  75. data/ext/libsass/src/to_value.cpp +3 -5
  76. data/ext/libsass/src/to_value.hpp +1 -1
  77. data/ext/libsass/src/units.cpp +96 -59
  78. data/ext/libsass/src/units.hpp +10 -8
  79. data/ext/libsass/src/utf8_string.cpp +5 -0
  80. data/ext/libsass/src/util.cpp +23 -156
  81. data/ext/libsass/src/util.hpp +10 -14
  82. data/ext/libsass/src/values.cpp +1 -0
  83. data/ext/libsass/test/test_node.cpp +2 -6
  84. data/ext/libsass/test/test_selector_difference.cpp +1 -3
  85. data/ext/libsass/test/test_specificity.cpp +0 -2
  86. data/ext/libsass/test/test_superselector.cpp +0 -2
  87. data/ext/libsass/test/test_unification.cpp +1 -3
  88. data/ext/libsass/win/libsass.targets +18 -5
  89. data/ext/libsass/win/libsass.vcxproj +9 -7
  90. data/ext/libsass/win/libsass.vcxproj.filters +148 -106
  91. data/lib/sassc/version.rb +1 -1
  92. data/test/engine_test.rb +12 -0
  93. data/test/native_test.rb +1 -1
  94. metadata +3 -4
  95. data/ext/libsass/src/to_string.cpp +0 -48
  96. data/ext/libsass/src/to_string.hpp +0 -38
@@ -44,15 +44,29 @@
44
44
  #include "error_handling.hpp"
45
45
  #include "ast_def_macros.hpp"
46
46
  #include "ast_fwd_decl.hpp"
47
- #include "to_string.hpp"
48
47
  #include "source_map.hpp"
49
48
 
50
49
  #include "sass.h"
51
50
 
52
51
  namespace Sass {
53
52
 
53
+ // ToDo: should this really be hardcoded
54
+ // Note: most methods follow precision option
54
55
  const double NUMBER_EPSILON = 0.00000000000001;
55
56
 
57
+ // ToDo: where does this fit best?
58
+ // We don't share this with C-API?
59
+ class Operand {
60
+ public:
61
+ Operand(Sass_OP operand, bool ws_before = false, bool ws_after = false)
62
+ : operand(operand), ws_before(ws_before), ws_after(ws_after)
63
+ { }
64
+ public:
65
+ enum Sass_OP operand;
66
+ bool ws_before;
67
+ bool ws_after;
68
+ };
69
+
56
70
  // from boost (functional/hash):
57
71
  // http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html
58
72
  // Boost Software License - Version 1.0
@@ -74,6 +88,11 @@ namespace Sass {
74
88
  : pstate_(pstate)
75
89
  { }
76
90
  virtual ~AST_Node() = 0;
91
+ virtual size_t hash() { return 0; }
92
+ virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
93
+ virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
94
+ virtual std::string to_string(Sass_Inspect_Options opt) const;
95
+ virtual std::string to_string() const;
77
96
  // virtual Block* block() { return 0; }
78
97
  public:
79
98
  void update_pstate(const ParserState& pstate);
@@ -129,9 +148,26 @@ namespace Sass {
129
148
  virtual bool is_false() { return false; }
130
149
  virtual bool operator== (const Expression& rhs) const { return false; }
131
150
  virtual void set_delayed(bool delayed) { is_delayed(delayed); }
151
+ virtual bool has_interpolant() const { return is_interpolant(); }
152
+ virtual bool is_left_interpolant() const { return is_interpolant(); }
153
+ virtual bool is_right_interpolant() const { return is_interpolant(); }
154
+ virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
155
+ virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
132
156
  virtual size_t hash() { return 0; }
133
157
  };
134
158
 
159
+ //////////////////////////////////////////////////////////////////////
160
+ // Still just an expression, but with a to_string method
161
+ //////////////////////////////////////////////////////////////////////
162
+ class PreValue : public Expression {
163
+ public:
164
+ PreValue(ParserState pstate,
165
+ bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
166
+ : Expression(pstate, d, e, i, ct)
167
+ { }
168
+ virtual ~PreValue() { }
169
+ };
170
+
135
171
  //////////////////////////////////////////////////////////////////////
136
172
  // base class for values that support operations
137
173
  //////////////////////////////////////////////////////////////////////
@@ -142,7 +178,6 @@ namespace Sass {
142
178
  : Expression(pstate, d, e, i, ct)
143
179
  { }
144
180
  virtual bool operator== (const Expression& rhs) const = 0;
145
- virtual std::string to_string(bool compressed = false, int precision = 5) const = 0;
146
181
  };
147
182
  }
148
183
 
@@ -189,8 +224,8 @@ namespace Sass {
189
224
  virtual ~Vectorized() = 0;
190
225
  size_t length() const { return elements_.size(); }
191
226
  bool empty() const { return elements_.empty(); }
192
- T last() { return elements_.back(); }
193
- T first() { return elements_.front(); }
227
+ T last() const { return elements_.back(); }
228
+ T first() const { return elements_.front(); }
194
229
  T& operator[](size_t i) { return elements_[i]; }
195
230
  virtual const T& at(size_t i) const { return elements_.at(i); }
196
231
  const T& operator[](size_t i) const { return elements_[i]; }
@@ -216,6 +251,16 @@ namespace Sass {
216
251
  const std::vector<T>& elements() const { return elements_; }
217
252
  std::vector<T>& elements(std::vector<T>& e) { elements_ = e; return elements_; }
218
253
 
254
+ virtual size_t hash()
255
+ {
256
+ if (hash_ == 0) {
257
+ for (T& el : elements_) {
258
+ hash_combine(hash_, el->hash());
259
+ }
260
+ }
261
+ return hash_;
262
+ }
263
+
219
264
  typename std::vector<T>::iterator end() { return elements_.end(); }
220
265
  typename std::vector<T>::iterator begin() { return elements_.begin(); }
221
266
  typename std::vector<T>::const_iterator end() const { return elements_.end(); }
@@ -820,8 +865,8 @@ namespace Sass {
820
865
  std::string type() { return is_arglist_ ? "arglist" : "list"; }
821
866
  static std::string type_name() { return "list"; }
822
867
  const char* sep_string(bool compressed = false) const {
823
- return separator() == SASS_COMMA ?
824
- (compressed ? "," : ", ") : " ";
868
+ return separator() == SASS_SPACE ?
869
+ " " : (compressed ? "," : ", ");
825
870
  }
826
871
  bool is_invisible() const { return empty(); }
827
872
  Expression* value_at_index(size_t i);
@@ -846,7 +891,6 @@ namespace Sass {
846
891
  }
847
892
 
848
893
  virtual bool operator== (const Expression& rhs) const;
849
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
850
894
 
851
895
  ATTACH_OPERATIONS()
852
896
  };
@@ -879,29 +923,49 @@ namespace Sass {
879
923
  }
880
924
 
881
925
  virtual bool operator== (const Expression& rhs) const;
882
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
883
926
 
884
927
  ATTACH_OPERATIONS()
885
928
  };
886
929
 
930
+ inline static const std::string sass_op_to_name(enum Sass_OP op) {
931
+ switch (op) {
932
+ case AND: return "and"; break;
933
+ case OR: return "or"; break;
934
+ case EQ: return "eq"; break;
935
+ case NEQ: return "neq"; break;
936
+ case GT: return "gt"; break;
937
+ case GTE: return "gte"; break;
938
+ case LT: return "lt"; break;
939
+ case LTE: return "lte"; break;
940
+ case ADD: return "plus"; break;
941
+ case SUB: return "sub"; break;
942
+ case MUL: return "times"; break;
943
+ case DIV: return "div"; break;
944
+ case MOD: return "mod"; break;
945
+ // this is only used internally!
946
+ case NUM_OPS: return "[OPS]"; break;
947
+ default: return "invalid"; break;
948
+ }
949
+ }
950
+
887
951
  //////////////////////////////////////////////////////////////////////////
888
952
  // Binary expressions. Represents logical, relational, and arithmetic
889
953
  // operations. Templatized to avoid large switch statements and repetitive
890
954
  // subclassing.
891
955
  //////////////////////////////////////////////////////////////////////////
892
- class Binary_Expression : public Expression {
956
+ class Binary_Expression : public PreValue {
893
957
  private:
894
- ADD_HASHED(enum Sass_OP, type)
958
+ ADD_HASHED(Operand, op)
895
959
  ADD_HASHED(Expression*, left)
896
960
  ADD_HASHED(Expression*, right)
897
961
  size_t hash_;
898
962
  public:
899
963
  Binary_Expression(ParserState pstate,
900
- enum Sass_OP t, Expression* lhs, Expression* rhs)
901
- : Expression(pstate), type_(t), left_(lhs), right_(rhs), hash_(0)
964
+ Operand op, Expression* lhs, Expression* rhs)
965
+ : PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)
902
966
  { }
903
967
  const std::string type_name() {
904
- switch (type_) {
968
+ switch (type()) {
905
969
  case AND: return "and"; break;
906
970
  case OR: return "or"; break;
907
971
  case EQ: return "eq"; break;
@@ -915,10 +979,38 @@ namespace Sass {
915
979
  case MUL: return "mul"; break;
916
980
  case DIV: return "div"; break;
917
981
  case MOD: return "mod"; break;
918
- case NUM_OPS: return "num_ops"; break;
982
+ // this is only used internally!
983
+ case NUM_OPS: return "[OPS]"; break;
984
+ default: return "invalid"; break;
985
+ }
986
+ }
987
+ const std::string separator() {
988
+ switch (type()) {
989
+ case AND: return "&&"; break;
990
+ case OR: return "||"; break;
991
+ case EQ: return "=="; break;
992
+ case NEQ: return "!="; break;
993
+ case GT: return ">"; break;
994
+ case GTE: return ">="; break;
995
+ case LT: return "<"; break;
996
+ case LTE: return "<="; break;
997
+ case ADD: return "+"; break;
998
+ case SUB: return "-"; break;
999
+ case MUL: return "*"; break;
1000
+ case DIV: return "/"; break;
1001
+ case MOD: return "%"; break;
1002
+ // this is only used internally!
1003
+ case NUM_OPS: return "[OPS]"; break;
919
1004
  default: return "invalid"; break;
920
1005
  }
921
1006
  }
1007
+ bool is_left_interpolant(void) const;
1008
+ bool is_right_interpolant(void) const;
1009
+ bool has_interpolant() const
1010
+ {
1011
+ return is_left_interpolant() ||
1012
+ is_right_interpolant();
1013
+ }
922
1014
  virtual void set_delayed(bool delayed)
923
1015
  {
924
1016
  right()->set_delayed(delayed);
@@ -944,12 +1036,13 @@ namespace Sass {
944
1036
  virtual size_t hash()
945
1037
  {
946
1038
  if (hash_ == 0) {
947
- hash_ = std::hash<size_t>()(type_);
1039
+ hash_ = std::hash<size_t>()(type());
948
1040
  hash_combine(hash_, left()->hash());
949
1041
  hash_combine(hash_, right()->hash());
950
1042
  }
951
1043
  return hash_;
952
1044
  }
1045
+ enum Sass_OP type() const { return op_.operand; }
953
1046
  ATTACH_OPERATIONS()
954
1047
  };
955
1048
 
@@ -1065,23 +1158,27 @@ namespace Sass {
1065
1158
  has_rest_argument_(false),
1066
1159
  has_keyword_argument_(false)
1067
1160
  { }
1161
+
1162
+ Argument* get_rest_argument();
1163
+ Argument* get_keyword_argument();
1164
+
1068
1165
  ATTACH_OPERATIONS()
1069
1166
  };
1070
1167
 
1071
1168
  //////////////////
1072
1169
  // Function calls.
1073
1170
  //////////////////
1074
- class Function_Call : public Expression {
1171
+ class Function_Call : public PreValue {
1075
1172
  ADD_HASHED(std::string, name)
1076
1173
  ADD_HASHED(Arguments*, arguments)
1077
1174
  ADD_PROPERTY(void*, cookie)
1078
1175
  size_t hash_;
1079
1176
  public:
1080
1177
  Function_Call(ParserState pstate, std::string n, Arguments* args, void* cookie)
1081
- : Expression(pstate), name_(n), arguments_(args), cookie_(cookie), hash_(0)
1178
+ : PreValue(pstate), name_(n), arguments_(args), cookie_(cookie), hash_(0)
1082
1179
  { concrete_type(STRING); }
1083
1180
  Function_Call(ParserState pstate, std::string n, Arguments* args)
1084
- : Expression(pstate), name_(n), arguments_(args), cookie_(0), hash_(0)
1181
+ : PreValue(pstate), name_(n), arguments_(args), cookie_(0), hash_(0)
1085
1182
  { concrete_type(STRING); }
1086
1183
 
1087
1184
  virtual bool operator==(const Expression& rhs) const
@@ -1131,11 +1228,11 @@ namespace Sass {
1131
1228
  ///////////////////////
1132
1229
  // Variable references.
1133
1230
  ///////////////////////
1134
- class Variable : public Expression {
1231
+ class Variable : public PreValue {
1135
1232
  ADD_PROPERTY(std::string, name)
1136
1233
  public:
1137
1234
  Variable(ParserState pstate, std::string n)
1138
- : Expression(pstate), name_(n)
1235
+ : PreValue(pstate), name_(n)
1139
1236
  { }
1140
1237
 
1141
1238
  virtual bool operator==(const Expression& rhs) const
@@ -1214,7 +1311,8 @@ namespace Sass {
1214
1311
  size_t hash_;
1215
1312
  public:
1216
1313
  Number(ParserState pstate, double val, std::string u = "", bool zero = true);
1217
- bool zero() { return zero_; }
1314
+ bool zero() { return zero_; }
1315
+ bool is_valid_css_unit() const;
1218
1316
  std::vector<std::string>& numerator_units() { return numerator_units_; }
1219
1317
  std::vector<std::string>& denominator_units() { return denominator_units_; }
1220
1318
  const std::vector<std::string>& numerator_units() const { return numerator_units_; }
@@ -1223,8 +1321,9 @@ namespace Sass {
1223
1321
  static std::string type_name() { return "number"; }
1224
1322
  std::string unit() const;
1225
1323
 
1226
- bool is_unitless();
1227
- void convert(const std::string& unit = "", bool strict = false);
1324
+ bool is_unitless() const;
1325
+ double convert_factor(const Number&) const;
1326
+ bool convert(const std::string& unit = "", bool strict = false);
1228
1327
  void normalize(const std::string& unit = "", bool strict = false);
1229
1328
  // useful for making one number compatible with another
1230
1329
  std::string find_convertible_unit() const;
@@ -1243,7 +1342,6 @@ namespace Sass {
1243
1342
 
1244
1343
  virtual bool operator< (const Number& rhs) const;
1245
1344
  virtual bool operator== (const Expression& rhs) const;
1246
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1247
1345
 
1248
1346
  ATTACH_OPERATIONS()
1249
1347
  };
@@ -1256,12 +1354,11 @@ namespace Sass {
1256
1354
  ADD_HASHED(double, g)
1257
1355
  ADD_HASHED(double, b)
1258
1356
  ADD_HASHED(double, a)
1259
- ADD_PROPERTY(bool, sixtuplet)
1260
1357
  ADD_PROPERTY(std::string, disp)
1261
1358
  size_t hash_;
1262
1359
  public:
1263
- Color(ParserState pstate, double r, double g, double b, double a = 1, bool sixtuplet = true, const std::string disp = "")
1264
- : Value(pstate), r_(r), g_(g), b_(b), a_(a), sixtuplet_(sixtuplet), disp_(disp),
1360
+ Color(ParserState pstate, double r, double g, double b, double a = 1, const std::string disp = "")
1361
+ : Value(pstate), r_(r), g_(g), b_(b), a_(a), disp_(disp),
1265
1362
  hash_(0)
1266
1363
  { concrete_type(COLOR); }
1267
1364
  std::string type() { return "color"; }
@@ -1279,7 +1376,6 @@ namespace Sass {
1279
1376
  }
1280
1377
 
1281
1378
  virtual bool operator== (const Expression& rhs) const;
1282
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1283
1379
 
1284
1380
  ATTACH_OPERATIONS()
1285
1381
  };
@@ -1294,7 +1390,6 @@ namespace Sass {
1294
1390
  : Value(pstate), message_(msg)
1295
1391
  { concrete_type(C_ERROR); }
1296
1392
  virtual bool operator== (const Expression& rhs) const;
1297
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1298
1393
  ATTACH_OPERATIONS()
1299
1394
  };
1300
1395
 
@@ -1308,7 +1403,6 @@ namespace Sass {
1308
1403
  : Value(pstate), message_(msg)
1309
1404
  { concrete_type(C_WARNING); }
1310
1405
  virtual bool operator== (const Expression& rhs) const;
1311
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1312
1406
  ATTACH_OPERATIONS()
1313
1407
  };
1314
1408
 
@@ -1337,7 +1431,6 @@ namespace Sass {
1337
1431
  }
1338
1432
 
1339
1433
  virtual bool operator== (const Expression& rhs) const;
1340
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1341
1434
 
1342
1435
  ATTACH_OPERATIONS()
1343
1436
  };
@@ -1355,7 +1448,6 @@ namespace Sass {
1355
1448
  static std::string type_name() { return "string"; }
1356
1449
  virtual ~String() = 0;
1357
1450
  virtual bool operator==(const Expression& rhs) const = 0;
1358
- virtual std::string to_string(bool compressed = false, int precision = 5) const = 0;
1359
1451
  ATTACH_OPERATIONS()
1360
1452
  };
1361
1453
  inline String::~String() { };
@@ -1365,15 +1457,25 @@ namespace Sass {
1365
1457
  // evaluation phase.
1366
1458
  ///////////////////////////////////////////////////////////////////////
1367
1459
  class String_Schema : public String, public Vectorized<Expression*> {
1368
- ADD_PROPERTY(bool, has_interpolants)
1460
+ // ADD_PROPERTY(bool, has_interpolants)
1369
1461
  size_t hash_;
1370
1462
  public:
1371
1463
  String_Schema(ParserState pstate, size_t size = 0, bool has_interpolants = false)
1372
- : String(pstate), Vectorized<Expression*>(size), has_interpolants_(has_interpolants), hash_(0)
1464
+ : String(pstate), Vectorized<Expression*>(size), hash_(0)
1373
1465
  { concrete_type(STRING); }
1374
1466
  std::string type() { return "string"; }
1375
1467
  static std::string type_name() { return "string"; }
1376
1468
 
1469
+ bool is_left_interpolant(void) const;
1470
+ bool is_right_interpolant(void) const;
1471
+ // void has_interpolants(bool tc) { }
1472
+ bool has_interpolants() {
1473
+ for (auto el : elements()) {
1474
+ if (el->is_interpolant()) return true;
1475
+ }
1476
+ return false;
1477
+ }
1478
+
1377
1479
  virtual size_t hash()
1378
1480
  {
1379
1481
  if (hash_ == 0) {
@@ -1384,7 +1486,6 @@ namespace Sass {
1384
1486
  }
1385
1487
 
1386
1488
  virtual bool operator==(const Expression& rhs) const;
1387
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1388
1489
 
1389
1490
  ATTACH_OPERATIONS()
1390
1491
  };
@@ -1423,7 +1524,7 @@ namespace Sass {
1423
1524
  }
1424
1525
 
1425
1526
  virtual bool operator==(const Expression& rhs) const;
1426
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1527
+ virtual std::string inspect() const; // quotes are forced on inspection
1427
1528
 
1428
1529
  // static char auto_quote() { return '*'; }
1429
1530
  static char double_quote() { return '"'; }
@@ -1444,7 +1545,7 @@ namespace Sass {
1444
1545
  if (q && quote_mark_) quote_mark_ = q;
1445
1546
  }
1446
1547
  virtual bool operator==(const Expression& rhs) const;
1447
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1548
+ virtual std::string inspect() const; // quotes are forced on inspection
1448
1549
  ATTACH_OPERATIONS()
1449
1550
  };
1450
1551
 
@@ -1581,8 +1682,7 @@ namespace Sass {
1581
1682
  { }
1582
1683
  bool exclude(std::string str)
1583
1684
  {
1584
- To_String to_string;
1585
- bool with = feature() && unquote(feature()->perform(&to_string)).compare("with") == 0;
1685
+ bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
1586
1686
  List* l = static_cast<List*>(value());
1587
1687
  std::string v;
1588
1688
 
@@ -1591,7 +1691,7 @@ namespace Sass {
1591
1691
  if (!l || l->length() == 0) return str.compare("rule") != 0;
1592
1692
  for (size_t i = 0, L = l->length(); i < L; ++i)
1593
1693
  {
1594
- v = unquote((*l)[i]->perform(&to_string));
1694
+ v = unquote((*l)[i]->to_string());
1595
1695
  if (v.compare("all") == 0 || v == str) return false;
1596
1696
  }
1597
1697
  return true;
@@ -1601,7 +1701,7 @@ namespace Sass {
1601
1701
  if (!l || !l->length()) return str.compare("rule") == 0;
1602
1702
  for (size_t i = 0, L = l->length(); i < L; ++i)
1603
1703
  {
1604
- v = unquote((*l)[i]->perform(&to_string));
1704
+ v = unquote((*l)[i]->to_string());
1605
1705
  if (v.compare("all") == 0 || v == str) return true;
1606
1706
  }
1607
1707
  return false;
@@ -1665,7 +1765,6 @@ namespace Sass {
1665
1765
  }
1666
1766
 
1667
1767
  virtual bool operator== (const Expression& rhs) const;
1668
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1669
1768
 
1670
1769
  ATTACH_OPERATIONS()
1671
1770
  };
@@ -1747,7 +1846,7 @@ namespace Sass {
1747
1846
  // Abstract base class for CSS selectors.
1748
1847
  /////////////////////////////////////////
1749
1848
  class Selector : public Expression {
1750
- ADD_PROPERTY(bool, has_reference)
1849
+ // ADD_PROPERTY(bool, has_reference)
1751
1850
  ADD_PROPERTY(bool, has_placeholder)
1752
1851
  // line break before list separator
1753
1852
  ADD_PROPERTY(bool, has_line_feed)
@@ -1757,21 +1856,27 @@ namespace Sass {
1757
1856
  ADD_PROPERTY(bool, is_optional)
1758
1857
  // parent block pointers
1759
1858
  ADD_PROPERTY(Media_Block*, media_block)
1859
+ protected:
1860
+ size_t hash_;
1760
1861
  public:
1761
1862
  Selector(ParserState pstate, bool r = false, bool h = false)
1762
1863
  : Expression(pstate),
1763
- has_reference_(r),
1864
+ // has_reference_(r),
1764
1865
  has_placeholder_(h),
1765
1866
  has_line_feed_(false),
1766
1867
  has_line_break_(false),
1767
1868
  is_optional_(false),
1768
- media_block_(0)
1869
+ media_block_(0),
1870
+ hash_(0)
1769
1871
  { concrete_type(SELECTOR); }
1770
1872
  virtual ~Selector() = 0;
1873
+ virtual size_t hash() = 0;
1874
+ virtual bool has_parent_ref() {
1875
+ return false;
1876
+ }
1771
1877
  virtual unsigned long specificity() {
1772
1878
  return Constants::Specificity_Universal;
1773
1879
  }
1774
- virtual std::string to_string(bool compressed = false, int precision = 5) const = 0;
1775
1880
  };
1776
1881
  inline Selector::~Selector() { }
1777
1882
 
@@ -1786,7 +1891,12 @@ namespace Sass {
1786
1891
  Selector_Schema(ParserState pstate, String* c)
1787
1892
  : Selector(pstate), contents_(c), at_root_(false)
1788
1893
  { }
1789
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1894
+ virtual size_t hash() {
1895
+ if (hash_ == 0) {
1896
+ hash_combine(hash_, contents_->hash());
1897
+ }
1898
+ return hash_;
1899
+ }
1790
1900
  ATTACH_OPERATIONS()
1791
1901
  };
1792
1902
 
@@ -1816,6 +1926,15 @@ namespace Sass {
1816
1926
  name += ns_ + "|";
1817
1927
  return name + name_;
1818
1928
  }
1929
+ virtual size_t hash()
1930
+ {
1931
+ if (hash_ == 0) {
1932
+ hash_combine(hash_, std::hash<int>()(SELECTOR));
1933
+ hash_combine(hash_, std::hash<std::string>()(ns()));
1934
+ hash_combine(hash_, std::hash<std::string>()(name()));
1935
+ }
1936
+ return hash_;
1937
+ }
1819
1938
  // namespace query functions
1820
1939
  bool is_universal_ns() const
1821
1940
  {
@@ -1856,7 +1975,6 @@ namespace Sass {
1856
1975
 
1857
1976
  bool operator<(const Simple_Selector& rhs) const;
1858
1977
  // 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(); };
1860
1978
  ATTACH_OPERATIONS();
1861
1979
  };
1862
1980
  inline Simple_Selector::~Simple_Selector() { }
@@ -1872,7 +1990,7 @@ namespace Sass {
1872
1990
  public:
1873
1991
  Parent_Selector(ParserState pstate)
1874
1992
  : Simple_Selector(pstate, "&")
1875
- { has_reference(true); }
1993
+ { /* has_reference(true); */ }
1876
1994
  virtual bool has_parent_ref() { return true; };
1877
1995
  virtual unsigned long specificity()
1878
1996
  {
@@ -1880,7 +1998,6 @@ namespace Sass {
1880
1998
  }
1881
1999
  std::string type() { return "selector"; }
1882
2000
  static std::string type_name() { return "selector"; }
1883
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1884
2001
  ATTACH_OPERATIONS()
1885
2002
  };
1886
2003
 
@@ -1944,6 +2061,15 @@ namespace Sass {
1944
2061
  Attribute_Selector(ParserState pstate, std::string n, std::string m, String* v)
1945
2062
  : Simple_Selector(pstate, n), matcher_(m), value_(v)
1946
2063
  { }
2064
+ virtual size_t hash()
2065
+ {
2066
+ if (hash_ == 0) {
2067
+ hash_combine(hash_, Simple_Selector::hash());
2068
+ hash_combine(hash_, std::hash<std::string>()(matcher()));
2069
+ if (value_) hash_combine(hash_, value_->hash());
2070
+ }
2071
+ return hash_;
2072
+ }
1947
2073
  virtual unsigned long specificity()
1948
2074
  {
1949
2075
  return Constants::Specificity_Attr;
@@ -1952,7 +2078,6 @@ namespace Sass {
1952
2078
  bool operator==(const Attribute_Selector& rhs) const;
1953
2079
  bool operator<(const Simple_Selector& rhs) const;
1954
2080
  bool operator<(const Attribute_Selector& rhs) const;
1955
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
1956
2081
  ATTACH_OPERATIONS()
1957
2082
  };
1958
2083
 
@@ -1971,6 +2096,7 @@ namespace Sass {
1971
2096
  name == ":first-letter";
1972
2097
  }
1973
2098
 
2099
+ // Pseudo Selector cannot have any namespace?
1974
2100
  class Pseudo_Selector : public Simple_Selector {
1975
2101
  ADD_PROPERTY(String*, expression)
1976
2102
  public:
@@ -1999,6 +2125,14 @@ namespace Sass {
1999
2125
  return (name_[0] == ':' && name_[1] == ':')
2000
2126
  || is_pseudo_class_element(name_);
2001
2127
  }
2128
+ virtual size_t hash()
2129
+ {
2130
+ if (hash_ == 0) {
2131
+ hash_combine(hash_, Simple_Selector::hash());
2132
+ if (expression_) hash_combine(hash_, expression_->hash());
2133
+ }
2134
+ return hash_;
2135
+ }
2002
2136
  virtual unsigned long specificity()
2003
2137
  {
2004
2138
  if (is_pseudo_element())
@@ -2018,16 +2152,30 @@ namespace Sass {
2018
2152
  Wrapped_Selector(ParserState pstate, std::string n, Selector* sel)
2019
2153
  : Simple_Selector(pstate, n), selector_(sel)
2020
2154
  { }
2155
+ virtual bool has_parent_ref() {
2156
+ // if (has_reference()) return true;
2157
+ if (!selector()) return false;
2158
+ return selector()->has_parent_ref();
2159
+ }
2021
2160
  virtual bool is_superselector_of(Wrapped_Selector* sub);
2022
2161
  // Selectors inside the negation pseudo-class are counted like any
2023
2162
  // other, but the negation itself does not count as a pseudo-class.
2163
+ virtual size_t hash()
2164
+ {
2165
+ if (hash_ == 0) {
2166
+ hash_combine(hash_, Simple_Selector::hash());
2167
+ if (selector_) hash_combine(hash_, selector_->hash());
2168
+ }
2169
+ return hash_;
2170
+ }
2024
2171
  virtual unsigned long specificity()
2025
2172
  {
2026
2173
  return selector_ ? selector_->specificity() : 0;
2027
2174
  }
2028
2175
  bool operator==(const Simple_Selector& rhs) const;
2029
2176
  bool operator==(const Wrapped_Selector& rhs) const;
2030
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
2177
+ bool operator<(const Simple_Selector& rhs) const;
2178
+ bool operator<(const Wrapped_Selector& rhs) const;
2031
2179
  ATTACH_OPERATIONS()
2032
2180
  };
2033
2181
 
@@ -2043,17 +2191,19 @@ namespace Sass {
2043
2191
  class Compound_Selector : public Selector, public Vectorized<Simple_Selector*> {
2044
2192
  private:
2045
2193
  SourcesSet sources_;
2194
+ ADD_PROPERTY(bool, extended);
2046
2195
  ADD_PROPERTY(bool, has_parent_reference);
2047
2196
  protected:
2048
2197
  void adjust_after_pushing(Simple_Selector* s)
2049
2198
  {
2050
- if (s->has_reference()) has_reference(true);
2199
+ // if (s->has_reference()) has_reference(true);
2051
2200
  if (s->has_placeholder()) has_placeholder(true);
2052
2201
  }
2053
2202
  public:
2054
2203
  Compound_Selector(ParserState pstate, size_t s = 0)
2055
2204
  : Selector(pstate),
2056
2205
  Vectorized<Simple_Selector*>(s),
2206
+ extended_(false),
2057
2207
  has_parent_reference_(false)
2058
2208
  { }
2059
2209
  bool contains_placeholder() {
@@ -2079,14 +2229,22 @@ namespace Sass {
2079
2229
  }
2080
2230
  const Simple_Selector* base() const {
2081
2231
  if (length() == 0) return 0;
2082
- if (typeid(*(*this)[0]) == typeid(Type_Selector))
2232
+ // ToDo: why is this needed?
2233
+ if (dynamic_cast<Type_Selector*>((*this)[0]))
2083
2234
  return (*this)[0];
2084
- // else cerr << "SERIOUSELY " << "\n";
2085
2235
  return 0;
2086
2236
  }
2087
2237
  virtual bool is_superselector_of(Compound_Selector* sub, std::string wrapped = "");
2088
2238
  virtual bool is_superselector_of(Complex_Selector* sub, std::string wrapped = "");
2089
2239
  virtual bool is_superselector_of(Selector_List* sub, std::string wrapped = "");
2240
+ virtual size_t hash()
2241
+ {
2242
+ if (Selector::hash_ == 0) {
2243
+ hash_combine(Selector::hash_, std::hash<int>()(SELECTOR));
2244
+ if (length()) hash_combine(Selector::hash_, Vectorized::hash());
2245
+ }
2246
+ return Selector::hash_;
2247
+ }
2090
2248
  virtual unsigned long specificity()
2091
2249
  {
2092
2250
  int sum = 0;
@@ -2098,7 +2256,7 @@ namespace Sass {
2098
2256
  bool is_empty_reference()
2099
2257
  {
2100
2258
  return length() == 1 &&
2101
- typeid(*(*this)[0]) == typeid(Parent_Selector);
2259
+ dynamic_cast<Parent_Selector*>((*this)[0]);
2102
2260
  }
2103
2261
  std::vector<std::string> to_str_vec(); // sometimes need to convert to a flat "by-value" data structure
2104
2262
 
@@ -2114,7 +2272,6 @@ namespace Sass {
2114
2272
  Compound_Selector* clone(Context&) const; // does not clone the Simple_Selector*s
2115
2273
 
2116
2274
  Compound_Selector* minus(Compound_Selector* rhs, Context& ctx);
2117
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
2118
2275
  ATTACH_OPERATIONS()
2119
2276
  };
2120
2277
 
@@ -2147,7 +2304,7 @@ namespace Sass {
2147
2304
  head_(h), tail_(t),
2148
2305
  reference_(r)
2149
2306
  {
2150
- if ((h && h->has_reference()) || (t && t->has_reference())) has_reference(true);
2307
+ // if ((h && h->has_reference()) || (t && t->has_reference())) has_reference(true);
2151
2308
  if ((h && h->has_placeholder()) || (t && t->has_placeholder())) has_placeholder(true);
2152
2309
  }
2153
2310
  virtual bool has_parent_ref();
@@ -2202,6 +2359,16 @@ namespace Sass {
2202
2359
  Combinator clear_innermost();
2203
2360
  void append(Context&, Complex_Selector*);
2204
2361
  void set_innermost(Complex_Selector*, Combinator);
2362
+ virtual size_t hash()
2363
+ {
2364
+ if (hash_ == 0) {
2365
+ hash_combine(hash_, std::hash<int>()(SELECTOR));
2366
+ hash_combine(hash_, std::hash<int>()(combinator_));
2367
+ if (head_) hash_combine(hash_, head_->hash());
2368
+ if (tail_) hash_combine(hash_, tail_->hash());
2369
+ }
2370
+ return hash_;
2371
+ }
2205
2372
  virtual unsigned long specificity() const
2206
2373
  {
2207
2374
  int sum = 0;
@@ -2263,7 +2430,6 @@ namespace Sass {
2263
2430
  Complex_Selector* clone(Context&) const; // does not clone Compound_Selector*s
2264
2431
  Complex_Selector* cloneFully(Context&) const; // clones Compound_Selector*s
2265
2432
  // std::vector<Compound_Selector*> to_vector();
2266
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
2267
2433
  ATTACH_OPERATIONS()
2268
2434
  };
2269
2435
 
@@ -2284,6 +2450,7 @@ namespace Sass {
2284
2450
  std::string type() { return "list"; }
2285
2451
  // remove parent selector references
2286
2452
  // basically unwraps parsed selectors
2453
+ virtual bool has_parent_ref();
2287
2454
  void remove_parent_selectors();
2288
2455
  // virtual Selector_Placeholder* find_placeholder();
2289
2456
  Selector_List* parentize(Selector_List* parents, Context& ctx);
@@ -2292,6 +2459,14 @@ namespace Sass {
2292
2459
  virtual bool is_superselector_of(Selector_List* sub, std::string wrapping = "");
2293
2460
  Selector_List* unify_with(Selector_List*, Context&);
2294
2461
  void populate_extends(Selector_List*, Context&, ExtensionSubsetMap&);
2462
+ virtual size_t hash()
2463
+ {
2464
+ if (Selector::hash_ == 0) {
2465
+ hash_combine(Selector::hash_, std::hash<int>()(SELECTOR));
2466
+ hash_combine(Selector::hash_, Vectorized::hash());
2467
+ }
2468
+ return Selector::hash_;
2469
+ }
2295
2470
  virtual unsigned long specificity()
2296
2471
  {
2297
2472
  unsigned long sum = 0;
@@ -2309,7 +2484,6 @@ namespace Sass {
2309
2484
  virtual bool operator==(const Selector_List& rhs) const;
2310
2485
  // Selector Lists can be compared to comma lists
2311
2486
  virtual bool operator==(const Expression& rhs) const;
2312
- virtual std::string to_string(bool compressed = false, int precision = 5) const;
2313
2487
  ATTACH_OPERATIONS()
2314
2488
  };
2315
2489