sassc 1.8.3 → 1.8.4

Sign up to get free protection for your applications and to get access to all the features.
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