sassc 1.11.4 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +2 -2
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/README.md +4 -1
  5. data/ext/libsass/.editorconfig +1 -1
  6. data/ext/libsass/.github/CONTRIBUTING.md +7 -7
  7. data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
  8. data/ext/libsass/.gitignore +3 -0
  9. data/ext/libsass/.travis.yml +37 -18
  10. data/ext/libsass/GNUmakefile.am +23 -37
  11. data/ext/libsass/Makefile +10 -6
  12. data/ext/libsass/Makefile.conf +3 -0
  13. data/ext/libsass/Readme.md +68 -63
  14. data/ext/libsass/appveyor.yml +7 -3
  15. data/ext/libsass/configure.ac +10 -14
  16. data/ext/libsass/docs/api-context-internal.md +29 -21
  17. data/ext/libsass/docs/api-context.md +26 -6
  18. data/ext/libsass/docs/api-doc.md +49 -16
  19. data/ext/libsass/docs/api-function-example.md +1 -1
  20. data/ext/libsass/docs/api-function.md +31 -7
  21. data/ext/libsass/docs/api-importer.md +19 -19
  22. data/ext/libsass/docs/api-value.md +4 -2
  23. data/ext/libsass/docs/build-on-windows.md +4 -4
  24. data/ext/libsass/docs/build-with-mingw.md +3 -3
  25. data/ext/libsass/docs/build.md +9 -9
  26. data/ext/libsass/docs/custom-functions-internal.md +10 -8
  27. data/ext/libsass/docs/implementations.md +20 -8
  28. data/ext/libsass/docs/unicode.md +16 -10
  29. data/ext/libsass/include/sass/base.h +0 -3
  30. data/ext/libsass/include/sass/context.h +20 -2
  31. data/ext/libsass/include/sass/functions.h +31 -0
  32. data/ext/libsass/include/sass/values.h +3 -1
  33. data/ext/libsass/include/sass/version.h +1 -1
  34. data/ext/libsass/include/sass/version.h.in +1 -1
  35. data/ext/libsass/include/sass2scss.h +1 -1
  36. data/ext/libsass/res/resource.rc +6 -6
  37. data/ext/libsass/script/ci-build-libsass +10 -5
  38. data/ext/libsass/script/ci-build-plugin +62 -0
  39. data/ext/libsass/script/ci-install-compiler +1 -1
  40. data/ext/libsass/script/ci-install-deps +4 -7
  41. data/ext/libsass/script/ci-report-coverage +13 -3
  42. data/ext/libsass/script/tap-driver +1 -1
  43. data/ext/libsass/script/tap-runner +1 -1
  44. data/ext/libsass/src/GNUmakefile.am +1 -1
  45. data/ext/libsass/src/ast.cpp +537 -762
  46. data/ext/libsass/src/ast.hpp +377 -419
  47. data/ext/libsass/src/ast_def_macros.hpp +26 -1
  48. data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
  49. data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
  50. data/ext/libsass/src/b64/encode.h +3 -1
  51. data/ext/libsass/src/backtrace.cpp +46 -0
  52. data/ext/libsass/src/backtrace.hpp +7 -54
  53. data/ext/libsass/src/bind.cpp +72 -50
  54. data/ext/libsass/src/bind.hpp +0 -1
  55. data/ext/libsass/src/cencode.c +6 -0
  56. data/ext/libsass/src/check_nesting.cpp +157 -135
  57. data/ext/libsass/src/check_nesting.hpp +11 -10
  58. data/ext/libsass/src/color_maps.cpp +10 -6
  59. data/ext/libsass/src/color_maps.hpp +6 -8
  60. data/ext/libsass/src/constants.cpp +4 -3
  61. data/ext/libsass/src/constants.hpp +4 -3
  62. data/ext/libsass/src/context.cpp +110 -47
  63. data/ext/libsass/src/context.hpp +11 -1
  64. data/ext/libsass/src/cssize.cpp +105 -94
  65. data/ext/libsass/src/cssize.hpp +4 -5
  66. data/ext/libsass/src/debugger.hpp +247 -244
  67. data/ext/libsass/src/emitter.cpp +30 -6
  68. data/ext/libsass/src/emitter.hpp +7 -0
  69. data/ext/libsass/src/environment.cpp +67 -16
  70. data/ext/libsass/src/environment.hpp +28 -7
  71. data/ext/libsass/src/error_handling.cpp +92 -64
  72. data/ext/libsass/src/error_handling.hpp +64 -43
  73. data/ext/libsass/src/eval.cpp +494 -544
  74. data/ext/libsass/src/eval.hpp +17 -23
  75. data/ext/libsass/src/expand.cpp +182 -154
  76. data/ext/libsass/src/expand.hpp +4 -5
  77. data/ext/libsass/src/extend.cpp +299 -291
  78. data/ext/libsass/src/extend.hpp +46 -11
  79. data/ext/libsass/src/file.cpp +103 -36
  80. data/ext/libsass/src/file.hpp +21 -4
  81. data/ext/libsass/src/functions.cpp +561 -312
  82. data/ext/libsass/src/functions.hpp +8 -5
  83. data/ext/libsass/src/inspect.cpp +108 -53
  84. data/ext/libsass/src/inspect.hpp +5 -2
  85. data/ext/libsass/src/lexer.cpp +15 -7
  86. data/ext/libsass/src/lexer.hpp +13 -4
  87. data/ext/libsass/src/listize.cpp +3 -2
  88. data/ext/libsass/src/listize.hpp +0 -1
  89. data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
  90. data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
  91. data/ext/libsass/src/node.cpp +34 -38
  92. data/ext/libsass/src/node.hpp +6 -8
  93. data/ext/libsass/src/operation.hpp +2 -2
  94. data/ext/libsass/src/operators.cpp +240 -0
  95. data/ext/libsass/src/operators.hpp +30 -0
  96. data/ext/libsass/src/output.cpp +22 -20
  97. data/ext/libsass/src/parser.cpp +719 -358
  98. data/ext/libsass/src/parser.hpp +57 -22
  99. data/ext/libsass/src/plugins.cpp +28 -10
  100. data/ext/libsass/src/position.cpp +21 -3
  101. data/ext/libsass/src/position.hpp +2 -1
  102. data/ext/libsass/src/prelexer.cpp +104 -19
  103. data/ext/libsass/src/prelexer.hpp +10 -3
  104. data/ext/libsass/src/remove_placeholders.cpp +9 -10
  105. data/ext/libsass/src/remove_placeholders.hpp +1 -5
  106. data/ext/libsass/src/sass.cpp +62 -4
  107. data/ext/libsass/src/sass.hpp +5 -2
  108. data/ext/libsass/src/sass_context.cpp +96 -58
  109. data/ext/libsass/src/sass_context.hpp +7 -5
  110. data/ext/libsass/src/sass_functions.cpp +63 -1
  111. data/ext/libsass/src/sass_functions.hpp +19 -1
  112. data/ext/libsass/src/sass_util.cpp +3 -3
  113. data/ext/libsass/src/sass_util.hpp +4 -4
  114. data/ext/libsass/src/sass_values.cpp +42 -39
  115. data/ext/libsass/src/sass_values.hpp +2 -1
  116. data/ext/libsass/src/source_map.cpp +16 -18
  117. data/ext/libsass/src/subset_map.cpp +6 -8
  118. data/ext/libsass/src/subset_map.hpp +6 -6
  119. data/ext/libsass/src/to_c.cpp +2 -2
  120. data/ext/libsass/src/to_value.cpp +8 -3
  121. data/ext/libsass/src/to_value.hpp +1 -0
  122. data/ext/libsass/src/units.cpp +349 -45
  123. data/ext/libsass/src/units.hpp +39 -22
  124. data/ext/libsass/src/utf8/checked.h +7 -0
  125. data/ext/libsass/src/utf8/unchecked.h +7 -0
  126. data/ext/libsass/src/utf8_string.cpp +1 -1
  127. data/ext/libsass/src/util.cpp +139 -45
  128. data/ext/libsass/src/util.hpp +4 -7
  129. data/ext/libsass/src/values.cpp +15 -23
  130. data/ext/libsass/win/libsass.sln +13 -2
  131. data/ext/libsass/win/libsass.sln.DotSettings +9 -0
  132. data/ext/libsass/win/libsass.targets +3 -0
  133. data/ext/libsass/win/libsass.vcxproj.filters +9 -0
  134. data/lib/sassc/version.rb +1 -1
  135. data/sassc.gemspec +1 -1
  136. data/test/native_test.rb +1 -1
  137. metadata +11 -4
@@ -61,15 +61,15 @@ namespace Sass {
61
61
  static Node createCombinator(const Complex_Selector::Combinator& combinator);
62
62
 
63
63
  // This method will klone the selector, stripping off the tail and combinator
64
- static Node createSelector(Complex_Selector_Ptr pSelector, Context& ctx);
64
+ static Node createSelector(const Complex_Selector& pSelector);
65
65
 
66
66
  static Node createCollection();
67
67
  static Node createCollection(const NodeDeque& values);
68
68
 
69
69
  static Node createNil();
70
- static Node naiveTrim(Node& seqses, Context& ctx);
70
+ static Node naiveTrim(Node& seqses);
71
71
 
72
- Node klone(Context& ctx) const;
72
+ Node klone() const;
73
73
 
74
74
  bool operator==(const Node& rhs) const;
75
75
  inline bool operator!=(const Node& rhs) const { return !(*this == rhs); }
@@ -91,7 +91,7 @@ namespace Sass {
91
91
  // potentialChild must be a node collection of selectors/combinators. this must be a collection
92
92
  // of collections of nodes/combinators. This method checks if potentialChild is a child of this
93
93
  // Node.
94
- bool contains(const Node& potentialChild, bool simpleSelectorOrderDependent) const;
94
+ bool contains(const Node& potentialChild) const;
95
95
 
96
96
  private:
97
97
  // Private constructor; Use the static methods (like createCombinator and createSelector)
@@ -110,10 +110,8 @@ namespace Sass {
110
110
  #ifdef DEBUG
111
111
  std::ostream& operator<<(std::ostream& os, const Node& node);
112
112
  #endif
113
- Node complexSelectorToNode(Complex_Selector_Ptr pToConvert, Context& ctx);
114
- Complex_Selector_Ptr nodeToComplexSelector(const Node& toConvert, Context& ctx);
115
-
116
- bool nodesEqual(const Node& one, const Node& two, bool simpleSelectorOrderDependent);
113
+ Node complexSelectorToNode(Complex_Selector_Ptr pToConvert);
114
+ Complex_Selector_Ptr nodeToComplexSelector(const Node& toConvert);
117
115
 
118
116
  }
119
117
 
@@ -40,6 +40,7 @@ namespace Sass {
40
40
  // expressions
41
41
  virtual T operator()(List_Ptr x) = 0;
42
42
  virtual T operator()(Map_Ptr x) = 0;
43
+ virtual T operator()(Function_Ptr x) = 0;
43
44
  virtual T operator()(Binary_Expression_Ptr x) = 0;
44
45
  virtual T operator()(Unary_Expression_Ptr x) = 0;
45
46
  virtual T operator()(Function_Call_Ptr x) = 0;
@@ -47,7 +48,6 @@ namespace Sass {
47
48
  virtual T operator()(Custom_Warning_Ptr x) = 0;
48
49
  virtual T operator()(Custom_Error_Ptr x) = 0;
49
50
  virtual T operator()(Variable_Ptr x) = 0;
50
- virtual T operator()(Textual_Ptr x) = 0;
51
51
  virtual T operator()(Number_Ptr x) = 0;
52
52
  virtual T operator()(Color_Ptr x) = 0;
53
53
  virtual T operator()(Boolean_Ptr x) = 0;
@@ -122,6 +122,7 @@ namespace Sass {
122
122
  // expressions
123
123
  T operator()(List_Ptr x) { return static_cast<D*>(this)->fallback(x); }
124
124
  T operator()(Map_Ptr x) { return static_cast<D*>(this)->fallback(x); }
125
+ T operator()(Function_Ptr x) { return static_cast<D*>(this)->fallback(x); }
125
126
  T operator()(Binary_Expression_Ptr x) { return static_cast<D*>(this)->fallback(x); }
126
127
  T operator()(Unary_Expression_Ptr x) { return static_cast<D*>(this)->fallback(x); }
127
128
  T operator()(Function_Call_Ptr x) { return static_cast<D*>(this)->fallback(x); }
@@ -129,7 +130,6 @@ namespace Sass {
129
130
  T operator()(Custom_Warning_Ptr x) { return static_cast<D*>(this)->fallback(x); }
130
131
  T operator()(Custom_Error_Ptr x) { return static_cast<D*>(this)->fallback(x); }
131
132
  T operator()(Variable_Ptr x) { return static_cast<D*>(this)->fallback(x); }
132
- T operator()(Textual_Ptr x) { return static_cast<D*>(this)->fallback(x); }
133
133
  T operator()(Number_Ptr x) { return static_cast<D*>(this)->fallback(x); }
134
134
  T operator()(Color_Ptr x) { return static_cast<D*>(this)->fallback(x); }
135
135
  T operator()(Boolean_Ptr x) { return static_cast<D*>(this)->fallback(x); }
@@ -0,0 +1,240 @@
1
+ #include "sass.hpp"
2
+ #include "operators.hpp"
3
+
4
+ namespace Sass {
5
+
6
+ namespace Operators {
7
+
8
+ inline double add(double x, double y) { return x + y; }
9
+ inline double sub(double x, double y) { return x - y; }
10
+ inline double mul(double x, double y) { return x * y; }
11
+ inline double div(double x, double y) { return x / y; } // x/0 checked by caller
12
+
13
+ inline double mod(double x, double y) { // x/0 checked by caller
14
+ if ((x > 0 && y < 0) || (x < 0 && y > 0)) {
15
+ double ret = std::fmod(x, y);
16
+ return ret ? ret + y : ret;
17
+ } else {
18
+ return std::fmod(x, y);
19
+ }
20
+ }
21
+
22
+ typedef double (*bop)(double, double);
23
+ bop ops[Sass_OP::NUM_OPS] = {
24
+ 0, 0, // and, or
25
+ 0, 0, 0, 0, 0, 0, // eq, neq, gt, gte, lt, lte
26
+ add, sub, mul, div, mod
27
+ };
28
+
29
+ /* static function, has no pstate or traces */
30
+ bool eq(Expression_Obj lhs, Expression_Obj rhs)
31
+ {
32
+ // operation is undefined if one is not a number
33
+ if (!lhs || !rhs) throw Exception::UndefinedOperation(lhs, rhs, Sass_OP::EQ);
34
+ // use compare operator from ast node
35
+ return *lhs == *rhs;
36
+ }
37
+
38
+ /* static function, throws OperationError, has no pstate or traces */
39
+ bool cmp(Expression_Obj lhs, Expression_Obj rhs, const Sass_OP op)
40
+ {
41
+ // can only compare numbers!?
42
+ Number_Obj l = Cast<Number>(lhs);
43
+ Number_Obj r = Cast<Number>(rhs);
44
+ // operation is undefined if one is not a number
45
+ if (!l || !r) throw Exception::UndefinedOperation(lhs, rhs, op);
46
+ // use compare operator from ast node
47
+ return *l < *r;
48
+ }
49
+
50
+ /* static functions, throws OperationError, has no pstate or traces */
51
+ bool lt(Expression_Obj lhs, Expression_Obj rhs) { return cmp(lhs, rhs, Sass_OP::LT); }
52
+ bool neq(Expression_Obj lhs, Expression_Obj rhs) { return eq(lhs, rhs) == false; }
53
+ bool gt(Expression_Obj lhs, Expression_Obj rhs) { return !cmp(lhs, rhs, Sass_OP::GT) && neq(lhs, rhs); }
54
+ bool lte(Expression_Obj lhs, Expression_Obj rhs) { return cmp(lhs, rhs, Sass_OP::LTE) || eq(lhs, rhs); }
55
+ bool gte(Expression_Obj lhs, Expression_Obj rhs) { return !cmp(lhs, rhs, Sass_OP::GTE) || eq(lhs, rhs); }
56
+
57
+ /* static function, throws OperationError, has no traces but optional pstate for returned value */
58
+ Value_Ptr op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
59
+ {
60
+ enum Sass_OP op = operand.operand;
61
+
62
+ String_Quoted_Ptr lqstr = Cast<String_Quoted>(&lhs);
63
+ String_Quoted_Ptr rqstr = Cast<String_Quoted>(&rhs);
64
+
65
+ std::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt));
66
+ std::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt));
67
+
68
+ if (Cast<Null>(&lhs)) throw Exception::InvalidNullOperation(&lhs, &rhs, op);
69
+ if (Cast<Null>(&rhs)) throw Exception::InvalidNullOperation(&lhs, &rhs, op);
70
+
71
+ std::string sep;
72
+ switch (op) {
73
+ case Sass_OP::ADD: sep = ""; break;
74
+ case Sass_OP::SUB: sep = "-"; break;
75
+ case Sass_OP::DIV: sep = "/"; break;
76
+ case Sass_OP::EQ: sep = "=="; break;
77
+ case Sass_OP::NEQ: sep = "!="; break;
78
+ case Sass_OP::LT: sep = "<"; break;
79
+ case Sass_OP::GT: sep = ">"; break;
80
+ case Sass_OP::LTE: sep = "<="; break;
81
+ case Sass_OP::GTE: sep = ">="; break;
82
+ default:
83
+ throw Exception::UndefinedOperation(&lhs, &rhs, op);
84
+ break;
85
+ }
86
+
87
+ if (op == Sass_OP::ADD) {
88
+ // create string that might be quoted on output (but do not unquote what we pass)
89
+ return SASS_MEMORY_NEW(String_Quoted, pstate, lstr + rstr, 0, false, true);
90
+ }
91
+
92
+ // add whitespace around operator
93
+ // but only if result is not delayed
94
+ if (sep != "" && delayed == false) {
95
+ if (operand.ws_before) sep = " " + sep;
96
+ if (operand.ws_after) sep = sep + " ";
97
+ }
98
+
99
+ if (op == Sass_OP::SUB || op == Sass_OP::DIV) {
100
+ if (lqstr && lqstr->quote_mark()) lstr = quote(lstr);
101
+ if (rqstr && rqstr->quote_mark()) rstr = quote(rstr);
102
+ }
103
+
104
+ return SASS_MEMORY_NEW(String_Constant, pstate, lstr + sep + rstr);
105
+ }
106
+
107
+ /* static function, throws OperationError, has no traces but optional pstate for returned value */
108
+ Value_Ptr op_colors(enum Sass_OP op, const Color& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
109
+ {
110
+ if (lhs.a() != rhs.a()) {
111
+ throw Exception::AlphaChannelsNotEqual(&lhs, &rhs, op);
112
+ }
113
+ if (op == Sass_OP::DIV && (!rhs.r() || !rhs.g() || !rhs.b())) {
114
+ throw Exception::ZeroDivisionError(lhs, rhs);
115
+ }
116
+ return SASS_MEMORY_NEW(Color,
117
+ pstate,
118
+ ops[op](lhs.r(), rhs.r()),
119
+ ops[op](lhs.g(), rhs.g()),
120
+ ops[op](lhs.b(), rhs.b()),
121
+ lhs.a());
122
+ }
123
+
124
+ /* static function, throws OperationError, has no traces but optional pstate for returned value */
125
+ Value_Ptr op_numbers(enum Sass_OP op, const Number& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
126
+ {
127
+ double lval = lhs.value();
128
+ double rval = rhs.value();
129
+
130
+ if (op == Sass_OP::MOD && rval == 0) {
131
+ return SASS_MEMORY_NEW(String_Quoted, pstate, "NaN");
132
+ }
133
+
134
+ if (op == Sass_OP::DIV && rval == 0) {
135
+ std::string result(lval ? "Infinity" : "NaN");
136
+ return SASS_MEMORY_NEW(String_Quoted, pstate, result);
137
+ }
138
+
139
+ size_t l_n_units = lhs.numerators.size();
140
+ size_t l_d_units = lhs.numerators.size();
141
+ size_t r_n_units = rhs.denominators.size();
142
+ size_t r_d_units = rhs.denominators.size();
143
+ // optimize out the most common and simplest case
144
+ if (l_n_units == r_n_units && l_d_units == r_d_units) {
145
+ if (l_n_units + l_d_units <= 1 && r_n_units + r_d_units <= 1) {
146
+ if (lhs.numerators == rhs.numerators) {
147
+ if (lhs.denominators == rhs.denominators) {
148
+ Number_Ptr v = SASS_MEMORY_COPY(&lhs);
149
+ v->value(ops[op](lval, rval));
150
+ return v;
151
+ }
152
+ }
153
+ }
154
+ }
155
+
156
+ Number_Obj v = SASS_MEMORY_COPY(&lhs);
157
+
158
+ if (lhs.is_unitless() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) {
159
+ v->numerators = rhs.numerators;
160
+ v->denominators = rhs.denominators;
161
+ }
162
+
163
+ if (op == Sass_OP::MUL) {
164
+ v->value(ops[op](lval, rval));
165
+ v->numerators.insert(v->numerators.end(),
166
+ rhs.numerators.begin(), rhs.numerators.end()
167
+ );
168
+ v->denominators.insert(v->denominators.end(),
169
+ rhs.denominators.begin(), rhs.denominators.end()
170
+ );
171
+ v->reduce();
172
+ }
173
+ else if (op == Sass_OP::DIV) {
174
+ v->value(ops[op](lval, rval));
175
+ v->numerators.insert(v->numerators.end(),
176
+ rhs.denominators.begin(), rhs.denominators.end()
177
+ );
178
+ v->denominators.insert(v->denominators.end(),
179
+ rhs.numerators.begin(), rhs.numerators.end()
180
+ );
181
+ v->reduce();
182
+ }
183
+ else {
184
+ Number ln(lhs), rn(rhs);
185
+ ln.reduce(); rn.reduce();
186
+ double f(rn.convert_factor(ln));
187
+ v->value(ops[op](lval, rn.value() * f));
188
+ }
189
+
190
+ v->pstate(pstate);
191
+ return v.detach();
192
+ }
193
+
194
+ /* static function, throws OperationError, has no traces but optional pstate for returned value */
195
+ Value_Ptr op_number_color(enum Sass_OP op, const Number& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
196
+ {
197
+ double lval = lhs.value();
198
+ switch (op) {
199
+ case Sass_OP::ADD:
200
+ case Sass_OP::MUL: {
201
+ return SASS_MEMORY_NEW(Color,
202
+ pstate,
203
+ ops[op](lval, rhs.r()),
204
+ ops[op](lval, rhs.g()),
205
+ ops[op](lval, rhs.b()),
206
+ rhs.a());
207
+ }
208
+ case Sass_OP::SUB:
209
+ case Sass_OP::DIV: {
210
+ std::string color(rhs.to_string(opt));
211
+ return SASS_MEMORY_NEW(String_Quoted,
212
+ pstate,
213
+ lhs.to_string(opt)
214
+ + sass_op_separator(op)
215
+ + color);
216
+ }
217
+ default: break;
218
+ }
219
+ throw Exception::UndefinedOperation(&lhs, &rhs, op);
220
+ }
221
+
222
+ /* static function, throws OperationError, has no traces but optional pstate for returned value */
223
+ Value_Ptr op_color_number(enum Sass_OP op, const Color& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
224
+ {
225
+ double rval = rhs.value();
226
+ if (op == Sass_OP::DIV && rval == 0) {
227
+ // comparison of Fixnum with Float failed?
228
+ throw Exception::ZeroDivisionError(lhs, rhs);
229
+ }
230
+ return SASS_MEMORY_NEW(Color,
231
+ pstate,
232
+ ops[op](lhs.r(), rval),
233
+ ops[op](lhs.g(), rval),
234
+ ops[op](lhs.b(), rval),
235
+ lhs.a());
236
+ }
237
+
238
+ }
239
+
240
+ }
@@ -0,0 +1,30 @@
1
+ #ifndef SASS_OPERATORS_H
2
+ #define SASS_OPERATORS_H
3
+
4
+ #include "values.hpp"
5
+ #include "sass/values.h"
6
+
7
+ namespace Sass {
8
+
9
+ namespace Operators {
10
+
11
+ // equality operator using AST Node operator==
12
+ bool eq(Expression_Obj, Expression_Obj);
13
+ bool neq(Expression_Obj, Expression_Obj);
14
+ // specific operators based on cmp and eq
15
+ bool lt(Expression_Obj, Expression_Obj);
16
+ bool gt(Expression_Obj, Expression_Obj);
17
+ bool lte(Expression_Obj, Expression_Obj);
18
+ bool gte(Expression_Obj, Expression_Obj);
19
+ // arithmetic for all the combinations that matter
20
+ Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
21
+ Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
22
+ Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
23
+ Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
24
+ Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
25
+
26
+ };
27
+
28
+ }
29
+
30
+ #endif
@@ -19,13 +19,14 @@ namespace Sass {
19
19
 
20
20
  void Output::operator()(Number_Ptr n)
21
21
  {
22
- // use values to_string facility
23
- std::string res = n->to_string(opt);
24
22
  // check for a valid unit here
25
23
  // includes result for reporting
26
24
  if (!n->is_valid_css_unit()) {
27
- throw Exception::InvalidValue(*n);
25
+ // should be handle in check_expression
26
+ throw Exception::InvalidValue({}, *n);
28
27
  }
28
+ // use values to_string facility
29
+ std::string res = n->to_string(opt);
29
30
  // output the final token
30
31
  append_token(res, n);
31
32
  }
@@ -37,8 +38,8 @@ namespace Sass {
37
38
 
38
39
  void Output::operator()(Map_Ptr m)
39
40
  {
40
- std::string dbg(m->to_string(opt));
41
- error(dbg + " isn't a valid CSS value.", m->pstate());
41
+ // should be handle in check_expression
42
+ throw Exception::InvalidValue({}, *m);
42
43
  }
43
44
 
44
45
  OutputBuffer Output::get_buffer(void)
@@ -116,8 +117,8 @@ namespace Sass {
116
117
  if (!Util::isPrintable(r, output_style())) {
117
118
  for (size_t i = 0, L = b->length(); i < L; ++i) {
118
119
  const Statement_Obj& stm = b->at(i);
119
- if (dynamic_cast<Has_Block_Ptr>(&stm)) {
120
- if (!dynamic_cast<Declaration_Ptr>(&stm)) {
120
+ if (Cast<Has_Block>(stm)) {
121
+ if (!Cast<Declaration>(stm)) {
121
122
  stm->perform(this);
122
123
  }
123
124
  }
@@ -134,28 +135,29 @@ namespace Sass {
134
135
  append_string(ss.str());
135
136
  append_optional_linefeed();
136
137
  }
138
+ scheduled_crutch = s;
137
139
  if (s) s->perform(this);
138
- append_scope_opener(&b);
140
+ append_scope_opener(b);
139
141
  for (size_t i = 0, L = b->length(); i < L; ++i) {
140
142
  Statement_Obj stm = b->at(i);
141
143
  bool bPrintExpression = true;
142
144
  // Check print conditions
143
- if (Declaration_Ptr dec = SASS_MEMORY_CAST(Declaration, stm)) {
144
- if (String_Constant_Ptr valConst = SASS_MEMORY_CAST(String_Constant, dec->value())) {
145
+ if (Declaration_Ptr dec = Cast<Declaration>(stm)) {
146
+ if (String_Constant_Ptr valConst = Cast<String_Constant>(dec->value())) {
145
147
  std::string val(valConst->value());
146
- if (String_Quoted_Ptr qstr = SASS_MEMORY_CAST_PTR(String_Quoted, valConst)) {
148
+ if (String_Quoted_Ptr qstr = Cast<String_Quoted>(valConst)) {
147
149
  if (!qstr->quote_mark() && val.empty()) {
148
150
  bPrintExpression = false;
149
151
  }
150
152
  }
151
153
  }
152
- else if (List_Ptr list = SASS_MEMORY_CAST(List, dec->value())) {
154
+ else if (List_Ptr list = Cast<List>(dec->value())) {
153
155
  bool all_invisible = true;
154
156
  for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
155
- Expression_Ptr item = &list->at(list_i);
157
+ Expression_Ptr item = list->at(list_i);
156
158
  if (!item->is_invisible()) all_invisible = false;
157
159
  }
158
- if (all_invisible) bPrintExpression = false;
160
+ if (all_invisible && !list->is_bracketed()) bPrintExpression = false;
159
161
  }
160
162
  }
161
163
  // Print if OK
@@ -164,7 +166,7 @@ namespace Sass {
164
166
  }
165
167
  }
166
168
  if (output_style() == NESTED) indentation -= r->tabs();
167
- append_scope_closer(&b);
169
+ append_scope_closer(b);
168
170
 
169
171
  }
170
172
  void Output::operator()(Keyframe_Rule_Ptr r)
@@ -172,7 +174,7 @@ namespace Sass {
172
174
  Block_Obj b = r->block();
173
175
  Selector_Obj v = r->name();
174
176
 
175
- if (&v) {
177
+ if (!v.isNull()) {
176
178
  v->perform(this);
177
179
  }
178
180
 
@@ -201,7 +203,7 @@ namespace Sass {
201
203
  if (!Util::isPrintable(f, output_style())) {
202
204
  for (size_t i = 0, L = b->length(); i < L; ++i) {
203
205
  Statement_Obj stm = b->at(i);
204
- if (dynamic_cast<Has_Block_Ptr>(&stm)) {
206
+ if (Cast<Has_Block>(stm)) {
205
207
  stm->perform(this);
206
208
  }
207
209
  }
@@ -237,7 +239,7 @@ namespace Sass {
237
239
  if (!Util::isPrintable(m, output_style())) {
238
240
  for (size_t i = 0, L = b->length(); i < L; ++i) {
239
241
  Statement_Obj stm = b->at(i);
240
- if (dynamic_cast<Has_Block_Ptr>(&stm)) {
242
+ if (Cast<Has_Block>(stm)) {
241
243
  stm->perform(this);
242
244
  }
243
245
  }
@@ -282,7 +284,7 @@ namespace Sass {
282
284
  if (v) {
283
285
  append_mandatory_space();
284
286
  // ruby sass bug? should use options?
285
- append_token(v->to_string(/* opt */), &v);
287
+ append_token(v->to_string(/* opt */), v);
286
288
  }
287
289
  if (!b) {
288
290
  append_delimiter();
@@ -324,7 +326,7 @@ namespace Sass {
324
326
  if (s->can_compress_whitespace() && output_style() == COMPRESSED) {
325
327
  value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end());
326
328
  }
327
- if (!in_comment) {
329
+ if (!in_comment && !in_custom_property) {
328
330
  append_token(string_to_output(value), s);
329
331
  } else {
330
332
  append_token(value, s);