sassc 2.2.1 → 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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/Rakefile +1 -3
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +4 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +158 -168
- data/ext/libsass/src/ast.hpp +389 -230
- data/ext/libsass/src/ast_def_macros.hpp +18 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +594 -1026
- data/ext/libsass/src/ast_selectors.hpp +339 -385
- data/ext/libsass/src/ast_supports.cpp +36 -52
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +271 -84
- data/ext/libsass/src/ast_values.hpp +116 -107
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +18 -18
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +40 -41
- data/ext/libsass/src/check_nesting.hpp +6 -2
- data/ext/libsass/src/color_maps.cpp +14 -13
- data/ext/libsass/src/color_maps.hpp +1 -9
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +92 -119
- data/ext/libsass/src/context.hpp +41 -53
- data/ext/libsass/src/cssize.cpp +66 -149
- data/ext/libsass/src/cssize.hpp +17 -23
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +451 -295
- data/ext/libsass/src/emitter.cpp +15 -16
- data/ext/libsass/src/emitter.hpp +10 -12
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +29 -24
- data/ext/libsass/src/error_handling.cpp +62 -41
- data/ext/libsass/src/error_handling.hpp +61 -51
- data/ext/libsass/src/eval.cpp +167 -281
- data/ext/libsass/src/eval.hpp +27 -29
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +275 -222
- data/ext/libsass/src/expand.hpp +36 -16
- data/ext/libsass/src/extender.cpp +1188 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +81 -72
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +20 -18
- data/ext/libsass/src/fn_lists.cpp +30 -29
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +34 -46
- data/ext/libsass/src/fn_numbers.cpp +20 -13
- data/ext/libsass/src/fn_selectors.cpp +98 -128
- data/ext/libsass/src/fn_strings.cpp +47 -33
- data/ext/libsass/src/fn_utils.cpp +31 -29
- data/ext/libsass/src/fn_utils.hpp +17 -11
- data/ext/libsass/src/inspect.cpp +186 -148
- data/ext/libsass/src/inspect.hpp +31 -29
- data/ext/libsass/src/lexer.cpp +20 -82
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +23 -37
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +71 -61
- data/ext/libsass/src/operators.cpp +19 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +45 -64
- data/ext/libsass/src/output.hpp +6 -6
- data/ext/libsass/src/parser.cpp +512 -700
- data/ext/libsass/src/parser.hpp +89 -97
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.cpp +16 -15
- data/ext/libsass/src/sass.hpp +10 -5
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +91 -122
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +8 -11
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +24 -22
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +48 -50
- data/ext/libsass/src/util.hpp +20 -21
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +62 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +4 -6
- data/lib/sassc/script.rb +4 -4
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +18 -1
- data/test/native_test.rb +4 -4
- metadata +29 -15
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/lib/sassc/native/lib_c.rb +0 -21
@@ -1,28 +1,11 @@
|
|
1
1
|
// sass.hpp must go before all system headers to get the
|
2
2
|
// __EXTENSIONS__ fix on Solaris.
|
3
3
|
#include "sass.hpp"
|
4
|
-
|
5
4
|
#include "ast.hpp"
|
6
|
-
#include "context.hpp"
|
7
|
-
#include "node.hpp"
|
8
|
-
#include "eval.hpp"
|
9
|
-
#include "extend.hpp"
|
10
|
-
#include "emitter.hpp"
|
11
|
-
#include "color_maps.hpp"
|
12
|
-
#include "ast_fwd_decl.hpp"
|
13
|
-
#include <set>
|
14
|
-
#include <iomanip>
|
15
|
-
#include <iostream>
|
16
|
-
#include <algorithm>
|
17
|
-
#include <functional>
|
18
|
-
#include <cctype>
|
19
|
-
#include <locale>
|
20
|
-
|
21
|
-
#include "ast_values.hpp"
|
22
5
|
|
23
6
|
namespace Sass {
|
24
7
|
|
25
|
-
void str_rtrim(
|
8
|
+
void str_rtrim(sass::string& str, const sass::string& delimiters = " \f\n\r\t\v")
|
26
9
|
{
|
27
10
|
str.erase( str.find_last_not_of( delimiters ) + 1 );
|
28
11
|
}
|
@@ -30,7 +13,7 @@ namespace Sass {
|
|
30
13
|
/////////////////////////////////////////////////////////////////////////
|
31
14
|
/////////////////////////////////////////////////////////////////////////
|
32
15
|
|
33
|
-
PreValue::PreValue(
|
16
|
+
PreValue::PreValue(SourceSpan pstate, bool d, bool e, bool i, Type ct)
|
34
17
|
: Expression(pstate, d, e, i, ct)
|
35
18
|
{ }
|
36
19
|
PreValue::PreValue(const PreValue* ptr)
|
@@ -40,7 +23,7 @@ namespace Sass {
|
|
40
23
|
/////////////////////////////////////////////////////////////////////////
|
41
24
|
/////////////////////////////////////////////////////////////////////////
|
42
25
|
|
43
|
-
Value::Value(
|
26
|
+
Value::Value(SourceSpan pstate, bool d, bool e, bool i, Type ct)
|
44
27
|
: PreValue(pstate, d, e, i, ct)
|
45
28
|
{ }
|
46
29
|
Value::Value(const Value* ptr)
|
@@ -50,9 +33,9 @@ namespace Sass {
|
|
50
33
|
/////////////////////////////////////////////////////////////////////////
|
51
34
|
/////////////////////////////////////////////////////////////////////////
|
52
35
|
|
53
|
-
List::List(
|
36
|
+
List::List(SourceSpan pstate, size_t size, enum Sass_Separator sep, bool argl, bool bracket)
|
54
37
|
: Value(pstate),
|
55
|
-
Vectorized<
|
38
|
+
Vectorized<ExpressionObj>(size),
|
56
39
|
separator_(sep),
|
57
40
|
is_arglist_(argl),
|
58
41
|
is_bracketed_(bracket),
|
@@ -61,7 +44,7 @@ namespace Sass {
|
|
61
44
|
|
62
45
|
List::List(const List* ptr)
|
63
46
|
: Value(ptr),
|
64
|
-
Vectorized<
|
47
|
+
Vectorized<ExpressionObj>(*ptr),
|
65
48
|
separator_(ptr->separator_),
|
66
49
|
is_arglist_(ptr->is_arglist_),
|
67
50
|
is_bracketed_(ptr->is_bracketed_),
|
@@ -71,7 +54,7 @@ namespace Sass {
|
|
71
54
|
size_t List::hash() const
|
72
55
|
{
|
73
56
|
if (hash_ == 0) {
|
74
|
-
hash_ = std::hash<
|
57
|
+
hash_ = std::hash<sass::string>()(sep_string());
|
75
58
|
hash_combine(hash_, std::hash<bool>()(is_bracketed()));
|
76
59
|
for (size_t i = 0, L = length(); i < L; ++i)
|
77
60
|
hash_combine(hash_, (elements()[i])->hash());
|
@@ -85,6 +68,24 @@ namespace Sass {
|
|
85
68
|
// don't set children
|
86
69
|
}
|
87
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
|
+
|
88
89
|
bool List::operator== (const Expression& rhs) const
|
89
90
|
{
|
90
91
|
if (auto r = Cast<List>(&rhs)) {
|
@@ -108,7 +109,7 @@ namespace Sass {
|
|
108
109
|
// arglist expects a list of arguments
|
109
110
|
// so we need to break before keywords
|
110
111
|
for (size_t i = 0, L = length(); i < L; ++i) {
|
111
|
-
|
112
|
+
ExpressionObj obj = this->at(i);
|
112
113
|
if (Argument* arg = Cast<Argument>(obj)) {
|
113
114
|
if (!arg->name().empty()) return i;
|
114
115
|
}
|
@@ -117,8 +118,8 @@ namespace Sass {
|
|
117
118
|
}
|
118
119
|
|
119
120
|
|
120
|
-
|
121
|
-
|
121
|
+
ExpressionObj List::value_at_index(size_t i) {
|
122
|
+
ExpressionObj obj = this->at(i);
|
122
123
|
if (is_arglist_) {
|
123
124
|
if (Argument* arg = Cast<Argument>(obj)) {
|
124
125
|
return arg->value();
|
@@ -133,7 +134,7 @@ namespace Sass {
|
|
133
134
|
/////////////////////////////////////////////////////////////////////////
|
134
135
|
/////////////////////////////////////////////////////////////////////////
|
135
136
|
|
136
|
-
Map::Map(
|
137
|
+
Map::Map(SourceSpan pstate, size_t size)
|
137
138
|
: Value(pstate),
|
138
139
|
Hashed(size)
|
139
140
|
{ concrete_type(MAP); }
|
@@ -143,6 +144,31 @@ namespace Sass {
|
|
143
144
|
Hashed(*ptr)
|
144
145
|
{ concrete_type(MAP); }
|
145
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
|
+
|
146
172
|
bool Map::operator== (const Expression& rhs) const
|
147
173
|
{
|
148
174
|
if (auto r = Cast<Map>(&rhs)) {
|
@@ -159,7 +185,7 @@ namespace Sass {
|
|
159
185
|
return false;
|
160
186
|
}
|
161
187
|
|
162
|
-
List_Obj Map::to_list(
|
188
|
+
List_Obj Map::to_list(SourceSpan& pstate) {
|
163
189
|
List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);
|
164
190
|
|
165
191
|
for (auto key : keys()) {
|
@@ -187,8 +213,8 @@ namespace Sass {
|
|
187
213
|
/////////////////////////////////////////////////////////////////////////
|
188
214
|
/////////////////////////////////////////////////////////////////////////
|
189
215
|
|
190
|
-
Binary_Expression::Binary_Expression(
|
191
|
-
Operand op,
|
216
|
+
Binary_Expression::Binary_Expression(SourceSpan pstate,
|
217
|
+
Operand op, ExpressionObj lhs, ExpressionObj rhs)
|
192
218
|
: PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)
|
193
219
|
{ }
|
194
220
|
|
@@ -209,12 +235,12 @@ namespace Sass {
|
|
209
235
|
return is_interpolant() || (right() && right()->is_right_interpolant());
|
210
236
|
}
|
211
237
|
|
212
|
-
const
|
238
|
+
const sass::string Binary_Expression::type_name()
|
213
239
|
{
|
214
240
|
return sass_op_to_name(optype());
|
215
241
|
}
|
216
242
|
|
217
|
-
const
|
243
|
+
const sass::string Binary_Expression::separator()
|
218
244
|
{
|
219
245
|
return sass_op_separator(optype());
|
220
246
|
}
|
@@ -232,6 +258,17 @@ namespace Sass {
|
|
232
258
|
is_delayed(delayed);
|
233
259
|
}
|
234
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
|
+
|
235
272
|
bool Binary_Expression::operator==(const Expression& rhs) const
|
236
273
|
{
|
237
274
|
if (auto m = Cast<Binary_Expression>(&rhs)) {
|
@@ -255,7 +292,7 @@ namespace Sass {
|
|
255
292
|
/////////////////////////////////////////////////////////////////////////
|
256
293
|
/////////////////////////////////////////////////////////////////////////
|
257
294
|
|
258
|
-
Function::Function(
|
295
|
+
Function::Function(SourceSpan pstate, Definition_Obj def, bool css)
|
259
296
|
: Value(pstate), definition_(def), is_css_(css)
|
260
297
|
{ concrete_type(FUNCTION_VAL); }
|
261
298
|
|
@@ -263,6 +300,22 @@ namespace Sass {
|
|
263
300
|
: Value(ptr), definition_(ptr->definition_), is_css_(ptr->is_css_)
|
264
301
|
{ concrete_type(FUNCTION_VAL); }
|
265
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
|
+
|
266
319
|
bool Function::operator== (const Expression& rhs) const
|
267
320
|
{
|
268
321
|
if (auto r = Cast<Function>(&rhs)) {
|
@@ -273,7 +326,7 @@ namespace Sass {
|
|
273
326
|
return false;
|
274
327
|
}
|
275
328
|
|
276
|
-
|
329
|
+
sass::string Function::name() {
|
277
330
|
if (definition_) {
|
278
331
|
return definition_->name();
|
279
332
|
}
|
@@ -283,23 +336,23 @@ namespace Sass {
|
|
283
336
|
/////////////////////////////////////////////////////////////////////////
|
284
337
|
/////////////////////////////////////////////////////////////////////////
|
285
338
|
|
286
|
-
Function_Call::Function_Call(
|
339
|
+
Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, void* cookie)
|
287
340
|
: PreValue(pstate), sname_(n), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)
|
288
341
|
{ concrete_type(FUNCTION); }
|
289
|
-
Function_Call::Function_Call(
|
342
|
+
Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, Function_Obj func)
|
290
343
|
: PreValue(pstate), sname_(n), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
|
291
344
|
{ concrete_type(FUNCTION); }
|
292
|
-
Function_Call::Function_Call(
|
345
|
+
Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args)
|
293
346
|
: PreValue(pstate), sname_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)
|
294
347
|
{ concrete_type(FUNCTION); }
|
295
348
|
|
296
|
-
Function_Call::Function_Call(
|
349
|
+
Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, void* cookie)
|
297
350
|
: PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)
|
298
351
|
{ concrete_type(FUNCTION); }
|
299
|
-
Function_Call::Function_Call(
|
352
|
+
Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Function_Obj func)
|
300
353
|
: PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
|
301
354
|
{ concrete_type(FUNCTION); }
|
302
|
-
Function_Call::Function_Call(
|
355
|
+
Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args)
|
303
356
|
: PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), via_call_(false), cookie_(0), hash_(0)
|
304
357
|
{ concrete_type(FUNCTION); }
|
305
358
|
|
@@ -328,14 +381,14 @@ namespace Sass {
|
|
328
381
|
size_t Function_Call::hash() const
|
329
382
|
{
|
330
383
|
if (hash_ == 0) {
|
331
|
-
hash_ = std::hash<
|
384
|
+
hash_ = std::hash<sass::string>()(name());
|
332
385
|
for (auto argument : arguments()->elements())
|
333
386
|
hash_combine(hash_, argument->hash());
|
334
387
|
}
|
335
388
|
return hash_;
|
336
389
|
}
|
337
390
|
|
338
|
-
|
391
|
+
sass::string Function_Call::name() const
|
339
392
|
{
|
340
393
|
return sname();
|
341
394
|
}
|
@@ -348,7 +401,7 @@ namespace Sass {
|
|
348
401
|
/////////////////////////////////////////////////////////////////////////
|
349
402
|
/////////////////////////////////////////////////////////////////////////
|
350
403
|
|
351
|
-
Variable::Variable(
|
404
|
+
Variable::Variable(SourceSpan pstate, sass::string n)
|
352
405
|
: PreValue(pstate), name_(n)
|
353
406
|
{ concrete_type(VARIABLE); }
|
354
407
|
|
@@ -366,13 +419,13 @@ namespace Sass {
|
|
366
419
|
|
367
420
|
size_t Variable::hash() const
|
368
421
|
{
|
369
|
-
return std::hash<
|
422
|
+
return std::hash<sass::string>()(name());
|
370
423
|
}
|
371
424
|
|
372
425
|
/////////////////////////////////////////////////////////////////////////
|
373
426
|
/////////////////////////////////////////////////////////////////////////
|
374
427
|
|
375
|
-
Number::Number(
|
428
|
+
Number::Number(SourceSpan pstate, double val, sass::string u, bool zero)
|
376
429
|
: Value(pstate),
|
377
430
|
Units(),
|
378
431
|
value_(val),
|
@@ -385,12 +438,12 @@ namespace Sass {
|
|
385
438
|
bool nominator = true;
|
386
439
|
while (true) {
|
387
440
|
r = u.find_first_of("*/", l);
|
388
|
-
|
441
|
+
sass::string unit(u.substr(l, r == sass::string::npos ? r : r - l));
|
389
442
|
if (!unit.empty()) {
|
390
443
|
if (nominator) numerators.push_back(unit);
|
391
444
|
else denominators.push_back(unit);
|
392
445
|
}
|
393
|
-
if (r ==
|
446
|
+
if (r == sass::string::npos) break;
|
394
447
|
// ToDo: should error for multiple slashes
|
395
448
|
// if (!nominator && u[r] == '/') error(...)
|
396
449
|
if (u[r] == '/')
|
@@ -429,13 +482,21 @@ namespace Sass {
|
|
429
482
|
if (hash_ == 0) {
|
430
483
|
hash_ = std::hash<double>()(value_);
|
431
484
|
for (const auto numerator : numerators)
|
432
|
-
hash_combine(hash_, std::hash<
|
485
|
+
hash_combine(hash_, std::hash<sass::string>()(numerator));
|
433
486
|
for (const auto denominator : denominators)
|
434
|
-
hash_combine(hash_, std::hash<
|
487
|
+
hash_combine(hash_, std::hash<sass::string>()(denominator));
|
435
488
|
}
|
436
489
|
return hash_;
|
437
490
|
}
|
438
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
|
+
|
439
500
|
bool Number::operator== (const Expression& rhs) const
|
440
501
|
{
|
441
502
|
if (auto n = Cast<Number>(&rhs)) {
|
@@ -475,7 +536,7 @@ namespace Sass {
|
|
475
536
|
l.normalize(); r.normalize();
|
476
537
|
Units &lhs_unit = l, &rhs_unit = r;
|
477
538
|
if (!(lhs_unit == rhs_unit)) {
|
478
|
-
/* ToDo: do we always get
|
539
|
+
/* ToDo: do we always get useful backtraces? */
|
479
540
|
throw Exception::IncompatibleUnits(rhs, *this);
|
480
541
|
}
|
481
542
|
if (lhs_unit == rhs_unit) {
|
@@ -488,7 +549,7 @@ namespace Sass {
|
|
488
549
|
/////////////////////////////////////////////////////////////////////////
|
489
550
|
/////////////////////////////////////////////////////////////////////////
|
490
551
|
|
491
|
-
Color::Color(
|
552
|
+
Color::Color(SourceSpan pstate, double a, const sass::string disp)
|
492
553
|
: Value(pstate),
|
493
554
|
disp_(disp), a_(a),
|
494
555
|
hash_(0)
|
@@ -502,6 +563,21 @@ namespace Sass {
|
|
502
563
|
hash_(ptr->hash_)
|
503
564
|
{ concrete_type(COLOR); }
|
504
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
|
+
|
505
581
|
bool Color::operator== (const Expression& rhs) const
|
506
582
|
{
|
507
583
|
if (auto r = Cast<Color_RGBA>(&rhs)) {
|
@@ -519,7 +595,7 @@ namespace Sass {
|
|
519
595
|
/////////////////////////////////////////////////////////////////////////
|
520
596
|
/////////////////////////////////////////////////////////////////////////
|
521
597
|
|
522
|
-
Color_RGBA::Color_RGBA(
|
598
|
+
Color_RGBA::Color_RGBA(SourceSpan pstate, double r, double g, double b, double a, const sass::string disp)
|
523
599
|
: Color(pstate, a, disp),
|
524
600
|
r_(r), g_(g), b_(b)
|
525
601
|
{ concrete_type(COLOR); }
|
@@ -531,6 +607,23 @@ namespace Sass {
|
|
531
607
|
b_(ptr->b_)
|
532
608
|
{ concrete_type(COLOR); }
|
533
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
|
+
|
534
627
|
bool Color_RGBA::operator== (const Expression& rhs) const
|
535
628
|
{
|
536
629
|
if (auto r = Cast<Color_RGBA>(&rhs)) {
|
@@ -545,7 +638,7 @@ namespace Sass {
|
|
545
638
|
size_t Color_RGBA::hash() const
|
546
639
|
{
|
547
640
|
if (hash_ == 0) {
|
548
|
-
hash_ = std::hash<
|
641
|
+
hash_ = std::hash<sass::string>()("RGBA");
|
549
642
|
hash_combine(hash_, std::hash<double>()(a_));
|
550
643
|
hash_combine(hash_, std::hash<double>()(r_));
|
551
644
|
hash_combine(hash_, std::hash<double>()(g_));
|
@@ -600,7 +693,7 @@ namespace Sass {
|
|
600
693
|
/////////////////////////////////////////////////////////////////////////
|
601
694
|
/////////////////////////////////////////////////////////////////////////
|
602
695
|
|
603
|
-
Color_HSLA::Color_HSLA(
|
696
|
+
Color_HSLA::Color_HSLA(SourceSpan pstate, double h, double s, double l, double a, const sass::string disp)
|
604
697
|
: Color(pstate, a, disp),
|
605
698
|
h_(absmod(h, 360.0)),
|
606
699
|
s_(clip(s, 0.0, 100.0)),
|
@@ -616,6 +709,23 @@ namespace Sass {
|
|
616
709
|
// hash_(ptr->hash_)
|
617
710
|
{ concrete_type(COLOR); }
|
618
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
|
+
|
619
729
|
bool Color_HSLA::operator== (const Expression& rhs) const
|
620
730
|
{
|
621
731
|
if (auto r = Cast<Color_HSLA>(&rhs)) {
|
@@ -630,7 +740,7 @@ namespace Sass {
|
|
630
740
|
size_t Color_HSLA::hash() const
|
631
741
|
{
|
632
742
|
if (hash_ == 0) {
|
633
|
-
hash_ = std::hash<
|
743
|
+
hash_ = std::hash<sass::string>()("HSLA");
|
634
744
|
hash_combine(hash_, std::hash<double>()(a_));
|
635
745
|
hash_combine(hash_, std::hash<double>()(h_));
|
636
746
|
hash_combine(hash_, std::hash<double>()(s_));
|
@@ -679,7 +789,7 @@ namespace Sass {
|
|
679
789
|
/////////////////////////////////////////////////////////////////////////
|
680
790
|
/////////////////////////////////////////////////////////////////////////
|
681
791
|
|
682
|
-
Custom_Error::Custom_Error(
|
792
|
+
Custom_Error::Custom_Error(SourceSpan pstate, sass::string msg)
|
683
793
|
: Value(pstate), message_(msg)
|
684
794
|
{ concrete_type(C_ERROR); }
|
685
795
|
|
@@ -687,6 +797,15 @@ namespace Sass {
|
|
687
797
|
: Value(ptr), message_(ptr->message_)
|
688
798
|
{ concrete_type(C_ERROR); }
|
689
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
|
+
|
690
809
|
bool Custom_Error::operator== (const Expression& rhs) const
|
691
810
|
{
|
692
811
|
if (auto r = Cast<Custom_Error>(&rhs)) {
|
@@ -698,7 +817,7 @@ namespace Sass {
|
|
698
817
|
/////////////////////////////////////////////////////////////////////////
|
699
818
|
/////////////////////////////////////////////////////////////////////////
|
700
819
|
|
701
|
-
Custom_Warning::Custom_Warning(
|
820
|
+
Custom_Warning::Custom_Warning(SourceSpan pstate, sass::string msg)
|
702
821
|
: Value(pstate), message_(msg)
|
703
822
|
{ concrete_type(C_WARNING); }
|
704
823
|
|
@@ -706,6 +825,15 @@ namespace Sass {
|
|
706
825
|
: Value(ptr), message_(ptr->message_)
|
707
826
|
{ concrete_type(C_WARNING); }
|
708
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
|
+
|
709
837
|
bool Custom_Warning::operator== (const Expression& rhs) const
|
710
838
|
{
|
711
839
|
if (auto r = Cast<Custom_Warning>(&rhs)) {
|
@@ -717,7 +845,7 @@ namespace Sass {
|
|
717
845
|
/////////////////////////////////////////////////////////////////////////
|
718
846
|
/////////////////////////////////////////////////////////////////////////
|
719
847
|
|
720
|
-
Boolean::Boolean(
|
848
|
+
Boolean::Boolean(SourceSpan pstate, bool val)
|
721
849
|
: Value(pstate), value_(val),
|
722
850
|
hash_(0)
|
723
851
|
{ concrete_type(BOOLEAN); }
|
@@ -728,15 +856,23 @@ namespace Sass {
|
|
728
856
|
hash_(ptr->hash_)
|
729
857
|
{ concrete_type(BOOLEAN); }
|
730
858
|
|
731
|
-
bool Boolean::operator
|
859
|
+
bool Boolean::operator< (const Expression& rhs) const
|
732
860
|
{
|
733
861
|
if (auto r = Cast<Boolean>(&rhs)) {
|
734
|
-
return (value()
|
862
|
+
return (value() < r->value());
|
735
863
|
}
|
736
864
|
return false;
|
737
865
|
}
|
738
866
|
|
739
|
-
|
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
|
740
876
|
{
|
741
877
|
if (hash_ == 0) {
|
742
878
|
hash_ = std::hash<bool>()(value_);
|
@@ -747,7 +883,7 @@ namespace Sass {
|
|
747
883
|
/////////////////////////////////////////////////////////////////////////
|
748
884
|
/////////////////////////////////////////////////////////////////////////
|
749
885
|
|
750
|
-
String::String(
|
886
|
+
String::String(SourceSpan pstate, bool delayed)
|
751
887
|
: Value(pstate, delayed)
|
752
888
|
{ concrete_type(STRING); }
|
753
889
|
String::String(const String* ptr)
|
@@ -757,13 +893,13 @@ namespace Sass {
|
|
757
893
|
/////////////////////////////////////////////////////////////////////////
|
758
894
|
/////////////////////////////////////////////////////////////////////////
|
759
895
|
|
760
|
-
String_Schema::String_Schema(
|
761
|
-
: String(pstate), Vectorized<
|
896
|
+
String_Schema::String_Schema(SourceSpan pstate, size_t size, bool css)
|
897
|
+
: String(pstate), Vectorized<PreValueObj>(size), css_(css), hash_(0)
|
762
898
|
{ concrete_type(STRING); }
|
763
899
|
|
764
900
|
String_Schema::String_Schema(const String_Schema* ptr)
|
765
901
|
: String(ptr),
|
766
|
-
Vectorized<
|
902
|
+
Vectorized<PreValueObj>(*ptr),
|
767
903
|
css_(ptr->css_),
|
768
904
|
hash_(ptr->hash_)
|
769
905
|
{ concrete_type(STRING); }
|
@@ -784,6 +920,23 @@ namespace Sass {
|
|
784
920
|
return length() && last()->is_right_interpolant();
|
785
921
|
}
|
786
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
|
+
|
787
940
|
bool String_Schema::operator== (const Expression& rhs) const
|
788
941
|
{
|
789
942
|
if (auto r = Cast<String_Schema>(&rhs)) {
|
@@ -823,23 +976,22 @@ namespace Sass {
|
|
823
976
|
/////////////////////////////////////////////////////////////////////////
|
824
977
|
/////////////////////////////////////////////////////////////////////////
|
825
978
|
|
826
|
-
String_Constant::String_Constant(
|
827
|
-
: String(pstate), quote_mark_(0),
|
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)
|
828
981
|
{ }
|
829
|
-
String_Constant::String_Constant(
|
830
|
-
: String(pstate), quote_mark_(0),
|
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)
|
831
984
|
{ }
|
832
|
-
String_Constant::String_Constant(
|
833
|
-
: String(pstate), quote_mark_(0),
|
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)
|
834
987
|
{ }
|
835
|
-
String_Constant::String_Constant(
|
836
|
-
: String(pstate), quote_mark_(0),
|
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)
|
837
990
|
{ }
|
838
991
|
|
839
992
|
String_Constant::String_Constant(const String_Constant* ptr)
|
840
993
|
: String(ptr),
|
841
994
|
quote_mark_(ptr->quote_mark_),
|
842
|
-
can_compress_whitespace_(ptr->can_compress_whitespace_),
|
843
995
|
value_(ptr->value_),
|
844
996
|
hash_(ptr->hash_)
|
845
997
|
{ }
|
@@ -848,17 +1000,30 @@ namespace Sass {
|
|
848
1000
|
return value_.empty() && quote_mark_ == 0;
|
849
1001
|
}
|
850
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
|
+
|
851
1015
|
bool String_Constant::operator== (const Expression& rhs) const
|
852
1016
|
{
|
853
1017
|
if (auto qstr = Cast<String_Quoted>(&rhs)) {
|
854
1018
|
return value() == qstr->value();
|
855
|
-
}
|
1019
|
+
}
|
1020
|
+
else if (auto cstr = Cast<String_Constant>(&rhs)) {
|
856
1021
|
return value() == cstr->value();
|
857
1022
|
}
|
858
1023
|
return false;
|
859
1024
|
}
|
860
1025
|
|
861
|
-
|
1026
|
+
sass::string String_Constant::inspect() const
|
862
1027
|
{
|
863
1028
|
return quote(value_, '*');
|
864
1029
|
}
|
@@ -871,7 +1036,7 @@ namespace Sass {
|
|
871
1036
|
size_t String_Constant::hash() const
|
872
1037
|
{
|
873
1038
|
if (hash_ == 0) {
|
874
|
-
hash_ = std::hash<
|
1039
|
+
hash_ = std::hash<sass::string>()(value_);
|
875
1040
|
}
|
876
1041
|
return hash_;
|
877
1042
|
}
|
@@ -879,7 +1044,7 @@ namespace Sass {
|
|
879
1044
|
/////////////////////////////////////////////////////////////////////////
|
880
1045
|
/////////////////////////////////////////////////////////////////////////
|
881
1046
|
|
882
|
-
String_Quoted::String_Quoted(
|
1047
|
+
String_Quoted::String_Quoted(SourceSpan pstate, sass::string val, char q,
|
883
1048
|
bool keep_utf8_escapes, bool skip_unquoting,
|
884
1049
|
bool strict_unquoting, bool css)
|
885
1050
|
: String_Constant(pstate, val, css)
|
@@ -894,17 +1059,30 @@ namespace Sass {
|
|
894
1059
|
: String_Constant(ptr)
|
895
1060
|
{ }
|
896
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
|
+
|
897
1074
|
bool String_Quoted::operator== (const Expression& rhs) const
|
898
1075
|
{
|
899
1076
|
if (auto qstr = Cast<String_Quoted>(&rhs)) {
|
900
1077
|
return value() == qstr->value();
|
901
|
-
}
|
1078
|
+
}
|
1079
|
+
else if (auto cstr = Cast<String_Constant>(&rhs)) {
|
902
1080
|
return value() == cstr->value();
|
903
1081
|
}
|
904
1082
|
return false;
|
905
1083
|
}
|
906
1084
|
|
907
|
-
|
1085
|
+
sass::string String_Quoted::inspect() const
|
908
1086
|
{
|
909
1087
|
return quote(value_, '*');
|
910
1088
|
}
|
@@ -912,16 +1090,25 @@ namespace Sass {
|
|
912
1090
|
/////////////////////////////////////////////////////////////////////////
|
913
1091
|
/////////////////////////////////////////////////////////////////////////
|
914
1092
|
|
915
|
-
Null::Null(
|
1093
|
+
Null::Null(SourceSpan pstate)
|
916
1094
|
: Value(pstate)
|
917
1095
|
{ concrete_type(NULL_VAL); }
|
918
1096
|
|
919
1097
|
Null::Null(const Null* ptr) : Value(ptr)
|
920
1098
|
{ concrete_type(NULL_VAL); }
|
921
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
|
+
|
922
1109
|
bool Null::operator== (const Expression& rhs) const
|
923
1110
|
{
|
924
|
-
return Cast<Null>(&rhs) !=
|
1111
|
+
return Cast<Null>(&rhs) != nullptr;
|
925
1112
|
}
|
926
1113
|
|
927
1114
|
size_t Null::hash() const
|
@@ -932,7 +1119,7 @@ namespace Sass {
|
|
932
1119
|
/////////////////////////////////////////////////////////////////////////
|
933
1120
|
/////////////////////////////////////////////////////////////////////////
|
934
1121
|
|
935
|
-
Parent_Reference::Parent_Reference(
|
1122
|
+
Parent_Reference::Parent_Reference(SourceSpan pstate)
|
936
1123
|
: Value(pstate)
|
937
1124
|
{ concrete_type(PARENT); }
|
938
1125
|
|