sassc4 2.4.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 (216) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +16 -0
  5. data/CHANGELOG.md +97 -0
  6. data/CODE_OF_CONDUCT.md +10 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +80 -0
  10. data/Rakefile +51 -0
  11. data/ext/depend +4 -0
  12. data/ext/extconf.rb +92 -0
  13. data/ext/libsass/VERSION +1 -0
  14. data/ext/libsass/contrib/plugin.cpp +60 -0
  15. data/ext/libsass/include/sass/base.h +97 -0
  16. data/ext/libsass/include/sass/context.h +174 -0
  17. data/ext/libsass/include/sass/functions.h +139 -0
  18. data/ext/libsass/include/sass/values.h +145 -0
  19. data/ext/libsass/include/sass/version.h +12 -0
  20. data/ext/libsass/include/sass.h +15 -0
  21. data/ext/libsass/include/sass2scss.h +120 -0
  22. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  23. data/ext/libsass/src/ast.cpp +953 -0
  24. data/ext/libsass/src/ast.hpp +1064 -0
  25. data/ext/libsass/src/ast2c.cpp +80 -0
  26. data/ext/libsass/src/ast2c.hpp +39 -0
  27. data/ext/libsass/src/ast_def_macros.hpp +140 -0
  28. data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
  29. data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
  30. data/ext/libsass/src/ast_helpers.hpp +316 -0
  31. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  32. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  33. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  34. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  35. data/ext/libsass/src/ast_selectors.cpp +1070 -0
  36. data/ext/libsass/src/ast_selectors.hpp +523 -0
  37. data/ext/libsass/src/ast_supports.cpp +114 -0
  38. data/ext/libsass/src/ast_supports.hpp +121 -0
  39. data/ext/libsass/src/ast_values.cpp +1154 -0
  40. data/ext/libsass/src/ast_values.hpp +498 -0
  41. data/ext/libsass/src/b64/cencode.h +32 -0
  42. data/ext/libsass/src/b64/encode.h +79 -0
  43. data/ext/libsass/src/backtrace.cpp +50 -0
  44. data/ext/libsass/src/backtrace.hpp +29 -0
  45. data/ext/libsass/src/base64vlq.cpp +47 -0
  46. data/ext/libsass/src/base64vlq.hpp +30 -0
  47. data/ext/libsass/src/bind.cpp +312 -0
  48. data/ext/libsass/src/bind.hpp +15 -0
  49. data/ext/libsass/src/c2ast.cpp +64 -0
  50. data/ext/libsass/src/c2ast.hpp +14 -0
  51. data/ext/libsass/src/c99func.c +54 -0
  52. data/ext/libsass/src/cencode.c +106 -0
  53. data/ext/libsass/src/check_nesting.cpp +393 -0
  54. data/ext/libsass/src/check_nesting.hpp +70 -0
  55. data/ext/libsass/src/color_maps.cpp +652 -0
  56. data/ext/libsass/src/color_maps.hpp +323 -0
  57. data/ext/libsass/src/color_spaces.cpp +241 -0
  58. data/ext/libsass/src/color_spaces.hpp +227 -0
  59. data/ext/libsass/src/constants.cpp +199 -0
  60. data/ext/libsass/src/constants.hpp +200 -0
  61. data/ext/libsass/src/context.cpp +870 -0
  62. data/ext/libsass/src/context.hpp +140 -0
  63. data/ext/libsass/src/cssize.cpp +521 -0
  64. data/ext/libsass/src/cssize.hpp +71 -0
  65. data/ext/libsass/src/dart_helpers.hpp +199 -0
  66. data/ext/libsass/src/debug.hpp +43 -0
  67. data/ext/libsass/src/debugger.hpp +964 -0
  68. data/ext/libsass/src/emitter.cpp +297 -0
  69. data/ext/libsass/src/emitter.hpp +101 -0
  70. data/ext/libsass/src/environment.cpp +260 -0
  71. data/ext/libsass/src/environment.hpp +124 -0
  72. data/ext/libsass/src/error_handling.cpp +239 -0
  73. data/ext/libsass/src/error_handling.hpp +248 -0
  74. data/ext/libsass/src/eval.cpp +1543 -0
  75. data/ext/libsass/src/eval.hpp +110 -0
  76. data/ext/libsass/src/eval_selectors.cpp +75 -0
  77. data/ext/libsass/src/expand.cpp +875 -0
  78. data/ext/libsass/src/expand.hpp +98 -0
  79. data/ext/libsass/src/extender.cpp +1226 -0
  80. data/ext/libsass/src/extender.hpp +399 -0
  81. data/ext/libsass/src/extension.cpp +43 -0
  82. data/ext/libsass/src/extension.hpp +89 -0
  83. data/ext/libsass/src/file.cpp +531 -0
  84. data/ext/libsass/src/file.hpp +124 -0
  85. data/ext/libsass/src/fn_colors.cpp +836 -0
  86. data/ext/libsass/src/fn_colors.hpp +99 -0
  87. data/ext/libsass/src/fn_lists.cpp +285 -0
  88. data/ext/libsass/src/fn_lists.hpp +34 -0
  89. data/ext/libsass/src/fn_maps.cpp +94 -0
  90. data/ext/libsass/src/fn_maps.hpp +30 -0
  91. data/ext/libsass/src/fn_miscs.cpp +248 -0
  92. data/ext/libsass/src/fn_miscs.hpp +40 -0
  93. data/ext/libsass/src/fn_numbers.cpp +246 -0
  94. data/ext/libsass/src/fn_numbers.hpp +45 -0
  95. data/ext/libsass/src/fn_selectors.cpp +205 -0
  96. data/ext/libsass/src/fn_selectors.hpp +35 -0
  97. data/ext/libsass/src/fn_strings.cpp +268 -0
  98. data/ext/libsass/src/fn_strings.hpp +34 -0
  99. data/ext/libsass/src/fn_utils.cpp +159 -0
  100. data/ext/libsass/src/fn_utils.hpp +62 -0
  101. data/ext/libsass/src/inspect.cpp +1126 -0
  102. data/ext/libsass/src/inspect.hpp +101 -0
  103. data/ext/libsass/src/json.cpp +1436 -0
  104. data/ext/libsass/src/json.hpp +117 -0
  105. data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
  106. data/ext/libsass/src/lexer.cpp +122 -0
  107. data/ext/libsass/src/lexer.hpp +304 -0
  108. data/ext/libsass/src/listize.cpp +70 -0
  109. data/ext/libsass/src/listize.hpp +37 -0
  110. data/ext/libsass/src/mapping.hpp +19 -0
  111. data/ext/libsass/src/memory/allocator.cpp +48 -0
  112. data/ext/libsass/src/memory/allocator.hpp +138 -0
  113. data/ext/libsass/src/memory/config.hpp +20 -0
  114. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  115. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  116. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  117. data/ext/libsass/src/memory.hpp +12 -0
  118. data/ext/libsass/src/operation.hpp +223 -0
  119. data/ext/libsass/src/operators.cpp +267 -0
  120. data/ext/libsass/src/operators.hpp +30 -0
  121. data/ext/libsass/src/ordered_map.hpp +112 -0
  122. data/ext/libsass/src/output.cpp +320 -0
  123. data/ext/libsass/src/output.hpp +47 -0
  124. data/ext/libsass/src/parser.cpp +3059 -0
  125. data/ext/libsass/src/parser.hpp +395 -0
  126. data/ext/libsass/src/parser_selectors.cpp +189 -0
  127. data/ext/libsass/src/permutate.hpp +164 -0
  128. data/ext/libsass/src/plugins.cpp +188 -0
  129. data/ext/libsass/src/plugins.hpp +57 -0
  130. data/ext/libsass/src/position.cpp +163 -0
  131. data/ext/libsass/src/position.hpp +147 -0
  132. data/ext/libsass/src/prelexer.cpp +1780 -0
  133. data/ext/libsass/src/prelexer.hpp +484 -0
  134. data/ext/libsass/src/remove_placeholders.cpp +86 -0
  135. data/ext/libsass/src/remove_placeholders.hpp +37 -0
  136. data/ext/libsass/src/sass.cpp +156 -0
  137. data/ext/libsass/src/sass.hpp +147 -0
  138. data/ext/libsass/src/sass2scss.cpp +895 -0
  139. data/ext/libsass/src/sass_context.cpp +742 -0
  140. data/ext/libsass/src/sass_context.hpp +129 -0
  141. data/ext/libsass/src/sass_functions.cpp +210 -0
  142. data/ext/libsass/src/sass_functions.hpp +50 -0
  143. data/ext/libsass/src/sass_values.cpp +362 -0
  144. data/ext/libsass/src/sass_values.hpp +82 -0
  145. data/ext/libsass/src/settings.hpp +19 -0
  146. data/ext/libsass/src/source.cpp +69 -0
  147. data/ext/libsass/src/source.hpp +95 -0
  148. data/ext/libsass/src/source_data.hpp +32 -0
  149. data/ext/libsass/src/source_map.cpp +202 -0
  150. data/ext/libsass/src/source_map.hpp +65 -0
  151. data/ext/libsass/src/stylesheet.cpp +22 -0
  152. data/ext/libsass/src/stylesheet.hpp +57 -0
  153. data/ext/libsass/src/to_value.cpp +114 -0
  154. data/ext/libsass/src/to_value.hpp +46 -0
  155. data/ext/libsass/src/units.cpp +507 -0
  156. data/ext/libsass/src/units.hpp +110 -0
  157. data/ext/libsass/src/utf8/checked.h +336 -0
  158. data/ext/libsass/src/utf8/core.h +332 -0
  159. data/ext/libsass/src/utf8/unchecked.h +235 -0
  160. data/ext/libsass/src/utf8.h +34 -0
  161. data/ext/libsass/src/utf8_string.cpp +104 -0
  162. data/ext/libsass/src/utf8_string.hpp +38 -0
  163. data/ext/libsass/src/util.cpp +723 -0
  164. data/ext/libsass/src/util.hpp +105 -0
  165. data/ext/libsass/src/util_string.cpp +125 -0
  166. data/ext/libsass/src/util_string.hpp +73 -0
  167. data/ext/libsass/src/values.cpp +140 -0
  168. data/ext/libsass/src/values.hpp +12 -0
  169. data/lib/sassc/dependency.rb +17 -0
  170. data/lib/sassc/engine.rb +141 -0
  171. data/lib/sassc/error.rb +37 -0
  172. data/lib/sassc/functions_handler.rb +73 -0
  173. data/lib/sassc/import_handler.rb +50 -0
  174. data/lib/sassc/importer.rb +31 -0
  175. data/lib/sassc/native/native_context_api.rb +147 -0
  176. data/lib/sassc/native/native_functions_api.rb +159 -0
  177. data/lib/sassc/native/sass2scss_api.rb +10 -0
  178. data/lib/sassc/native/sass_input_style.rb +13 -0
  179. data/lib/sassc/native/sass_output_style.rb +12 -0
  180. data/lib/sassc/native/sass_value.rb +97 -0
  181. data/lib/sassc/native/string_list.rb +10 -0
  182. data/lib/sassc/native.rb +64 -0
  183. data/lib/sassc/sass_2_scss.rb +9 -0
  184. data/lib/sassc/script/functions.rb +8 -0
  185. data/lib/sassc/script/value/bool.rb +32 -0
  186. data/lib/sassc/script/value/color.rb +95 -0
  187. data/lib/sassc/script/value/list.rb +136 -0
  188. data/lib/sassc/script/value/map.rb +69 -0
  189. data/lib/sassc/script/value/number.rb +389 -0
  190. data/lib/sassc/script/value/string.rb +96 -0
  191. data/lib/sassc/script/value.rb +137 -0
  192. data/lib/sassc/script/value_conversion/base.rb +13 -0
  193. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  194. data/lib/sassc/script/value_conversion/color.rb +18 -0
  195. data/lib/sassc/script/value_conversion/list.rb +25 -0
  196. data/lib/sassc/script/value_conversion/map.rb +21 -0
  197. data/lib/sassc/script/value_conversion/number.rb +13 -0
  198. data/lib/sassc/script/value_conversion/string.rb +17 -0
  199. data/lib/sassc/script/value_conversion.rb +69 -0
  200. data/lib/sassc/script.rb +17 -0
  201. data/lib/sassc/util/normalized_map.rb +117 -0
  202. data/lib/sassc/util.rb +231 -0
  203. data/lib/sassc/version.rb +5 -0
  204. data/lib/sassc.rb +57 -0
  205. data/sassc.gemspec +69 -0
  206. data/test/css_color_level4_test.rb +168 -0
  207. data/test/custom_importer_test.rb +127 -0
  208. data/test/engine_test.rb +314 -0
  209. data/test/error_test.rb +29 -0
  210. data/test/fixtures/paths.scss +10 -0
  211. data/test/functions_test.rb +340 -0
  212. data/test/native_test.rb +213 -0
  213. data/test/output_style_test.rb +107 -0
  214. data/test/sass_2_scss_test.rb +14 -0
  215. data/test/test_helper.rb +45 -0
  216. metadata +396 -0
@@ -0,0 +1,1154 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+ #include "ast.hpp"
5
+
6
+ namespace Sass {
7
+
8
+ void str_rtrim(sass::string& str, const sass::string& delimiters = " \f\n\r\t\v")
9
+ {
10
+ str.erase( str.find_last_not_of( delimiters ) + 1 );
11
+ }
12
+
13
+ /////////////////////////////////////////////////////////////////////////
14
+ /////////////////////////////////////////////////////////////////////////
15
+
16
+ PreValue::PreValue(SourceSpan pstate, bool d, bool e, bool i, Type ct)
17
+ : Expression(pstate, d, e, i, ct)
18
+ { }
19
+ PreValue::PreValue(const PreValue* ptr)
20
+ : Expression(ptr)
21
+ { }
22
+
23
+ /////////////////////////////////////////////////////////////////////////
24
+ /////////////////////////////////////////////////////////////////////////
25
+
26
+ Value::Value(SourceSpan pstate, bool d, bool e, bool i, Type ct)
27
+ : PreValue(pstate, d, e, i, ct)
28
+ { }
29
+ Value::Value(const Value* ptr)
30
+ : PreValue(ptr)
31
+ { }
32
+
33
+ /////////////////////////////////////////////////////////////////////////
34
+ /////////////////////////////////////////////////////////////////////////
35
+
36
+ List::List(SourceSpan pstate, size_t size, enum Sass_Separator sep, bool argl, bool bracket)
37
+ : Value(pstate),
38
+ Vectorized<ExpressionObj>(size),
39
+ separator_(sep),
40
+ is_arglist_(argl),
41
+ is_bracketed_(bracket),
42
+ from_selector_(false)
43
+ { concrete_type(LIST); }
44
+
45
+ List::List(const List* ptr)
46
+ : Value(ptr),
47
+ Vectorized<ExpressionObj>(*ptr),
48
+ separator_(ptr->separator_),
49
+ is_arglist_(ptr->is_arglist_),
50
+ is_bracketed_(ptr->is_bracketed_),
51
+ from_selector_(ptr->from_selector_)
52
+ { concrete_type(LIST); }
53
+
54
+ size_t List::hash() const
55
+ {
56
+ if (hash_ == 0) {
57
+ hash_ = std::hash<sass::string>()(sep_string());
58
+ hash_combine(hash_, std::hash<bool>()(is_bracketed()));
59
+ for (size_t i = 0, L = length(); i < L; ++i)
60
+ hash_combine(hash_, (elements()[i])->hash());
61
+ }
62
+ return hash_;
63
+ }
64
+
65
+ void List::set_delayed(bool delayed)
66
+ {
67
+ is_delayed(delayed);
68
+ // don't set children
69
+ }
70
+
71
+ bool List::operator< (const Expression& rhs) const
72
+ {
73
+ if (auto r = Cast<List>(&rhs)) {
74
+ if (length() < r->length()) return true;
75
+ if (length() > r->length()) return false;
76
+ const auto& left = elements();
77
+ const auto& right = r->elements();
78
+ for (size_t i = 0; i < left.size(); i += 1) {
79
+ if (*left[i] < *right[i]) return true;
80
+ if (*left[i] == *right[i]) continue;
81
+ return false;
82
+ }
83
+ return false;
84
+ }
85
+ // compare/sort by type
86
+ return type() < rhs.type();
87
+ }
88
+
89
+ bool List::operator== (const Expression& rhs) const
90
+ {
91
+ if (auto r = Cast<List>(&rhs)) {
92
+ if (length() != r->length()) return false;
93
+ if (separator() != r->separator()) return false;
94
+ if (is_bracketed() != r->is_bracketed()) return false;
95
+ for (size_t i = 0, L = length(); i < L; ++i) {
96
+ auto rv = r->at(i);
97
+ auto lv = this->at(i);
98
+ if (!lv && rv) return false;
99
+ else if (!rv && lv) return false;
100
+ else if (*lv != *rv) return false;
101
+ }
102
+ return true;
103
+ }
104
+ return false;
105
+ }
106
+
107
+ size_t List::size() const {
108
+ if (!is_arglist_) return length();
109
+ // arglist expects a list of arguments
110
+ // so we need to break before keywords
111
+ for (size_t i = 0, L = length(); i < L; ++i) {
112
+ ExpressionObj obj = this->at(i);
113
+ if (Argument* arg = Cast<Argument>(obj)) {
114
+ if (!arg->name().empty()) return i;
115
+ }
116
+ }
117
+ return length();
118
+ }
119
+
120
+
121
+ ExpressionObj List::value_at_index(size_t i) {
122
+ ExpressionObj obj = this->at(i);
123
+ if (is_arglist_) {
124
+ if (Argument* arg = Cast<Argument>(obj)) {
125
+ return arg->value();
126
+ } else {
127
+ return obj;
128
+ }
129
+ } else {
130
+ return obj;
131
+ }
132
+ }
133
+
134
+ /////////////////////////////////////////////////////////////////////////
135
+ /////////////////////////////////////////////////////////////////////////
136
+
137
+ Map::Map(SourceSpan pstate, size_t size)
138
+ : Value(pstate),
139
+ Hashed(size)
140
+ { concrete_type(MAP); }
141
+
142
+ Map::Map(const Map* ptr)
143
+ : Value(ptr),
144
+ Hashed(*ptr)
145
+ { concrete_type(MAP); }
146
+
147
+ bool Map::operator< (const Expression& rhs) const
148
+ {
149
+ if (auto r = Cast<Map>(&rhs)) {
150
+ if (length() < r->length()) return true;
151
+ if (length() > r->length()) return false;
152
+ const auto& lkeys = keys();
153
+ const auto& rkeys = r->keys();
154
+ for (size_t i = 0; i < lkeys.size(); i += 1) {
155
+ if (*lkeys[i] < *rkeys[i]) return true;
156
+ if (*lkeys[i] == *rkeys[i]) continue;
157
+ return false;
158
+ }
159
+ const auto& lvals = values();
160
+ const auto& rvals = r->values();
161
+ for (size_t i = 0; i < lvals.size(); i += 1) {
162
+ if (*lvals[i] < *rvals[i]) return true;
163
+ if (*lvals[i] == *rvals[i]) continue;
164
+ return false;
165
+ }
166
+ return false;
167
+ }
168
+ // compare/sort by type
169
+ return type() < rhs.type();
170
+ }
171
+
172
+ bool Map::operator== (const Expression& rhs) const
173
+ {
174
+ if (auto r = Cast<Map>(&rhs)) {
175
+ if (length() != r->length()) return false;
176
+ for (auto key : keys()) {
177
+ auto rv = r->at(key);
178
+ auto lv = this->at(key);
179
+ if (!lv && rv) return false;
180
+ else if (!rv && lv) return false;
181
+ else if (*lv != *rv) return false;
182
+ }
183
+ return true;
184
+ }
185
+ return false;
186
+ }
187
+
188
+ List_Obj Map::to_list(SourceSpan& pstate) {
189
+ List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);
190
+
191
+ for (auto key : keys()) {
192
+ List_Obj l = SASS_MEMORY_NEW(List, pstate, 2);
193
+ l->append(key);
194
+ l->append(at(key));
195
+ ret->append(l);
196
+ }
197
+
198
+ return ret;
199
+ }
200
+
201
+ size_t Map::hash() const
202
+ {
203
+ if (hash_ == 0) {
204
+ for (auto key : keys()) {
205
+ hash_combine(hash_, key->hash());
206
+ hash_combine(hash_, at(key)->hash());
207
+ }
208
+ }
209
+
210
+ return hash_;
211
+ }
212
+
213
+ /////////////////////////////////////////////////////////////////////////
214
+ /////////////////////////////////////////////////////////////////////////
215
+
216
+ Binary_Expression::Binary_Expression(SourceSpan pstate,
217
+ Operand op, ExpressionObj lhs, ExpressionObj rhs)
218
+ : PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)
219
+ { }
220
+
221
+ Binary_Expression::Binary_Expression(const Binary_Expression* ptr)
222
+ : PreValue(ptr),
223
+ op_(ptr->op_),
224
+ left_(ptr->left_),
225
+ right_(ptr->right_),
226
+ hash_(ptr->hash_)
227
+ { }
228
+
229
+ bool Binary_Expression::is_left_interpolant(void) const
230
+ {
231
+ return is_interpolant() || (left() && left()->is_left_interpolant());
232
+ }
233
+ bool Binary_Expression::is_right_interpolant(void) const
234
+ {
235
+ return is_interpolant() || (right() && right()->is_right_interpolant());
236
+ }
237
+
238
+ const sass::string Binary_Expression::type_name()
239
+ {
240
+ return sass_op_to_name(optype());
241
+ }
242
+
243
+ const sass::string Binary_Expression::separator()
244
+ {
245
+ return sass_op_separator(optype());
246
+ }
247
+
248
+ bool Binary_Expression::has_interpolant() const
249
+ {
250
+ return is_left_interpolant() ||
251
+ is_right_interpolant();
252
+ }
253
+
254
+ void Binary_Expression::set_delayed(bool delayed)
255
+ {
256
+ right()->set_delayed(delayed);
257
+ left()->set_delayed(delayed);
258
+ is_delayed(delayed);
259
+ }
260
+
261
+ bool Binary_Expression::operator<(const Expression& rhs) const
262
+ {
263
+ if (auto m = Cast<Binary_Expression>(&rhs)) {
264
+ return type() < m->type() ||
265
+ *left() < *m->left() ||
266
+ *right() < *m->right();
267
+ }
268
+ // compare/sort by type
269
+ return type() < rhs.type();
270
+ }
271
+
272
+ bool Binary_Expression::operator==(const Expression& rhs) const
273
+ {
274
+ if (auto m = Cast<Binary_Expression>(&rhs)) {
275
+ return type() == m->type() &&
276
+ *left() == *m->left() &&
277
+ *right() == *m->right();
278
+ }
279
+ return false;
280
+ }
281
+
282
+ size_t Binary_Expression::hash() const
283
+ {
284
+ if (hash_ == 0) {
285
+ hash_ = std::hash<size_t>()(optype());
286
+ hash_combine(hash_, left()->hash());
287
+ hash_combine(hash_, right()->hash());
288
+ }
289
+ return hash_;
290
+ }
291
+
292
+ /////////////////////////////////////////////////////////////////////////
293
+ /////////////////////////////////////////////////////////////////////////
294
+
295
+ Function::Function(SourceSpan pstate, Definition_Obj def, bool css)
296
+ : Value(pstate), definition_(def), is_css_(css)
297
+ { concrete_type(FUNCTION_VAL); }
298
+
299
+ Function::Function(const Function* ptr)
300
+ : Value(ptr), definition_(ptr->definition_), is_css_(ptr->is_css_)
301
+ { concrete_type(FUNCTION_VAL); }
302
+
303
+ bool Function::operator< (const Expression& rhs) const
304
+ {
305
+ if (auto r = Cast<Function>(&rhs)) {
306
+ auto d1 = Cast<Definition>(definition());
307
+ auto d2 = Cast<Definition>(r->definition());
308
+ if (d1 == nullptr) return d2 != nullptr;
309
+ else if (d2 == nullptr) return false;
310
+ if (is_css() == r->is_css()) {
311
+ return d1 < d2;
312
+ }
313
+ return r->is_css();
314
+ }
315
+ // compare/sort by type
316
+ return type() < rhs.type();
317
+ }
318
+
319
+ bool Function::operator== (const Expression& rhs) const
320
+ {
321
+ if (auto r = Cast<Function>(&rhs)) {
322
+ auto d1 = Cast<Definition>(definition());
323
+ auto d2 = Cast<Definition>(r->definition());
324
+ return d1 && d2 && d1 == d2 && is_css() == r->is_css();
325
+ }
326
+ return false;
327
+ }
328
+
329
+ sass::string Function::name() {
330
+ if (definition_) {
331
+ return definition_->name();
332
+ }
333
+ return "";
334
+ }
335
+
336
+ /////////////////////////////////////////////////////////////////////////
337
+ /////////////////////////////////////////////////////////////////////////
338
+
339
+ Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, void* cookie)
340
+ : PreValue(pstate), sname_(n), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)
341
+ { concrete_type(FUNCTION); }
342
+ Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, Function_Obj func)
343
+ : PreValue(pstate), sname_(n), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
344
+ { concrete_type(FUNCTION); }
345
+ Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args)
346
+ : PreValue(pstate), sname_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)
347
+ { concrete_type(FUNCTION); }
348
+
349
+ Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, void* cookie)
350
+ : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)
351
+ { concrete_type(FUNCTION); }
352
+ Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Function_Obj func)
353
+ : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
354
+ { concrete_type(FUNCTION); }
355
+ Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args)
356
+ : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), via_call_(false), cookie_(0), hash_(0)
357
+ { concrete_type(FUNCTION); }
358
+
359
+ Function_Call::Function_Call(const Function_Call* ptr)
360
+ : PreValue(ptr),
361
+ sname_(ptr->sname_),
362
+ arguments_(ptr->arguments_),
363
+ func_(ptr->func_),
364
+ via_call_(ptr->via_call_),
365
+ cookie_(ptr->cookie_),
366
+ hash_(ptr->hash_)
367
+ { concrete_type(FUNCTION); }
368
+
369
+ bool Function_Call::operator==(const Expression& rhs) const
370
+ {
371
+ if (auto m = Cast<Function_Call>(&rhs)) {
372
+ if (*sname() != *m->sname()) return false;
373
+ if (arguments()->length() != m->arguments()->length()) return false;
374
+ for (size_t i = 0, L = arguments()->length(); i < L; ++i)
375
+ if (*arguments()->get(i) != *m->arguments()->get(i)) return false;
376
+ return true;
377
+ }
378
+ return false;
379
+ }
380
+
381
+ size_t Function_Call::hash() const
382
+ {
383
+ if (hash_ == 0) {
384
+ hash_ = std::hash<sass::string>()(name());
385
+ for (auto argument : arguments()->elements())
386
+ hash_combine(hash_, argument->hash());
387
+ }
388
+ return hash_;
389
+ }
390
+
391
+ sass::string Function_Call::name() const
392
+ {
393
+ return sname();
394
+ }
395
+
396
+ bool Function_Call::is_css() {
397
+ if (func_) return func_->is_css();
398
+ return false;
399
+ }
400
+
401
+ /////////////////////////////////////////////////////////////////////////
402
+ /////////////////////////////////////////////////////////////////////////
403
+
404
+ Variable::Variable(SourceSpan pstate, sass::string n)
405
+ : PreValue(pstate), name_(n)
406
+ { concrete_type(VARIABLE); }
407
+
408
+ Variable::Variable(const Variable* ptr)
409
+ : PreValue(ptr), name_(ptr->name_)
410
+ { concrete_type(VARIABLE); }
411
+
412
+ bool Variable::operator==(const Expression& rhs) const
413
+ {
414
+ if (auto e = Cast<Variable>(&rhs)) {
415
+ return name() == e->name();
416
+ }
417
+ return false;
418
+ }
419
+
420
+ size_t Variable::hash() const
421
+ {
422
+ return std::hash<sass::string>()(name());
423
+ }
424
+
425
+ /////////////////////////////////////////////////////////////////////////
426
+ /////////////////////////////////////////////////////////////////////////
427
+
428
+ Number::Number(SourceSpan pstate, double val, sass::string u, bool zero)
429
+ : Value(pstate),
430
+ Units(),
431
+ value_(val),
432
+ zero_(zero),
433
+ hash_(0)
434
+ {
435
+ size_t l = 0;
436
+ size_t r;
437
+ if (!u.empty()) {
438
+ bool nominator = true;
439
+ while (true) {
440
+ r = u.find_first_of("*/", l);
441
+ sass::string unit(u.substr(l, r == sass::string::npos ? r : r - l));
442
+ if (!unit.empty()) {
443
+ if (nominator) numerators.push_back(unit);
444
+ else denominators.push_back(unit);
445
+ }
446
+ if (r == sass::string::npos) break;
447
+ // ToDo: should error for multiple slashes
448
+ // if (!nominator && u[r] == '/') error(...)
449
+ if (u[r] == '/')
450
+ nominator = false;
451
+ // strange math parsing?
452
+ // else if (u[r] == '*')
453
+ // nominator = true;
454
+ l = r + 1;
455
+ }
456
+ }
457
+ concrete_type(NUMBER);
458
+ }
459
+
460
+ Number::Number(const Number* ptr)
461
+ : Value(ptr),
462
+ Units(ptr),
463
+ value_(ptr->value_), zero_(ptr->zero_),
464
+ hash_(ptr->hash_)
465
+ { concrete_type(NUMBER); }
466
+
467
+ // cancel out unnecessary units
468
+ void Number::reduce()
469
+ {
470
+ // apply conversion factor
471
+ value_ *= this->Units::reduce();
472
+ }
473
+
474
+ void Number::normalize()
475
+ {
476
+ // apply conversion factor
477
+ value_ *= this->Units::normalize();
478
+ }
479
+
480
+ size_t Number::hash() const
481
+ {
482
+ if (hash_ == 0) {
483
+ hash_ = std::hash<double>()(value_);
484
+ for (const auto& numerator : numerators)
485
+ hash_combine(hash_, std::hash<sass::string>()(numerator));
486
+ for (const auto& denominator : denominators)
487
+ hash_combine(hash_, std::hash<sass::string>()(denominator));
488
+ }
489
+ return hash_;
490
+ }
491
+
492
+ bool Number::operator< (const Expression& rhs) const
493
+ {
494
+ if (auto n = Cast<Number>(&rhs)) {
495
+ return *this < *n;
496
+ }
497
+ return false;
498
+ }
499
+
500
+ bool Number::operator== (const Expression& rhs) const
501
+ {
502
+ if (auto n = Cast<Number>(&rhs)) {
503
+ return *this == *n;
504
+ }
505
+ return false;
506
+ }
507
+
508
+ bool Number::operator== (const Number& rhs) const
509
+ {
510
+ // unitless or only having one unit are equivalent (3.4)
511
+ // therefore we need to reduce the units beforehand
512
+ Number l(*this), r(rhs); l.reduce(); r.reduce();
513
+ size_t lhs_units = l.numerators.size() + l.denominators.size();
514
+ size_t rhs_units = r.numerators.size() + r.denominators.size();
515
+ if (!lhs_units || !rhs_units) {
516
+ return NEAR_EQUAL(l.value(), r.value());
517
+ }
518
+ // ensure both have same units
519
+ l.normalize(); r.normalize();
520
+ Units &lhs_unit = l, &rhs_unit = r;
521
+ return lhs_unit == rhs_unit &&
522
+ NEAR_EQUAL(l.value(), r.value());
523
+ }
524
+
525
+ bool Number::operator< (const Number& rhs) const
526
+ {
527
+ // unitless or only having one unit are equivalent (3.4)
528
+ // therefore we need to reduce the units beforehand
529
+ Number l(*this), r(rhs); l.reduce(); r.reduce();
530
+ size_t lhs_units = l.numerators.size() + l.denominators.size();
531
+ size_t rhs_units = r.numerators.size() + r.denominators.size();
532
+ if (!lhs_units || !rhs_units) {
533
+ return l.value() < r.value();
534
+ }
535
+ // ensure both have same units
536
+ l.normalize(); r.normalize();
537
+ Units &lhs_unit = l, &rhs_unit = r;
538
+ if (!(lhs_unit == rhs_unit)) {
539
+ /* ToDo: do we always get useful backtraces? */
540
+ throw Exception::IncompatibleUnits(rhs, *this);
541
+ }
542
+ if (lhs_unit == rhs_unit) {
543
+ return l.value() < r.value();
544
+ } else {
545
+ return lhs_unit < rhs_unit;
546
+ }
547
+ }
548
+
549
+ /////////////////////////////////////////////////////////////////////////
550
+ /////////////////////////////////////////////////////////////////////////
551
+
552
+ Color::Color(SourceSpan pstate, double a, const sass::string disp)
553
+ : Value(pstate),
554
+ disp_(disp), a_(a),
555
+ hash_(0)
556
+ { concrete_type(COLOR); }
557
+
558
+ Color::Color(const Color* ptr)
559
+ : Value(ptr->pstate()),
560
+ // reset on copy
561
+ disp_(""),
562
+ a_(ptr->a_),
563
+ hash_(ptr->hash_)
564
+ { concrete_type(COLOR); }
565
+
566
+ bool Color::operator< (const Expression& rhs) const
567
+ {
568
+ if (auto r = Cast<Color_RGBA>(&rhs)) {
569
+ return *this < *r;
570
+ }
571
+ else if (auto r = Cast<Color_HSLA>(&rhs)) {
572
+ return *this < *r;
573
+ }
574
+ else if (auto r = Cast<Color>(&rhs)) {
575
+ return a_ < r->a();
576
+ }
577
+ // compare/sort by type
578
+ return type() < rhs.type();
579
+ }
580
+
581
+ bool Color::operator== (const Expression& rhs) const
582
+ {
583
+ if (auto r = Cast<Color_RGBA>(&rhs)) {
584
+ return *this == *r;
585
+ }
586
+ else if (auto r = Cast<Color_HSLA>(&rhs)) {
587
+ return *this == *r;
588
+ }
589
+ else if (auto r = Cast<Color>(&rhs)) {
590
+ return a_ == r->a();
591
+ }
592
+ return false;
593
+ }
594
+
595
+ /////////////////////////////////////////////////////////////////////////
596
+ /////////////////////////////////////////////////////////////////////////
597
+
598
+ Color_RGBA::Color_RGBA(SourceSpan pstate, double r, double g, double b, double a, const sass::string disp)
599
+ : Color(pstate, a, disp),
600
+ r_(r), g_(g), b_(b)
601
+ { concrete_type(COLOR); }
602
+
603
+ Color_RGBA::Color_RGBA(const Color_RGBA* ptr)
604
+ : Color(ptr),
605
+ r_(ptr->r_),
606
+ g_(ptr->g_),
607
+ b_(ptr->b_)
608
+ { concrete_type(COLOR); }
609
+
610
+ bool Color_RGBA::operator< (const Expression& rhs) const
611
+ {
612
+ if (auto r = Cast<Color_RGBA>(&rhs)) {
613
+ if (r_ < r->r()) return true;
614
+ if (r_ > r->r()) return false;
615
+ if (g_ < r->g()) return true;
616
+ if (g_ > r->g()) return false;
617
+ if (b_ < r->b()) return true;
618
+ if (b_ > r->b()) return false;
619
+ if (a_ < r->a()) return true;
620
+ if (a_ > r->a()) return false;
621
+ return false; // is equal
622
+ }
623
+ // compare/sort by type
624
+ return type() < rhs.type();
625
+ }
626
+
627
+ bool Color_RGBA::operator== (const Expression& rhs) const
628
+ {
629
+ if (auto r = Cast<Color_RGBA>(&rhs)) {
630
+ return r_ == r->r() &&
631
+ g_ == r->g() &&
632
+ b_ == r->b() &&
633
+ a_ == r->a();
634
+ }
635
+ return false;
636
+ }
637
+
638
+ size_t Color_RGBA::hash() const
639
+ {
640
+ if (hash_ == 0) {
641
+ hash_ = std::hash<sass::string>()("RGBA");
642
+ hash_combine(hash_, std::hash<double>()(a_));
643
+ hash_combine(hash_, std::hash<double>()(r_));
644
+ hash_combine(hash_, std::hash<double>()(g_));
645
+ hash_combine(hash_, std::hash<double>()(b_));
646
+ }
647
+ return hash_;
648
+ }
649
+
650
+ Color_HSLA* Color_RGBA::copyAsHSLA() const
651
+ {
652
+
653
+ // Algorithm from http://en.wikipedia.org/wiki/wHSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
654
+ double r = r_ / 255.0;
655
+ double g = g_ / 255.0;
656
+ double b = b_ / 255.0;
657
+
658
+ double max = std::max(r, std::max(g, b));
659
+ double min = std::min(r, std::min(g, b));
660
+ double delta = max - min;
661
+
662
+ double h = 0;
663
+ double s;
664
+ double l = (max + min) / 2.0;
665
+
666
+ if (NEAR_EQUAL(max, min)) {
667
+ h = s = 0; // achromatic
668
+ }
669
+ else {
670
+ if (l < 0.5) s = delta / (max + min);
671
+ else s = delta / (2.0 - max - min);
672
+
673
+ if (r == max) h = (g - b) / delta + (g < b ? 6 : 0);
674
+ else if (g == max) h = (b - r) / delta + 2;
675
+ else if (b == max) h = (r - g) / delta + 4;
676
+ }
677
+
678
+ // HSL hsl_struct;
679
+ h = h * 60;
680
+ s = s * 100;
681
+ l = l * 100;
682
+
683
+ return SASS_MEMORY_NEW(Color_HSLA,
684
+ pstate(), h, s, l, a(), ""
685
+ );
686
+ }
687
+
688
+ Color_RGBA* Color_RGBA::copyAsRGBA() const
689
+ {
690
+ return SASS_MEMORY_COPY(this);
691
+ }
692
+
693
+ /////////////////////////////////////////////////////////////////////////
694
+ /////////////////////////////////////////////////////////////////////////
695
+
696
+ Color_HSLA::Color_HSLA(SourceSpan pstate, double h, double s, double l, double a, const sass::string disp)
697
+ : Color(pstate, a, disp),
698
+ h_(absmod(h, 360.0)),
699
+ s_(clip(s, 0.0, 100.0)),
700
+ l_(clip(l, 0.0, 100.0))
701
+ // hash_(0)
702
+ { concrete_type(COLOR); }
703
+
704
+ Color_HSLA::Color_HSLA(const Color_HSLA* ptr)
705
+ : Color(ptr),
706
+ h_(ptr->h_),
707
+ s_(ptr->s_),
708
+ l_(ptr->l_)
709
+ // hash_(ptr->hash_)
710
+ { concrete_type(COLOR); }
711
+
712
+ bool Color_HSLA::operator< (const Expression& rhs) const
713
+ {
714
+ if (auto r = Cast<Color_HSLA>(&rhs)) {
715
+ if (h_ < r->h()) return true;
716
+ if (h_ > r->h()) return false;
717
+ if (s_ < r->s()) return true;
718
+ if (s_ > r->s()) return false;
719
+ if (l_ < r->l()) return true;
720
+ if (l_ > r->l()) return false;
721
+ if (a_ < r->a()) return true;
722
+ if (a_ > r->a()) return false;
723
+ return false; // is equal
724
+ }
725
+ // compare/sort by type
726
+ return type() < rhs.type();
727
+ }
728
+
729
+ bool Color_HSLA::operator== (const Expression& rhs) const
730
+ {
731
+ if (auto r = Cast<Color_HSLA>(&rhs)) {
732
+ return h_ == r->h() &&
733
+ s_ == r->s() &&
734
+ l_ == r->l() &&
735
+ a_ == r->a();
736
+ }
737
+ return false;
738
+ }
739
+
740
+ size_t Color_HSLA::hash() const
741
+ {
742
+ if (hash_ == 0) {
743
+ hash_ = std::hash<sass::string>()("HSLA");
744
+ hash_combine(hash_, std::hash<double>()(a_));
745
+ hash_combine(hash_, std::hash<double>()(h_));
746
+ hash_combine(hash_, std::hash<double>()(s_));
747
+ hash_combine(hash_, std::hash<double>()(l_));
748
+ }
749
+ return hash_;
750
+ }
751
+
752
+ // hue to RGB helper function
753
+ double h_to_rgb(double m1, double m2, double h)
754
+ {
755
+ h = absmod(h, 1.0);
756
+ if (h*6.0 < 1) return m1 + (m2 - m1)*h*6;
757
+ if (h*2.0 < 1) return m2;
758
+ if (h*3.0 < 2) return m1 + (m2 - m1) * (2.0/3.0 - h)*6;
759
+ return m1;
760
+ }
761
+
762
+ Color_RGBA* Color_HSLA::copyAsRGBA() const
763
+ {
764
+
765
+ double h = absmod(h_ / 360.0, 1.0);
766
+ double s = clip(s_ / 100.0, 0.0, 1.0);
767
+ double l = clip(l_ / 100.0, 0.0, 1.0);
768
+
769
+ // Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color.
770
+ double m2;
771
+ if (l <= 0.5) m2 = l*(s+1.0);
772
+ else m2 = (l+s)-(l*s);
773
+ double m1 = (l*2.0)-m2;
774
+ // round the results -- consider moving this into the Color constructor
775
+ double r = (h_to_rgb(m1, m2, h + 1.0/3.0) * 255.0);
776
+ double g = (h_to_rgb(m1, m2, h) * 255.0);
777
+ double b = (h_to_rgb(m1, m2, h - 1.0/3.0) * 255.0);
778
+
779
+ return SASS_MEMORY_NEW(Color_RGBA,
780
+ pstate(), r, g, b, a(), ""
781
+ );
782
+ }
783
+
784
+ Color_HSLA* Color_HSLA::copyAsHSLA() const
785
+ {
786
+ return SASS_MEMORY_COPY(this);
787
+ }
788
+
789
+ /////////////////////////////////////////////////////////////////////////
790
+ /////////////////////////////////////////////////////////////////////////
791
+
792
+ Custom_Error::Custom_Error(SourceSpan pstate, sass::string msg)
793
+ : Value(pstate), message_(msg)
794
+ { concrete_type(C_ERROR); }
795
+
796
+ Custom_Error::Custom_Error(const Custom_Error* ptr)
797
+ : Value(ptr), message_(ptr->message_)
798
+ { concrete_type(C_ERROR); }
799
+
800
+ bool Custom_Error::operator< (const Expression& rhs) const
801
+ {
802
+ if (auto r = Cast<Custom_Error>(&rhs)) {
803
+ return message() < r->message();
804
+ }
805
+ // compare/sort by type
806
+ return type() < rhs.type();
807
+ }
808
+
809
+ bool Custom_Error::operator== (const Expression& rhs) const
810
+ {
811
+ if (auto r = Cast<Custom_Error>(&rhs)) {
812
+ return message() == r->message();
813
+ }
814
+ return false;
815
+ }
816
+
817
+ /////////////////////////////////////////////////////////////////////////
818
+ /////////////////////////////////////////////////////////////////////////
819
+
820
+ Custom_Warning::Custom_Warning(SourceSpan pstate, sass::string msg)
821
+ : Value(pstate), message_(msg)
822
+ { concrete_type(C_WARNING); }
823
+
824
+ Custom_Warning::Custom_Warning(const Custom_Warning* ptr)
825
+ : Value(ptr), message_(ptr->message_)
826
+ { concrete_type(C_WARNING); }
827
+
828
+ bool Custom_Warning::operator< (const Expression& rhs) const
829
+ {
830
+ if (auto r = Cast<Custom_Warning>(&rhs)) {
831
+ return message() < r->message();
832
+ }
833
+ // compare/sort by type
834
+ return type() < rhs.type();
835
+ }
836
+
837
+ bool Custom_Warning::operator== (const Expression& rhs) const
838
+ {
839
+ if (auto r = Cast<Custom_Warning>(&rhs)) {
840
+ return message() == r->message();
841
+ }
842
+ return false;
843
+ }
844
+
845
+ /////////////////////////////////////////////////////////////////////////
846
+ /////////////////////////////////////////////////////////////////////////
847
+
848
+ Boolean::Boolean(SourceSpan pstate, bool val)
849
+ : Value(pstate), value_(val),
850
+ hash_(0)
851
+ { concrete_type(BOOLEAN); }
852
+
853
+ Boolean::Boolean(const Boolean* ptr)
854
+ : Value(ptr),
855
+ value_(ptr->value_),
856
+ hash_(ptr->hash_)
857
+ { concrete_type(BOOLEAN); }
858
+
859
+ bool Boolean::operator< (const Expression& rhs) const
860
+ {
861
+ if (auto r = Cast<Boolean>(&rhs)) {
862
+ return (value() < r->value());
863
+ }
864
+ return false;
865
+ }
866
+
867
+ bool Boolean::operator== (const Expression& rhs) const
868
+ {
869
+ if (auto r = Cast<Boolean>(&rhs)) {
870
+ return (value() == r->value());
871
+ }
872
+ return false;
873
+ }
874
+
875
+ size_t Boolean::hash() const
876
+ {
877
+ if (hash_ == 0) {
878
+ hash_ = std::hash<bool>()(value_);
879
+ }
880
+ return hash_;
881
+ }
882
+
883
+ /////////////////////////////////////////////////////////////////////////
884
+ /////////////////////////////////////////////////////////////////////////
885
+
886
+ String::String(SourceSpan pstate, bool delayed)
887
+ : Value(pstate, delayed)
888
+ { concrete_type(STRING); }
889
+ String::String(const String* ptr)
890
+ : Value(ptr)
891
+ { concrete_type(STRING); }
892
+
893
+ /////////////////////////////////////////////////////////////////////////
894
+ /////////////////////////////////////////////////////////////////////////
895
+
896
+ String_Schema::String_Schema(SourceSpan pstate, size_t size, bool css)
897
+ : String(pstate), Vectorized<PreValueObj>(size), css_(css), hash_(0)
898
+ { concrete_type(STRING); }
899
+
900
+ String_Schema::String_Schema(const String_Schema* ptr)
901
+ : String(ptr),
902
+ Vectorized<PreValueObj>(*ptr),
903
+ css_(ptr->css_),
904
+ hash_(ptr->hash_)
905
+ { concrete_type(STRING); }
906
+
907
+ void String_Schema::rtrim()
908
+ {
909
+ if (!empty()) {
910
+ if (String* str = Cast<String>(last())) str->rtrim();
911
+ }
912
+ }
913
+
914
+ bool String_Schema::is_left_interpolant(void) const
915
+ {
916
+ return length() && first()->is_left_interpolant();
917
+ }
918
+ bool String_Schema::is_right_interpolant(void) const
919
+ {
920
+ return length() && last()->is_right_interpolant();
921
+ }
922
+
923
+ bool String_Schema::operator< (const Expression& rhs) const
924
+ {
925
+ if (auto r = Cast<String_Schema>(&rhs)) {
926
+ if (length() < r->length()) return true;
927
+ if (length() > r->length()) return false;
928
+ for (size_t i = 0, L = length(); i < L; ++i) {
929
+ if (*get(i) < *r->get(i)) return true;
930
+ if (*get(i) == *r->get(i)) continue;
931
+ return false;
932
+ }
933
+ // Is equal
934
+ return false;
935
+ }
936
+ // compare/sort by type
937
+ return type() < rhs.type();
938
+ }
939
+
940
+ bool String_Schema::operator== (const Expression& rhs) const
941
+ {
942
+ if (auto r = Cast<String_Schema>(&rhs)) {
943
+ if (length() != r->length()) return false;
944
+ for (size_t i = 0, L = length(); i < L; ++i) {
945
+ auto rv = (*r)[i];
946
+ auto lv = (*this)[i];
947
+ if (*lv != *rv) return false;
948
+ }
949
+ return true;
950
+ }
951
+ return false;
952
+ }
953
+
954
+ bool String_Schema::has_interpolants()
955
+ {
956
+ for (auto el : elements()) {
957
+ if (el->is_interpolant()) return true;
958
+ }
959
+ return false;
960
+ }
961
+
962
+ size_t String_Schema::hash() const
963
+ {
964
+ if (hash_ == 0) {
965
+ for (auto string : elements())
966
+ hash_combine(hash_, string->hash());
967
+ }
968
+ return hash_;
969
+ }
970
+
971
+ void String_Schema::set_delayed(bool delayed)
972
+ {
973
+ is_delayed(delayed);
974
+ }
975
+
976
+ /////////////////////////////////////////////////////////////////////////
977
+ /////////////////////////////////////////////////////////////////////////
978
+
979
+ String_Constant::String_Constant(SourceSpan pstate, sass::string val, bool css)
980
+ : String(pstate), quote_mark_(0), value_(read_css_string(val, css)), hash_(0)
981
+ { }
982
+ String_Constant::String_Constant(SourceSpan pstate, const char* beg, bool css)
983
+ : String(pstate), quote_mark_(0), value_(read_css_string(sass::string(beg), css)), hash_(0)
984
+ { }
985
+ String_Constant::String_Constant(SourceSpan pstate, const char* beg, const char* end, bool css)
986
+ : String(pstate), quote_mark_(0), value_(read_css_string(sass::string(beg, end-beg), css)), hash_(0)
987
+ { }
988
+ String_Constant::String_Constant(SourceSpan pstate, const Token& tok, bool css)
989
+ : String(pstate), quote_mark_(0), value_(read_css_string(sass::string(tok.begin, tok.end), css)), hash_(0)
990
+ { }
991
+
992
+ String_Constant::String_Constant(const String_Constant* ptr)
993
+ : String(ptr),
994
+ quote_mark_(ptr->quote_mark_),
995
+ value_(ptr->value_),
996
+ hash_(ptr->hash_)
997
+ { }
998
+
999
+ bool String_Constant::is_invisible() const {
1000
+ return value_.empty() && quote_mark_ == 0;
1001
+ }
1002
+
1003
+ bool String_Constant::operator< (const Expression& rhs) const
1004
+ {
1005
+ if (auto qstr = Cast<String_Quoted>(&rhs)) {
1006
+ return value() < qstr->value();
1007
+ }
1008
+ else if (auto cstr = Cast<String_Constant>(&rhs)) {
1009
+ return value() < cstr->value();
1010
+ }
1011
+ // compare/sort by type
1012
+ return type() < rhs.type();
1013
+ }
1014
+
1015
+ bool String_Constant::operator== (const Expression& rhs) const
1016
+ {
1017
+ if (auto qstr = Cast<String_Quoted>(&rhs)) {
1018
+ return value() == qstr->value();
1019
+ }
1020
+ else if (auto cstr = Cast<String_Constant>(&rhs)) {
1021
+ return value() == cstr->value();
1022
+ }
1023
+ return false;
1024
+ }
1025
+
1026
+ sass::string String_Constant::inspect() const
1027
+ {
1028
+ return quote(value_, '*');
1029
+ }
1030
+
1031
+ void String_Constant::rtrim()
1032
+ {
1033
+ str_rtrim(value_);
1034
+ }
1035
+
1036
+ size_t String_Constant::hash() const
1037
+ {
1038
+ if (hash_ == 0) {
1039
+ hash_ = std::hash<sass::string>()(value_);
1040
+ }
1041
+ return hash_;
1042
+ }
1043
+
1044
+ /////////////////////////////////////////////////////////////////////////
1045
+ /////////////////////////////////////////////////////////////////////////
1046
+
1047
+ String_Quoted::String_Quoted(SourceSpan pstate, sass::string val, char q,
1048
+ bool keep_utf8_escapes, bool skip_unquoting,
1049
+ bool strict_unquoting, bool css)
1050
+ : String_Constant(pstate, val, css)
1051
+ {
1052
+ if (skip_unquoting == false) {
1053
+ value_ = unquote(value_, &quote_mark_, keep_utf8_escapes, strict_unquoting);
1054
+ }
1055
+ if (q && quote_mark_) quote_mark_ = q;
1056
+ }
1057
+
1058
+ String_Quoted::String_Quoted(const String_Quoted* ptr)
1059
+ : String_Constant(ptr)
1060
+ { }
1061
+
1062
+ bool String_Quoted::operator< (const Expression& rhs) const
1063
+ {
1064
+ if (auto qstr = Cast<String_Quoted>(&rhs)) {
1065
+ return value() < qstr->value();
1066
+ }
1067
+ else if (auto cstr = Cast<String_Constant>(&rhs)) {
1068
+ return value() < cstr->value();
1069
+ }
1070
+ // compare/sort by type
1071
+ return type() < rhs.type();
1072
+ }
1073
+
1074
+ bool String_Quoted::operator== (const Expression& rhs) const
1075
+ {
1076
+ if (auto qstr = Cast<String_Quoted>(&rhs)) {
1077
+ return value() == qstr->value();
1078
+ }
1079
+ else if (auto cstr = Cast<String_Constant>(&rhs)) {
1080
+ return value() == cstr->value();
1081
+ }
1082
+ return false;
1083
+ }
1084
+
1085
+ sass::string String_Quoted::inspect() const
1086
+ {
1087
+ return quote(value_, '*');
1088
+ }
1089
+
1090
+ /////////////////////////////////////////////////////////////////////////
1091
+ /////////////////////////////////////////////////////////////////////////
1092
+
1093
+ Null::Null(SourceSpan pstate)
1094
+ : Value(pstate)
1095
+ { concrete_type(NULL_VAL); }
1096
+
1097
+ Null::Null(const Null* ptr) : Value(ptr)
1098
+ { concrete_type(NULL_VAL); }
1099
+
1100
+ bool Null::operator< (const Expression& rhs) const
1101
+ {
1102
+ if (Cast<Null>(&rhs)) {
1103
+ return false;
1104
+ }
1105
+ // compare/sort by type
1106
+ return type() < rhs.type();
1107
+ }
1108
+
1109
+ bool Null::operator== (const Expression& rhs) const
1110
+ {
1111
+ return Cast<Null>(&rhs) != nullptr;
1112
+ }
1113
+
1114
+ size_t Null::hash() const
1115
+ {
1116
+ return -1;
1117
+ }
1118
+
1119
+ /////////////////////////////////////////////////////////////////////////
1120
+ /////////////////////////////////////////////////////////////////////////
1121
+
1122
+ Parent_Reference::Parent_Reference(SourceSpan pstate)
1123
+ : Value(pstate)
1124
+ { concrete_type(PARENT); }
1125
+
1126
+ Parent_Reference::Parent_Reference(const Parent_Reference* ptr)
1127
+ : Value(ptr)
1128
+ { concrete_type(PARENT); }
1129
+
1130
+ /////////////////////////////////////////////////////////////////////////
1131
+ /////////////////////////////////////////////////////////////////////////
1132
+
1133
+ IMPLEMENT_AST_OPERATORS(List);
1134
+ IMPLEMENT_AST_OPERATORS(Map);
1135
+ IMPLEMENT_AST_OPERATORS(Binary_Expression);
1136
+ IMPLEMENT_AST_OPERATORS(Function);
1137
+ IMPLEMENT_AST_OPERATORS(Function_Call);
1138
+ IMPLEMENT_AST_OPERATORS(Variable);
1139
+ IMPLEMENT_AST_OPERATORS(Number);
1140
+ IMPLEMENT_AST_OPERATORS(Color_RGBA);
1141
+ IMPLEMENT_AST_OPERATORS(Color_HSLA);
1142
+ IMPLEMENT_AST_OPERATORS(Custom_Error);
1143
+ IMPLEMENT_AST_OPERATORS(Custom_Warning);
1144
+ IMPLEMENT_AST_OPERATORS(Boolean);
1145
+ IMPLEMENT_AST_OPERATORS(String_Schema);
1146
+ IMPLEMENT_AST_OPERATORS(String_Constant);
1147
+ IMPLEMENT_AST_OPERATORS(String_Quoted);
1148
+ IMPLEMENT_AST_OPERATORS(Null);
1149
+ IMPLEMENT_AST_OPERATORS(Parent_Reference);
1150
+
1151
+ /////////////////////////////////////////////////////////////////////////
1152
+ /////////////////////////////////////////////////////////////////////////
1153
+
1154
+ }