1// sass.hpp must go before all system headers to get the
2// __EXTENSIONS__ fix on Solaris.
3#include "sass.hpp"
4
5#include "ast.hpp"
6
7namespace Sass {
8
9 static Null sass_null(SourceSpan("null"));
10
11 const char* sass_op_to_name(enum Sass_OP op) {
12 switch (op) {
13 case AND: return "and";
14 case OR: return "or";
15 case EQ: return "eq";
16 case NEQ: return "neq";
17 case GT: return "gt";
18 case GTE: return "gte";
19 case LT: return "lt";
20 case LTE: return "lte";
21 case ADD: return "plus";
22 case SUB: return "minus";
23 case MUL: return "times";
24 case DIV: return "div";
25 case MOD: return "mod";
26 // this is only used internally!
27 case NUM_OPS: return "[OPS]";
28 default: return "invalid";
29 }
30 }
31
32 const char* sass_op_separator(enum Sass_OP op) {
33 switch (op) {
34 case AND: return "&&";
35 case OR: return "||";
36 case EQ: return "==";
37 case NEQ: return "!=";
38 case GT: return ">";
39 case GTE: return ">=";
40 case LT: return "<";
41 case LTE: return "<=";
42 case ADD: return "+";
43 case SUB: return "-";
44 case MUL: return "*";
45 case DIV: return "/";
46 case MOD: return "%";
47 // this is only used internally!
48 case NUM_OPS: return "[OPS]";
49 default: return "invalid";
50 }
51 }
52
53 /////////////////////////////////////////////////////////////////////////
54 /////////////////////////////////////////////////////////////////////////
55
56 void AST_Node::update_pstate(const SourceSpan& pstate)
57 {
58 pstate_.offset += pstate.position - pstate_.position + pstate.offset;
59 }
60
61 sass::string AST_Node::to_string(Sass_Inspect_Options opt) const
62 {
63 Sass_Output_Options out(opt);
64 Emitter emitter(out);
65 Inspect i(emitter);
66 i.in_declaration = true;
67 // ToDo: inspect should be const
68 const_cast<AST_Node*>(this)->perform(op: &i);
69 return i.get_buffer();
70 }
71
72 sass::string AST_Node::to_css(Sass_Inspect_Options opt) const
73 {
74 opt.output_style = TO_CSS;
75 Sass_Output_Options out(opt);
76 Emitter emitter(out);
77 Inspect i(emitter);
78 i.in_declaration = true;
79 // ToDo: inspect should be const
80 const_cast<AST_Node*>(this)->perform(op: &i);
81 return i.get_buffer();
82 }
83
84 sass::string AST_Node::to_string() const
85 {
86 return to_string(opt: { NESTED, 5 });
87 }
88
89 /////////////////////////////////////////////////////////////////////////
90 /////////////////////////////////////////////////////////////////////////
91
92 Statement::Statement(SourceSpan pstate, Type st, size_t t)
93 : AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)
94 { }
95 Statement::Statement(const Statement* ptr)
96 : AST_Node(ptr),
97 statement_type_(ptr->statement_type_),
98 tabs_(ptr->tabs_),
99 group_end_(ptr->group_end_)
100 { }
101
102 bool Statement::bubbles()
103 {
104 return false;
105 }
106
107 bool Statement::has_content()
108 {
109 return statement_type_ == CONTENT;
110 }
111
112 bool Statement::is_invisible() const
113 {
114 return false;
115 }
116
117 /////////////////////////////////////////////////////////////////////////
118 /////////////////////////////////////////////////////////////////////////
119
120 Block::Block(SourceSpan pstate, size_t s, bool r)
121 : Statement(pstate),
122 Vectorized<Statement_Obj>(s),
123 is_root_(r)
124 { }
125 Block::Block(const Block* ptr)
126 : Statement(ptr),
127 Vectorized<Statement_Obj>(*ptr),
128 is_root_(ptr->is_root_)
129 { }
130
131 bool Block::isInvisible() const
132 {
133 for (auto& item : elements()) {
134 if (!item->is_invisible()) return false;
135 }
136 return true;
137 }
138
139 bool Block::has_content()
140 {
141 for (size_t i = 0, L = elements().size(); i < L; ++i) {
142 if (elements()[i]->has_content()) return true;
143 }
144 return Statement::has_content();
145 }
146
147 /////////////////////////////////////////////////////////////////////////
148 /////////////////////////////////////////////////////////////////////////
149
150 ParentStatement::ParentStatement(SourceSpan pstate, Block_Obj b)
151 : Statement(pstate), block_(b)
152 { }
153 ParentStatement::ParentStatement(const ParentStatement* ptr)
154 : Statement(ptr), block_(ptr->block_)
155 { }
156
157 bool ParentStatement::has_content()
158 {
159 return (block_ && block_->has_content()) || Statement::has_content();
160 }
161
162 /////////////////////////////////////////////////////////////////////////
163 /////////////////////////////////////////////////////////////////////////
164
165 StyleRule::StyleRule(SourceSpan pstate, SelectorListObj s, Block_Obj b)
166 : ParentStatement(pstate, b), selector_(s), schema_(), is_root_(false)
167 { statement_type(statement_type__: RULESET); }
168 StyleRule::StyleRule(const StyleRule* ptr)
169 : ParentStatement(ptr),
170 selector_(ptr->selector_),
171 schema_(ptr->schema_),
172 is_root_(ptr->is_root_)
173 { statement_type(statement_type__: RULESET); }
174
175 bool StyleRule::is_invisible() const {
176 if (const SelectorList * sl = Cast<SelectorList>(ptr: selector())) {
177 for (size_t i = 0, L = sl->length(); i < L; i += 1)
178 if (!(*sl)[i]->isInvisible()) return false;
179 }
180 return true;
181 }
182
183 /////////////////////////////////////////////////////////////////////////
184 /////////////////////////////////////////////////////////////////////////
185
186 Bubble::Bubble(SourceSpan pstate, Statement_Obj n, Statement_Obj g, size_t t)
187 : Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == nullptr)
188 { }
189 Bubble::Bubble(const Bubble* ptr)
190 : Statement(ptr),
191 node_(ptr->node_),
192 group_end_(ptr->group_end_)
193 { }
194
195 bool Bubble::bubbles()
196 {
197 return true;
198 }
199
200 /////////////////////////////////////////////////////////////////////////
201 /////////////////////////////////////////////////////////////////////////
202
203 Trace::Trace(SourceSpan pstate, sass::string n, Block_Obj b, char type)
204 : ParentStatement(pstate, b), type_(type), name_(n)
205 { }
206 Trace::Trace(const Trace* ptr)
207 : ParentStatement(ptr),
208 type_(ptr->type_),
209 name_(ptr->name_)
210 { }
211
212 /////////////////////////////////////////////////////////////////////////
213 /////////////////////////////////////////////////////////////////////////
214
215 AtRule::AtRule(SourceSpan pstate, sass::string kwd, SelectorListObj sel, Block_Obj b, ExpressionObj val)
216 : ParentStatement(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
217 { statement_type(statement_type__: DIRECTIVE); }
218 AtRule::AtRule(const AtRule* ptr)
219 : ParentStatement(ptr),
220 keyword_(ptr->keyword_),
221 selector_(ptr->selector_),
222 value_(ptr->value_) // set value manually if needed
223 { statement_type(statement_type__: DIRECTIVE); }
224
225 bool AtRule::bubbles() { return is_keyframes() || is_media(); }
226
227 bool AtRule::is_media() {
228 return keyword_.compare(s: "@-webkit-media") == 0 ||
229 keyword_.compare(s: "@-moz-media") == 0 ||
230 keyword_.compare(s: "@-o-media") == 0 ||
231 keyword_.compare(s: "@media") == 0;
232 }
233 bool AtRule::is_keyframes() {
234 return keyword_.compare(s: "@-webkit-keyframes") == 0 ||
235 keyword_.compare(s: "@-moz-keyframes") == 0 ||
236 keyword_.compare(s: "@-o-keyframes") == 0 ||
237 keyword_.compare(s: "@keyframes") == 0;
238 }
239
240 /////////////////////////////////////////////////////////////////////////
241 /////////////////////////////////////////////////////////////////////////
242
243 Keyframe_Rule::Keyframe_Rule(SourceSpan pstate, Block_Obj b)
244 : ParentStatement(pstate, b), name_()
245 { statement_type(statement_type__: KEYFRAMERULE); }
246 Keyframe_Rule::Keyframe_Rule(const Keyframe_Rule* ptr)
247 : ParentStatement(ptr), name_(ptr->name_)
248 { statement_type(statement_type__: KEYFRAMERULE); }
249
250 /////////////////////////////////////////////////////////////////////////
251 /////////////////////////////////////////////////////////////////////////
252
253 Declaration::Declaration(SourceSpan pstate, String_Obj prop, ExpressionObj val, bool i, bool c, Block_Obj b)
254 : ParentStatement(pstate, b), property_(prop), value_(val), is_important_(i), is_custom_property_(c), is_indented_(false)
255 { statement_type(statement_type__: DECLARATION); }
256 Declaration::Declaration(const Declaration* ptr)
257 : ParentStatement(ptr),
258 property_(ptr->property_),
259 value_(ptr->value_),
260 is_important_(ptr->is_important_),
261 is_custom_property_(ptr->is_custom_property_),
262 is_indented_(ptr->is_indented_)
263 { statement_type(statement_type__: DECLARATION); }
264
265 bool Declaration::is_invisible() const
266 {
267 if (is_custom_property()) return false;
268 return !(value_ && !Cast<Null>(ptr: value_));
269 }
270
271 /////////////////////////////////////////////////////////////////////////
272 /////////////////////////////////////////////////////////////////////////
273
274 Assignment::Assignment(SourceSpan pstate, sass::string var, ExpressionObj val, bool is_default, bool is_global)
275 : Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
276 { statement_type(statement_type__: ASSIGNMENT); }
277 Assignment::Assignment(const Assignment* ptr)
278 : Statement(ptr),
279 variable_(ptr->variable_),
280 value_(ptr->value_),
281 is_default_(ptr->is_default_),
282 is_global_(ptr->is_global_)
283 { statement_type(statement_type__: ASSIGNMENT); }
284
285 /////////////////////////////////////////////////////////////////////////
286 /////////////////////////////////////////////////////////////////////////
287
288 Import::Import(SourceSpan pstate)
289 : Statement(pstate),
290 urls_(sass::vector<ExpressionObj>()),
291 incs_(sass::vector<Include>()),
292 import_queries_()
293 { statement_type(statement_type__: IMPORT); }
294 Import::Import(const Import* ptr)
295 : Statement(ptr),
296 urls_(ptr->urls_),
297 incs_(ptr->incs_),
298 import_queries_(ptr->import_queries_)
299 { statement_type(statement_type__: IMPORT); }
300
301 sass::vector<Include>& Import::incs() { return incs_; }
302 sass::vector<ExpressionObj>& Import::urls() { return urls_; }
303
304 /////////////////////////////////////////////////////////////////////////
305 /////////////////////////////////////////////////////////////////////////
306
307 Import_Stub::Import_Stub(SourceSpan pstate, Include res)
308 : Statement(pstate), resource_(res)
309 { statement_type(statement_type__: IMPORT_STUB); }
310 Import_Stub::Import_Stub(const Import_Stub* ptr)
311 : Statement(ptr), resource_(ptr->resource_)
312 { statement_type(statement_type__: IMPORT_STUB); }
313 Include Import_Stub::resource() { return resource_; };
314 sass::string Import_Stub::imp_path() { return resource_.imp_path; };
315 sass::string Import_Stub::abs_path() { return resource_.abs_path; };
316
317 /////////////////////////////////////////////////////////////////////////
318 /////////////////////////////////////////////////////////////////////////
319
320 WarningRule::WarningRule(SourceSpan pstate, ExpressionObj msg)
321 : Statement(pstate), message_(msg)
322 { statement_type(statement_type__: WARNING); }
323 WarningRule::WarningRule(const WarningRule* ptr)
324 : Statement(ptr), message_(ptr->message_)
325 { statement_type(statement_type__: WARNING); }
326
327 /////////////////////////////////////////////////////////////////////////
328 /////////////////////////////////////////////////////////////////////////
329
330 ErrorRule::ErrorRule(SourceSpan pstate, ExpressionObj msg)
331 : Statement(pstate), message_(msg)
332 { statement_type(statement_type__: ERROR); }
333 ErrorRule::ErrorRule(const ErrorRule* ptr)
334 : Statement(ptr), message_(ptr->message_)
335 { statement_type(statement_type__: ERROR); }
336
337 /////////////////////////////////////////////////////////////////////////
338 /////////////////////////////////////////////////////////////////////////
339
340 DebugRule::DebugRule(SourceSpan pstate, ExpressionObj val)
341 : Statement(pstate), value_(val)
342 { statement_type(statement_type__: DEBUGSTMT); }
343 DebugRule::DebugRule(const DebugRule* ptr)
344 : Statement(ptr), value_(ptr->value_)
345 { statement_type(statement_type__: DEBUGSTMT); }
346
347 /////////////////////////////////////////////////////////////////////////
348 /////////////////////////////////////////////////////////////////////////
349
350 Comment::Comment(SourceSpan pstate, String_Obj txt, bool is_important)
351 : Statement(pstate), text_(txt), is_important_(is_important)
352 { statement_type(statement_type__: COMMENT); }
353 Comment::Comment(const Comment* ptr)
354 : Statement(ptr),
355 text_(ptr->text_),
356 is_important_(ptr->is_important_)
357 { statement_type(statement_type__: COMMENT); }
358
359 bool Comment::is_invisible() const
360 {
361 return false;
362 }
363
364 /////////////////////////////////////////////////////////////////////////
365 /////////////////////////////////////////////////////////////////////////
366
367 If::If(SourceSpan pstate, ExpressionObj pred, Block_Obj con, Block_Obj alt)
368 : ParentStatement(pstate, con), predicate_(pred), alternative_(alt)
369 { statement_type(statement_type__: IF); }
370 If::If(const If* ptr)
371 : ParentStatement(ptr),
372 predicate_(ptr->predicate_),
373 alternative_(ptr->alternative_)
374 { statement_type(statement_type__: IF); }
375
376 bool If::has_content()
377 {
378 return ParentStatement::has_content() || (alternative_ && alternative_->has_content());
379 }
380
381 /////////////////////////////////////////////////////////////////////////
382 /////////////////////////////////////////////////////////////////////////
383
384 ForRule::ForRule(SourceSpan pstate,
385 sass::string var, ExpressionObj lo, ExpressionObj hi, Block_Obj b, bool inc)
386 : ParentStatement(pstate, b),
387 variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc)
388 { statement_type(statement_type__: FOR); }
389 ForRule::ForRule(const ForRule* ptr)
390 : ParentStatement(ptr),
391 variable_(ptr->variable_),
392 lower_bound_(ptr->lower_bound_),
393 upper_bound_(ptr->upper_bound_),
394 is_inclusive_(ptr->is_inclusive_)
395 { statement_type(statement_type__: FOR); }
396
397 /////////////////////////////////////////////////////////////////////////
398 /////////////////////////////////////////////////////////////////////////
399
400 EachRule::EachRule(SourceSpan pstate, sass::vector<sass::string> vars, ExpressionObj lst, Block_Obj b)
401 : ParentStatement(pstate, b), variables_(vars), list_(lst)
402 { statement_type(statement_type__: EACH); }
403 EachRule::EachRule(const EachRule* ptr)
404 : ParentStatement(ptr), variables_(ptr->variables_), list_(ptr->list_)
405 { statement_type(statement_type__: EACH); }
406
407 /////////////////////////////////////////////////////////////////////////
408 /////////////////////////////////////////////////////////////////////////
409
410 WhileRule::WhileRule(SourceSpan pstate, ExpressionObj pred, Block_Obj b)
411 : ParentStatement(pstate, b), predicate_(pred)
412 { statement_type(statement_type__: WHILE); }
413 WhileRule::WhileRule(const WhileRule* ptr)
414 : ParentStatement(ptr), predicate_(ptr->predicate_)
415 { statement_type(statement_type__: WHILE); }
416
417 /////////////////////////////////////////////////////////////////////////
418 /////////////////////////////////////////////////////////////////////////
419
420 Return::Return(SourceSpan pstate, ExpressionObj val)
421 : Statement(pstate), value_(val)
422 { statement_type(statement_type__: RETURN); }
423 Return::Return(const Return* ptr)
424 : Statement(ptr), value_(ptr->value_)
425 { statement_type(statement_type__: RETURN); }
426
427 /////////////////////////////////////////////////////////////////////////
428 /////////////////////////////////////////////////////////////////////////
429
430 ExtendRule::ExtendRule(SourceSpan pstate, SelectorListObj s)
431 : Statement(pstate), isOptional_(false), selector_(s), schema_()
432 { statement_type(statement_type__: EXTEND); }
433 ExtendRule::ExtendRule(SourceSpan pstate, Selector_Schema_Obj s)
434 : Statement(pstate), isOptional_(false), selector_(), schema_(s)
435 {
436 statement_type(statement_type__: EXTEND);
437 }
438 ExtendRule::ExtendRule(const ExtendRule* ptr)
439 : Statement(ptr),
440 isOptional_(ptr->isOptional_),
441 selector_(ptr->selector_),
442 schema_(ptr->schema_)
443 { statement_type(statement_type__: EXTEND); }
444
445 /////////////////////////////////////////////////////////////////////////
446 /////////////////////////////////////////////////////////////////////////
447
448 Definition::Definition(const Definition* ptr)
449 : ParentStatement(ptr),
450 name_(ptr->name_),
451 parameters_(ptr->parameters_),
452 environment_(ptr->environment_),
453 type_(ptr->type_),
454 native_function_(ptr->native_function_),
455 c_function_(ptr->c_function_),
456 cookie_(ptr->cookie_),
457 is_overload_stub_(ptr->is_overload_stub_),
458 signature_(ptr->signature_)
459 { }
460
461 Definition::Definition(SourceSpan pstate,
462 sass::string n,
463 Parameters_Obj params,
464 Block_Obj b,
465 Type t)
466 : ParentStatement(pstate, b),
467 name_(n),
468 parameters_(params),
469 environment_(0),
470 type_(t),
471 native_function_(0),
472 c_function_(0),
473 cookie_(0),
474 is_overload_stub_(false),
475 signature_(0)
476 { }
477
478 Definition::Definition(SourceSpan pstate,
479 Signature sig,
480 sass::string n,
481 Parameters_Obj params,
482 Native_Function func_ptr,
483 bool overload_stub)
484 : ParentStatement(pstate, {}),
485 name_(n),
486 parameters_(params),
487 environment_(0),
488 type_(FUNCTION),
489 native_function_(func_ptr),
490 c_function_(0),
491 cookie_(0),
492 is_overload_stub_(overload_stub),
493 signature_(sig)
494 { }
495
496 Definition::Definition(SourceSpan pstate,
497 Signature sig,
498 sass::string n,
499 Parameters_Obj params,
500 Sass_Function_Entry c_func)
501 : ParentStatement(pstate, {}),
502 name_(n),
503 parameters_(params),
504 environment_(0),
505 type_(FUNCTION),
506 native_function_(0),
507 c_function_(c_func),
508 cookie_(sass_function_get_cookie(cb: c_func)),
509 is_overload_stub_(false),
510 signature_(sig)
511 { }
512
513 /////////////////////////////////////////////////////////////////////////
514 /////////////////////////////////////////////////////////////////////////
515
516 Mixin_Call::Mixin_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Parameters_Obj b_params, Block_Obj b)
517 : ParentStatement(pstate, b), name_(n), arguments_(args), block_parameters_(b_params)
518 { }
519 Mixin_Call::Mixin_Call(const Mixin_Call* ptr)
520 : ParentStatement(ptr),
521 name_(ptr->name_),
522 arguments_(ptr->arguments_),
523 block_parameters_(ptr->block_parameters_)
524 { }
525
526 /////////////////////////////////////////////////////////////////////////
527 /////////////////////////////////////////////////////////////////////////
528
529 Content::Content(SourceSpan pstate, Arguments_Obj args)
530 : Statement(pstate),
531 arguments_(args)
532 { statement_type(statement_type__: CONTENT); }
533 Content::Content(const Content* ptr)
534 : Statement(ptr),
535 arguments_(ptr->arguments_)
536 { statement_type(statement_type__: CONTENT); }
537
538 /////////////////////////////////////////////////////////////////////////
539 /////////////////////////////////////////////////////////////////////////
540
541 Expression::Expression(SourceSpan pstate, bool d, bool e, bool i, Type ct)
542 : AST_Node(pstate),
543 is_delayed_(d),
544 is_expanded_(e),
545 is_interpolant_(i),
546 concrete_type_(ct)
547 { }
548
549 Expression::Expression(const Expression* ptr)
550 : AST_Node(ptr),
551 is_delayed_(ptr->is_delayed_),
552 is_expanded_(ptr->is_expanded_),
553 is_interpolant_(ptr->is_interpolant_),
554 concrete_type_(ptr->concrete_type_)
555 { }
556
557 /////////////////////////////////////////////////////////////////////////
558 /////////////////////////////////////////////////////////////////////////
559
560 Unary_Expression::Unary_Expression(SourceSpan pstate, Type t, ExpressionObj o)
561 : Expression(pstate), optype_(t), operand_(o), hash_(0)
562 { }
563 Unary_Expression::Unary_Expression(const Unary_Expression* ptr)
564 : Expression(ptr),
565 optype_(ptr->optype_),
566 operand_(ptr->operand_),
567 hash_(ptr->hash_)
568 { }
569 const sass::string Unary_Expression::type_name() {
570 switch (optype_) {
571 case PLUS: return "plus";
572 case MINUS: return "minus";
573 case SLASH: return "slash";
574 case NOT: return "not";
575 default: return "invalid";
576 }
577 }
578 bool Unary_Expression::operator==(const Expression& rhs) const
579 {
580 try
581 {
582 const Unary_Expression* m = Cast<Unary_Expression>(ptr: &rhs);
583 if (m == 0) return false;
584 return type() == m->type() &&
585 *operand() == *m->operand();
586 }
587 catch (std::bad_cast&)
588 {
589 return false;
590 }
591 catch (...) { throw; }
592 }
593 size_t Unary_Expression::hash() const
594 {
595 if (hash_ == 0) {
596 hash_ = std::hash<size_t>()(optype_);
597 hash_combine(seed&: hash_, val: operand()->hash());
598 };
599 return hash_;
600 }
601
602 /////////////////////////////////////////////////////////////////////////
603 /////////////////////////////////////////////////////////////////////////
604
605 Argument::Argument(SourceSpan pstate, ExpressionObj val, sass::string n, bool rest, bool keyword)
606 : Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)
607 {
608 if (!name_.empty() && is_rest_argument_) {
609 coreError(msg: "variable-length argument may not be passed by name", pstate: pstate_);
610 }
611 }
612 Argument::Argument(const Argument* ptr)
613 : Expression(ptr),
614 value_(ptr->value_),
615 name_(ptr->name_),
616 is_rest_argument_(ptr->is_rest_argument_),
617 is_keyword_argument_(ptr->is_keyword_argument_),
618 hash_(ptr->hash_)
619 {
620 if (!name_.empty() && is_rest_argument_) {
621 coreError(msg: "variable-length argument may not be passed by name", pstate: pstate_);
622 }
623 }
624
625 void Argument::set_delayed(bool delayed)
626 {
627 if (value_) value_->set_delayed(delayed);
628 is_delayed(is_delayed__: delayed);
629 }
630
631 bool Argument::operator==(const Expression& rhs) const
632 {
633 try
634 {
635 const Argument* m = Cast<Argument>(ptr: &rhs);
636 if (!(m && name() == m->name())) return false;
637 return *value() == *m->value();
638 }
639 catch (std::bad_cast&)
640 {
641 return false;
642 }
643 catch (...) { throw; }
644 }
645
646 size_t Argument::hash() const
647 {
648 if (hash_ == 0) {
649 hash_ = std::hash<sass::string>()(name());
650 hash_combine(seed&: hash_, val: value()->hash());
651 }
652 return hash_;
653 }
654
655 /////////////////////////////////////////////////////////////////////////
656 /////////////////////////////////////////////////////////////////////////
657
658 Arguments::Arguments(SourceSpan pstate)
659 : Expression(pstate),
660 Vectorized<Argument_Obj>(),
661 has_named_arguments_(false),
662 has_rest_argument_(false),
663 has_keyword_argument_(false)
664 { }
665 Arguments::Arguments(const Arguments* ptr)
666 : Expression(ptr),
667 Vectorized<Argument_Obj>(*ptr),
668 has_named_arguments_(ptr->has_named_arguments_),
669 has_rest_argument_(ptr->has_rest_argument_),
670 has_keyword_argument_(ptr->has_keyword_argument_)
671 { }
672
673 void Arguments::set_delayed(bool delayed)
674 {
675 for (Argument_Obj arg : elements()) {
676 if (arg) arg->set_delayed(delayed);
677 }
678 is_delayed(is_delayed__: delayed);
679 }
680
681 Argument_Obj Arguments::get_rest_argument()
682 {
683 if (this->has_rest_argument()) {
684 for (Argument_Obj arg : this->elements()) {
685 if (arg->is_rest_argument()) {
686 return arg;
687 }
688 }
689 }
690 return {};
691 }
692
693 Argument_Obj Arguments::get_keyword_argument()
694 {
695 if (this->has_keyword_argument()) {
696 for (Argument_Obj arg : this->elements()) {
697 if (arg->is_keyword_argument()) {
698 return arg;
699 }
700 }
701 }
702 return {};
703 }
704
705 void Arguments::adjust_after_pushing(Argument_Obj a)
706 {
707 if (!a->name().empty()) {
708 if (has_keyword_argument()) {
709 coreError(msg: "named arguments must precede variable-length argument", pstate: a->pstate());
710 }
711 has_named_arguments(has_named_arguments__: true);
712 }
713 else if (a->is_rest_argument()) {
714 if (has_rest_argument()) {
715 coreError(msg: "functions and mixins may only be called with one variable-length argument", pstate: a->pstate());
716 }
717 if (has_keyword_argument_) {
718 coreError(msg: "only keyword arguments may follow variable arguments", pstate: a->pstate());
719 }
720 has_rest_argument(has_rest_argument__: true);
721 }
722 else if (a->is_keyword_argument()) {
723 if (has_keyword_argument()) {
724 coreError(msg: "functions and mixins may only be called with one keyword argument", pstate: a->pstate());
725 }
726 has_keyword_argument(has_keyword_argument__: true);
727 }
728 else {
729 if (has_rest_argument()) {
730 coreError(msg: "ordinal arguments must precede variable-length arguments", pstate: a->pstate());
731 }
732 if (has_named_arguments()) {
733 coreError(msg: "ordinal arguments must precede named arguments", pstate: a->pstate());
734 }
735 }
736 }
737
738 /////////////////////////////////////////////////////////////////////////
739 /////////////////////////////////////////////////////////////////////////
740
741 Media_Query::Media_Query(SourceSpan pstate, String_Obj t, size_t s, bool n, bool r)
742 : Expression(pstate), Vectorized<Media_Query_ExpressionObj>(s),
743 media_type_(t), is_negated_(n), is_restricted_(r)
744 { }
745 Media_Query::Media_Query(const Media_Query* ptr)
746 : Expression(ptr),
747 Vectorized<Media_Query_ExpressionObj>(*ptr),
748 media_type_(ptr->media_type_),
749 is_negated_(ptr->is_negated_),
750 is_restricted_(ptr->is_restricted_)
751 { }
752
753 /////////////////////////////////////////////////////////////////////////
754 /////////////////////////////////////////////////////////////////////////
755
756 Media_Query_Expression::Media_Query_Expression(SourceSpan pstate,
757 ExpressionObj f, ExpressionObj v, bool i)
758 : Expression(pstate), feature_(f), value_(v), is_interpolated_(i)
759 { }
760 Media_Query_Expression::Media_Query_Expression(const Media_Query_Expression* ptr)
761 : Expression(ptr),
762 feature_(ptr->feature_),
763 value_(ptr->value_),
764 is_interpolated_(ptr->is_interpolated_)
765 { }
766
767 /////////////////////////////////////////////////////////////////////////
768 /////////////////////////////////////////////////////////////////////////
769
770 At_Root_Query::At_Root_Query(SourceSpan pstate, ExpressionObj f, ExpressionObj v, bool i)
771 : Expression(pstate), feature_(f), value_(v)
772 { }
773 At_Root_Query::At_Root_Query(const At_Root_Query* ptr)
774 : Expression(ptr),
775 feature_(ptr->feature_),
776 value_(ptr->value_)
777 { }
778
779 bool At_Root_Query::exclude(sass::string str)
780 {
781 bool with = feature() && unquote(feature()->to_string()).compare(s: "with") == 0;
782 List* l = static_cast<List*>(value().ptr());
783 sass::string v;
784
785 if (with)
786 {
787 if (!l || l->length() == 0) return str.compare(s: "rule") != 0;
788 for (size_t i = 0, L = l->length(); i < L; ++i)
789 {
790 v = unquote((*l)[i]->to_string());
791 if (v.compare(s: "all") == 0 || v == str) return false;
792 }
793 return true;
794 }
795 else
796 {
797 if (!l || !l->length()) return str.compare(s: "rule") == 0;
798 for (size_t i = 0, L = l->length(); i < L; ++i)
799 {
800 v = unquote((*l)[i]->to_string());
801 if (v.compare(s: "all") == 0 || v == str) return true;
802 }
803 return false;
804 }
805 }
806
807 /////////////////////////////////////////////////////////////////////////
808 /////////////////////////////////////////////////////////////////////////
809
810 AtRootRule::AtRootRule(SourceSpan pstate, Block_Obj b, At_Root_Query_Obj e)
811 : ParentStatement(pstate, b), expression_(e)
812 { statement_type(statement_type__: ATROOT); }
813 AtRootRule::AtRootRule(const AtRootRule* ptr)
814 : ParentStatement(ptr), expression_(ptr->expression_)
815 { statement_type(statement_type__: ATROOT); }
816
817 bool AtRootRule::bubbles() {
818 return true;
819 }
820
821 bool AtRootRule::exclude_node(Statement_Obj s) {
822 if (expression() == nullptr)
823 {
824 return s->statement_type() == Statement::RULESET;
825 }
826
827 if (s->statement_type() == Statement::DIRECTIVE)
828 {
829 if (AtRuleObj dir = Cast<AtRule>(ptr: s))
830 {
831 sass::string keyword(dir->keyword());
832 if (keyword.length() > 0) keyword.erase(pos: 0, n: 1);
833 return expression()->exclude(str: keyword);
834 }
835 }
836 if (s->statement_type() == Statement::MEDIA)
837 {
838 return expression()->exclude(str: "media");
839 }
840 if (s->statement_type() == Statement::RULESET)
841 {
842 return expression()->exclude(str: "rule");
843 }
844 if (s->statement_type() == Statement::SUPPORTS)
845 {
846 return expression()->exclude(str: "supports");
847 }
848 if (AtRuleObj dir = Cast<AtRule>(ptr: s))
849 {
850 if (dir->is_keyframes()) return expression()->exclude(str: "keyframes");
851 }
852 return false;
853 }
854
855 /////////////////////////////////////////////////////////////////////////
856 /////////////////////////////////////////////////////////////////////////
857
858 Parameter::Parameter(SourceSpan pstate, sass::string n, ExpressionObj def, bool rest)
859 : AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)
860 { }
861 Parameter::Parameter(const Parameter* ptr)
862 : AST_Node(ptr),
863 name_(ptr->name_),
864 default_value_(ptr->default_value_),
865 is_rest_parameter_(ptr->is_rest_parameter_)
866 { }
867
868 /////////////////////////////////////////////////////////////////////////
869 /////////////////////////////////////////////////////////////////////////
870
871 Parameters::Parameters(SourceSpan pstate)
872 : AST_Node(pstate),
873 Vectorized<Parameter_Obj>(),
874 has_optional_parameters_(false),
875 has_rest_parameter_(false)
876 { }
877 Parameters::Parameters(const Parameters* ptr)
878 : AST_Node(ptr),
879 Vectorized<Parameter_Obj>(*ptr),
880 has_optional_parameters_(ptr->has_optional_parameters_),
881 has_rest_parameter_(ptr->has_rest_parameter_)
882 { }
883
884 void Parameters::adjust_after_pushing(Parameter_Obj p)
885 {
886 if (p->default_value()) {
887 if (has_rest_parameter()) {
888 coreError(msg: "optional parameters may not be combined with variable-length parameters", pstate: p->pstate());
889 }
890 has_optional_parameters(has_optional_parameters__: true);
891 }
892 else if (p->is_rest_parameter()) {
893 if (has_rest_parameter()) {
894 coreError(msg: "functions and mixins cannot have more than one variable-length parameter", pstate: p->pstate());
895 }
896 has_rest_parameter(has_rest_parameter__: true);
897 }
898 else {
899 if (has_rest_parameter()) {
900 coreError(msg: "required parameters must precede variable-length parameters", pstate: p->pstate());
901 }
902 if (has_optional_parameters()) {
903 coreError(msg: "required parameters must precede optional parameters", pstate: p->pstate());
904 }
905 }
906 }
907
908 /////////////////////////////////////////////////////////////////////////
909 /////////////////////////////////////////////////////////////////////////
910
911 // If you forget to add a class here you will get
912 // undefined reference to `vtable for Sass::Class'
913
914 IMPLEMENT_AST_OPERATORS(StyleRule);
915 IMPLEMENT_AST_OPERATORS(MediaRule);
916 IMPLEMENT_AST_OPERATORS(CssMediaRule);
917 IMPLEMENT_AST_OPERATORS(CssMediaQuery);
918 IMPLEMENT_AST_OPERATORS(Import);
919 IMPLEMENT_AST_OPERATORS(Import_Stub);
920 IMPLEMENT_AST_OPERATORS(AtRule);
921 IMPLEMENT_AST_OPERATORS(AtRootRule);
922 IMPLEMENT_AST_OPERATORS(WhileRule);
923 IMPLEMENT_AST_OPERATORS(EachRule);
924 IMPLEMENT_AST_OPERATORS(ForRule);
925 IMPLEMENT_AST_OPERATORS(If);
926 IMPLEMENT_AST_OPERATORS(Mixin_Call);
927 IMPLEMENT_AST_OPERATORS(ExtendRule);
928 IMPLEMENT_AST_OPERATORS(Media_Query);
929 IMPLEMENT_AST_OPERATORS(Media_Query_Expression);
930 IMPLEMENT_AST_OPERATORS(DebugRule);
931 IMPLEMENT_AST_OPERATORS(ErrorRule);
932 IMPLEMENT_AST_OPERATORS(WarningRule);
933 IMPLEMENT_AST_OPERATORS(Assignment);
934 IMPLEMENT_AST_OPERATORS(Return);
935 IMPLEMENT_AST_OPERATORS(At_Root_Query);
936 IMPLEMENT_AST_OPERATORS(Comment);
937 IMPLEMENT_AST_OPERATORS(Parameters);
938 IMPLEMENT_AST_OPERATORS(Parameter);
939 IMPLEMENT_AST_OPERATORS(Arguments);
940 IMPLEMENT_AST_OPERATORS(Argument);
941 IMPLEMENT_AST_OPERATORS(Unary_Expression);
942 IMPLEMENT_AST_OPERATORS(Block);
943 IMPLEMENT_AST_OPERATORS(Content);
944 IMPLEMENT_AST_OPERATORS(Trace);
945 IMPLEMENT_AST_OPERATORS(Keyframe_Rule);
946 IMPLEMENT_AST_OPERATORS(Bubble);
947 IMPLEMENT_AST_OPERATORS(Definition);
948 IMPLEMENT_AST_OPERATORS(Declaration);
949
950 /////////////////////////////////////////////////////////////////////////
951 /////////////////////////////////////////////////////////////////////////
952
953}
954

source code of gtk/subprojects/libsass/src/ast.cpp