Initial commit
[yaffs-website] / node_modules / node-sass / src / libsass / src / ast.hpp
1 #ifndef SASS_AST_H
2 #define SASS_AST_H
3
4 #include "sass.hpp"
5 #include <set>
6 #include <deque>
7 #include <vector>
8 #include <string>
9 #include <sstream>
10 #include <iostream>
11 #include <typeinfo>
12 #include <algorithm>
13 #include "sass/base.h"
14 #include "ast_fwd_decl.hpp"
15
16 #ifdef DEBUG_SHARED_PTR
17
18 #define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \
19   virtual klass##_Ptr copy(std::string, size_t) const = 0; \
20   virtual klass##_Ptr clone(std::string, size_t) const = 0; \
21
22 #define ATTACH_AST_OPERATIONS(klass) \
23   virtual klass##_Ptr copy(std::string, size_t) const; \
24   virtual klass##_Ptr clone(std::string, size_t) const; \
25
26 #else
27
28 #define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \
29   virtual klass##_Ptr copy() const = 0; \
30   virtual klass##_Ptr clone() const = 0; \
31
32 #define ATTACH_AST_OPERATIONS(klass) \
33   virtual klass##_Ptr copy() const; \
34   virtual klass##_Ptr clone() const; \
35
36 #endif
37
38 #ifdef __clang__
39
40 /*
41  * There are some overloads used here that trigger the clang overload
42  * hiding warning. Specifically:
43  *
44  * Type type() which hides string type() from Expression
45  *
46  */
47 #pragma clang diagnostic push
48 #pragma clang diagnostic ignored "-Woverloaded-virtual"
49
50 #endif
51
52 #include "util.hpp"
53 #include "units.hpp"
54 #include "context.hpp"
55 #include "position.hpp"
56 #include "constants.hpp"
57 #include "operation.hpp"
58 #include "position.hpp"
59 #include "inspect.hpp"
60 #include "source_map.hpp"
61 #include "environment.hpp"
62 #include "error_handling.hpp"
63 #include "ast_def_macros.hpp"
64 #include "ast_fwd_decl.hpp"
65 #include "source_map.hpp"
66
67 #include "sass.h"
68
69 namespace Sass {
70
71   // easier to search with name
72   const bool DELAYED = true;
73
74   // ToDo: should this really be hardcoded
75   // Note: most methods follow precision option
76   const double NUMBER_EPSILON = 0.00000000000001;
77
78   // ToDo: where does this fit best?
79   // We don't share this with C-API?
80   class Operand {
81     public:
82       Operand(Sass_OP operand, bool ws_before = false, bool ws_after = false)
83       : operand(operand), ws_before(ws_before), ws_after(ws_after)
84       { }
85     public:
86       enum Sass_OP operand;
87       bool ws_before;
88       bool ws_after;
89   };
90
91   //////////////////////////////////////////////////////////
92   // `hash_combine` comes from boost (functional/hash):
93   // http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html
94   // Boost Software License - Version 1.0
95   // http://www.boost.org/users/license.html
96   template <typename T>
97   void hash_combine (std::size_t& seed, const T& val)
98   {
99     seed ^= std::hash<T>()(val) + 0x9e3779b9
100              + (seed<<6) + (seed>>2);
101   }
102   //////////////////////////////////////////////////////////
103
104   //////////////////////////////////////////////////////////
105   // Abstract base class for all abstract syntax tree nodes.
106   //////////////////////////////////////////////////////////
107   class AST_Node : public SharedObj {
108     ADD_PROPERTY(ParserState, pstate)
109   public:
110     AST_Node(ParserState pstate)
111     : pstate_(pstate)
112     { }
113     AST_Node(const AST_Node* ptr)
114     : pstate_(ptr->pstate_)
115     { }
116
117     // AST_Node(AST_Node& ptr) = delete;
118
119     virtual ~AST_Node() = 0;
120     virtual size_t hash() { return 0; }
121     ATTACH_VIRTUAL_AST_OPERATIONS(AST_Node);
122     virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
123     virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
124     virtual const std::string to_string(Sass_Inspect_Options opt) const;
125     virtual const std::string to_string() const;
126     virtual void cloneChildren() {};
127   public:
128     void update_pstate(const ParserState& pstate);
129   public:
130     Offset off() { return pstate(); }
131     Position pos() { return pstate(); }
132     ATTACH_OPERATIONS()
133   };
134   inline AST_Node::~AST_Node() { }
135
136   //////////////////////////////////////////////////////////////////////
137   // define cast template now (need complete type)
138   //////////////////////////////////////////////////////////////////////
139
140   template<class T>
141   T* Cast(AST_Node* ptr) {
142     return ptr && typeid(T) == typeid(*ptr) ?
143            static_cast<T*>(ptr) : NULL;
144   };
145
146   template<class T>
147   const T* Cast(const AST_Node* ptr) {
148     return ptr && typeid(T) == typeid(*ptr) ?
149            static_cast<const T*>(ptr) : NULL;
150   };
151
152   //////////////////////////////////////////////////////////////////////
153   // Abstract base class for expressions. This side of the AST hierarchy
154   // represents elements in value contexts, which exist primarily to be
155   // evaluated and returned.
156   //////////////////////////////////////////////////////////////////////
157   class Expression : public AST_Node {
158   public:
159     enum Concrete_Type {
160       NONE,
161       BOOLEAN,
162       NUMBER,
163       COLOR,
164       STRING,
165       LIST,
166       MAP,
167       SELECTOR,
168       NULL_VAL,
169       C_WARNING,
170       C_ERROR,
171       FUNCTION,
172       NUM_TYPES
173     };
174     enum Simple_Type {
175       SIMPLE,
176       ATTR_SEL,
177       PSEUDO_SEL,
178       WRAPPED_SEL,
179     };
180   private:
181     // expressions in some contexts shouldn't be evaluated
182     ADD_PROPERTY(bool, is_delayed)
183     ADD_PROPERTY(bool, is_expanded)
184     ADD_PROPERTY(bool, is_interpolant)
185     ADD_PROPERTY(Concrete_Type, concrete_type)
186   public:
187     Expression(ParserState pstate,
188                bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
189     : AST_Node(pstate),
190       is_delayed_(d),
191       is_expanded_(e),
192       is_interpolant_(i),
193       concrete_type_(ct)
194     { }
195     Expression(const Expression* ptr)
196     : AST_Node(ptr),
197       is_delayed_(ptr->is_delayed_),
198       is_expanded_(ptr->is_expanded_),
199       is_interpolant_(ptr->is_interpolant_),
200       concrete_type_(ptr->concrete_type_)
201     { }
202     virtual operator bool() { return true; }
203     virtual ~Expression() { }
204     virtual std::string type() const { return ""; /* TODO: raise an error? */ }
205     virtual bool is_invisible() const { return false; }
206     static std::string type_name() { return ""; }
207     virtual bool is_false() { return false; }
208     // virtual bool is_true() { return !is_false(); }
209     virtual bool operator== (const Expression& rhs) const { return false; }
210     virtual bool eq(const Expression& rhs) const { return *this == rhs; };
211     virtual void set_delayed(bool delayed) { is_delayed(delayed); }
212     virtual bool has_interpolant() const { return is_interpolant(); }
213     virtual bool is_left_interpolant() const { return is_interpolant(); }
214     virtual bool is_right_interpolant() const { return is_interpolant(); }
215     virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
216     virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
217     ATTACH_VIRTUAL_AST_OPERATIONS(Expression);
218     virtual size_t hash() { return 0; }
219   };
220
221   //////////////////////////////////////////////////////////////////////
222   // Still just an expression, but with a to_string method
223   //////////////////////////////////////////////////////////////////////
224   class PreValue : public Expression {
225   public:
226     PreValue(ParserState pstate,
227                bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
228     : Expression(pstate, d, e, i, ct)
229     { }
230     PreValue(const PreValue* ptr)
231     : Expression(ptr)
232     { }
233     ATTACH_VIRTUAL_AST_OPERATIONS(PreValue);
234     virtual ~PreValue() { }
235   };
236
237   //////////////////////////////////////////////////////////////////////
238   // base class for values that support operations
239   //////////////////////////////////////////////////////////////////////
240   class Value : public Expression {
241   public:
242     Value(ParserState pstate,
243           bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
244     : Expression(pstate, d, e, i, ct)
245     { }
246     Value(const Value* ptr)
247     : Expression(ptr)
248     { }
249     ATTACH_VIRTUAL_AST_OPERATIONS(Value);
250     virtual bool operator== (const Expression& rhs) const = 0;
251   };
252 }
253
254 /////////////////////////////////////////////////////////////////////////////////////
255 // Hash method specializations for std::unordered_map to work with Sass::Expression
256 /////////////////////////////////////////////////////////////////////////////////////
257
258 namespace std {
259   template<>
260   struct hash<Sass::Expression_Obj>
261   {
262     size_t operator()(Sass::Expression_Obj s) const
263     {
264       return s->hash();
265     }
266   };
267   template<>
268   struct equal_to<Sass::Expression_Obj>
269   {
270     bool operator()( Sass::Expression_Obj lhs,  Sass::Expression_Obj rhs) const
271     {
272       return lhs->hash() == rhs->hash();
273     }
274   };
275 }
276
277 namespace Sass {
278
279   /////////////////////////////////////////////////////////////////////////////
280   // Mixin class for AST nodes that should behave like vectors. Uses the
281   // "Template Method" design pattern to allow subclasses to adjust their flags
282   // when certain objects are pushed.
283   /////////////////////////////////////////////////////////////////////////////
284   template <typename T>
285   class Vectorized {
286     std::vector<T> elements_;
287   protected:
288     size_t hash_;
289     void reset_hash() { hash_ = 0; }
290     virtual void adjust_after_pushing(T element) { }
291   public:
292     Vectorized(size_t s = 0) : elements_(std::vector<T>()), hash_(0)
293     { elements_.reserve(s); }
294     virtual ~Vectorized() = 0;
295     size_t length() const   { return elements_.size(); }
296     bool empty() const      { return elements_.empty(); }
297     void clear()            { return elements_.clear(); }
298     T last() const          { return elements_.back(); }
299     T first() const         { return elements_.front(); }
300     T& operator[](size_t i) { return elements_[i]; }
301     virtual const T& at(size_t i) const { return elements_.at(i); }
302     virtual T& at(size_t i) { return elements_.at(i); }
303     const T& operator[](size_t i) const { return elements_[i]; }
304     virtual void append(T element)
305     {
306       if (element) {
307         reset_hash();
308         elements_.push_back(element);
309         adjust_after_pushing(element);
310       }
311     }
312     virtual void concat(Vectorized* v)
313     {
314       for (size_t i = 0, L = v->length(); i < L; ++i) this->append((*v)[i]);
315     }
316     Vectorized& unshift(T element)
317     {
318       elements_.insert(elements_.begin(), element);
319       return *this;
320     }
321     std::vector<T>& elements() { return elements_; }
322     const std::vector<T>& elements() const { return elements_; }
323     std::vector<T>& elements(std::vector<T>& e) { elements_ = e; return elements_; }
324
325     virtual size_t hash()
326     {
327       if (hash_ == 0) {
328         for (T& el : elements_) {
329           hash_combine(hash_, el->hash());
330         }
331       }
332       return hash_;
333     }
334
335     typename std::vector<T>::iterator end() { return elements_.end(); }
336     typename std::vector<T>::iterator begin() { return elements_.begin(); }
337     typename std::vector<T>::const_iterator end() const { return elements_.end(); }
338     typename std::vector<T>::const_iterator begin() const { return elements_.begin(); }
339     typename std::vector<T>::iterator erase(typename std::vector<T>::iterator el) { return elements_.erase(el); }
340     typename std::vector<T>::const_iterator erase(typename std::vector<T>::const_iterator el) { return elements_.erase(el); }
341
342   };
343   template <typename T>
344   inline Vectorized<T>::~Vectorized() { }
345
346   /////////////////////////////////////////////////////////////////////////////
347   // Mixin class for AST nodes that should behave like a hash table. Uses an
348   // extra <std::vector> internally to maintain insertion order for interation.
349   /////////////////////////////////////////////////////////////////////////////
350   class Hashed {
351   private:
352     ExpressionMap elements_;
353     std::vector<Expression_Obj> list_;
354   protected:
355     size_t hash_;
356     Expression_Obj duplicate_key_;
357     void reset_hash() { hash_ = 0; }
358     void reset_duplicate_key() { duplicate_key_ = 0; }
359     virtual void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { }
360   public:
361     Hashed(size_t s = 0) : elements_(ExpressionMap(s)), list_(std::vector<Expression_Obj>())
362     { elements_.reserve(s); list_.reserve(s); reset_duplicate_key(); }
363     virtual ~Hashed();
364     size_t length() const                  { return list_.size(); }
365     bool empty() const                     { return list_.empty(); }
366     bool has(Expression_Obj k) const          { return elements_.count(k) == 1; }
367     Expression_Obj at(Expression_Obj k) const;
368     bool has_duplicate_key() const         { return duplicate_key_ != 0; }
369     Expression_Obj get_duplicate_key() const  { return duplicate_key_; }
370     const ExpressionMap elements() { return elements_; }
371     Hashed& operator<<(std::pair<Expression_Obj, Expression_Obj> p)
372     {
373       reset_hash();
374
375       if (!has(p.first)) list_.push_back(p.first);
376       else if (!duplicate_key_) duplicate_key_ = p.first;
377
378       elements_[p.first] = p.second;
379
380       adjust_after_pushing(p);
381       return *this;
382     }
383     Hashed& operator+=(Hashed* h)
384     {
385       if (length() == 0) {
386         this->elements_ = h->elements_;
387         this->list_ = h->list_;
388         return *this;
389       }
390
391       for (auto key : h->keys()) {
392         *this << std::make_pair(key, h->at(key));
393       }
394
395       reset_duplicate_key();
396       return *this;
397     }
398     const ExpressionMap& pairs() const { return elements_; }
399     const std::vector<Expression_Obj>& keys() const { return list_; }
400
401 //    std::unordered_map<Expression_Obj, Expression_Obj>::iterator end() { return elements_.end(); }
402 //    std::unordered_map<Expression_Obj, Expression_Obj>::iterator begin() { return elements_.begin(); }
403 //    std::unordered_map<Expression_Obj, Expression_Obj>::const_iterator end() const { return elements_.end(); }
404 //    std::unordered_map<Expression_Obj, Expression_Obj>::const_iterator begin() const { return elements_.begin(); }
405
406   };
407   inline Hashed::~Hashed() { }
408
409
410   /////////////////////////////////////////////////////////////////////////
411   // Abstract base class for statements. This side of the AST hierarchy
412   // represents elements in expansion contexts, which exist primarily to be
413   // rewritten and macro-expanded.
414   /////////////////////////////////////////////////////////////////////////
415   class Statement : public AST_Node {
416   public:
417     enum Statement_Type {
418       NONE,
419       RULESET,
420       MEDIA,
421       DIRECTIVE,
422       SUPPORTS,
423       ATROOT,
424       BUBBLE,
425       CONTENT,
426       KEYFRAMERULE,
427       DECLARATION,
428       ASSIGNMENT,
429       IMPORT_STUB,
430       IMPORT,
431       COMMENT,
432       WARNING,
433       RETURN,
434       EXTEND,
435       ERROR,
436       DEBUGSTMT,
437       WHILE,
438       EACH,
439       FOR,
440       IF
441     };
442   private:
443     ADD_PROPERTY(Statement_Type, statement_type)
444     ADD_PROPERTY(size_t, tabs)
445     ADD_PROPERTY(bool, group_end)
446   public:
447     Statement(ParserState pstate, Statement_Type st = NONE, size_t t = 0)
448     : AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)
449      { }
450     Statement(const Statement* ptr)
451     : AST_Node(ptr),
452       statement_type_(ptr->statement_type_),
453       tabs_(ptr->tabs_),
454       group_end_(ptr->group_end_)
455      { }
456     virtual ~Statement() = 0;
457     // needed for rearranging nested rulesets during CSS emission
458     virtual bool   is_invisible() const { return false; }
459     virtual bool   bubbles() { return false; }
460     virtual bool has_content()
461     {
462       return statement_type_ == CONTENT;
463     }
464   };
465   inline Statement::~Statement() { }
466
467   ////////////////////////
468   // Blocks of statements.
469   ////////////////////////
470   class Block : public Statement, public Vectorized<Statement_Obj> {
471     ADD_PROPERTY(bool, is_root)
472     // needed for properly formatted CSS emission
473   protected:
474     void adjust_after_pushing(Statement_Obj s)
475     {
476     }
477   public:
478     Block(ParserState pstate, size_t s = 0, bool r = false)
479     : Statement(pstate),
480       Vectorized<Statement_Obj>(s),
481       is_root_(r)
482     { }
483     Block(const Block* ptr)
484     : Statement(ptr),
485       Vectorized<Statement_Obj>(*ptr),
486       is_root_(ptr->is_root_)
487     { }
488     virtual bool has_content()
489     {
490       for (size_t i = 0, L = elements().size(); i < L; ++i) {
491         if (elements()[i]->has_content()) return true;
492       }
493       return Statement::has_content();
494     }
495     ATTACH_AST_OPERATIONS(Block)
496     ATTACH_OPERATIONS()
497   };
498
499   ////////////////////////////////////////////////////////////////////////
500   // Abstract base class for statements that contain blocks of statements.
501   ////////////////////////////////////////////////////////////////////////
502   class Has_Block : public Statement {
503     ADD_PROPERTY(Block_Obj, block)
504   public:
505     Has_Block(ParserState pstate, Block_Obj b)
506     : Statement(pstate), block_(b)
507     { }
508     Has_Block(const Has_Block* ptr)
509     : Statement(ptr), block_(ptr->block_)
510     { }
511     virtual bool has_content()
512     {
513       return (block_ && block_->has_content()) || Statement::has_content();
514     }
515     virtual ~Has_Block() = 0;
516   };
517   inline Has_Block::~Has_Block() { }
518
519   /////////////////////////////////////////////////////////////////////////////
520   // Rulesets (i.e., sets of styles headed by a selector and containing a block
521   // of style declarations.
522   /////////////////////////////////////////////////////////////////////////////
523   class Ruleset : public Has_Block {
524     ADD_PROPERTY(Selector_List_Obj, selector)
525     ADD_PROPERTY(bool, is_root);
526   public:
527     Ruleset(ParserState pstate, Selector_List_Obj s = 0, Block_Obj b = 0)
528     : Has_Block(pstate, b), selector_(s), is_root_(false)
529     { statement_type(RULESET); }
530     Ruleset(const Ruleset* ptr)
531     : Has_Block(ptr),
532       selector_(ptr->selector_),
533       is_root_(ptr->is_root_)
534     { statement_type(RULESET); }
535     bool is_invisible() const;
536     ATTACH_AST_OPERATIONS(Ruleset)
537     ATTACH_OPERATIONS()
538   };
539
540   /////////////////
541   // Bubble.
542   /////////////////
543   class Bubble : public Statement {
544     ADD_PROPERTY(Statement_Obj, node)
545     ADD_PROPERTY(bool, group_end)
546   public:
547     Bubble(ParserState pstate, Statement_Obj n, Statement_Obj g = 0, size_t t = 0)
548     : Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == 0)
549     { }
550     Bubble(const Bubble* ptr)
551     : Statement(ptr),
552       node_(ptr->node_),
553       group_end_(ptr->group_end_)
554     { }
555     bool bubbles() { return true; }
556     ATTACH_AST_OPERATIONS(Bubble)
557     ATTACH_OPERATIONS()
558   };
559
560   /////////////////
561   // Trace.
562   /////////////////
563   class Trace : public Has_Block {
564     ADD_CONSTREF(std::string, name)
565   public:
566     Trace(ParserState pstate, std::string n, Block_Obj b = 0)
567     : Has_Block(pstate, b), name_(n)
568     { }
569     Trace(const Trace* ptr)
570     : Has_Block(ptr),
571       name_(ptr->name_)
572     { }
573     ATTACH_AST_OPERATIONS(Trace)
574     ATTACH_OPERATIONS()
575   };
576
577   /////////////////
578   // Media queries.
579   /////////////////
580   class Media_Block : public Has_Block {
581     ADD_PROPERTY(List_Obj, media_queries)
582   public:
583     Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b)
584     : Has_Block(pstate, b), media_queries_(mqs)
585     { statement_type(MEDIA); }
586     Media_Block(const Media_Block* ptr)
587     : Has_Block(ptr), media_queries_(ptr->media_queries_)
588     { statement_type(MEDIA); }
589     bool bubbles() { return true; }
590     bool is_invisible() const;
591     ATTACH_AST_OPERATIONS(Media_Block)
592     ATTACH_OPERATIONS()
593   };
594
595   ///////////////////////////////////////////////////////////////////////
596   // At-rules -- arbitrary directives beginning with "@" that may have an
597   // optional statement block.
598   ///////////////////////////////////////////////////////////////////////
599   class Directive : public Has_Block {
600     ADD_CONSTREF(std::string, keyword)
601     ADD_PROPERTY(Selector_List_Obj, selector)
602     ADD_PROPERTY(Expression_Obj, value)
603   public:
604     Directive(ParserState pstate, std::string kwd, Selector_List_Obj sel = 0, Block_Obj b = 0, Expression_Obj val = 0)
605     : Has_Block(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
606     { statement_type(DIRECTIVE); }
607     Directive(const Directive* ptr)
608     : Has_Block(ptr),
609       keyword_(ptr->keyword_),
610       selector_(ptr->selector_),
611       value_(ptr->value_) // set value manually if needed
612     { statement_type(DIRECTIVE); }
613     bool bubbles() { return is_keyframes() || is_media(); }
614     bool is_media() {
615       return keyword_.compare("@-webkit-media") == 0 ||
616              keyword_.compare("@-moz-media") == 0 ||
617              keyword_.compare("@-o-media") == 0 ||
618              keyword_.compare("@media") == 0;
619     }
620     bool is_keyframes() {
621       return keyword_.compare("@-webkit-keyframes") == 0 ||
622              keyword_.compare("@-moz-keyframes") == 0 ||
623              keyword_.compare("@-o-keyframes") == 0 ||
624              keyword_.compare("@keyframes") == 0;
625     }
626     ATTACH_AST_OPERATIONS(Directive)
627     ATTACH_OPERATIONS()
628   };
629
630   ///////////////////////////////////////////////////////////////////////
631   // Keyframe-rules -- the child blocks of "@keyframes" nodes.
632   ///////////////////////////////////////////////////////////////////////
633   class Keyframe_Rule : public Has_Block {
634     // according to css spec, this should be <keyframes-name>
635     // <keyframes-name> = <custom-ident> | <string>
636     ADD_PROPERTY(Selector_List_Obj, name)
637   public:
638     Keyframe_Rule(ParserState pstate, Block_Obj b)
639     : Has_Block(pstate, b), name_()
640     { statement_type(KEYFRAMERULE); }
641     Keyframe_Rule(const Keyframe_Rule* ptr)
642     : Has_Block(ptr), name_(ptr->name_)
643     { statement_type(KEYFRAMERULE); }
644     ATTACH_AST_OPERATIONS(Keyframe_Rule)
645     ATTACH_OPERATIONS()
646   };
647
648   ////////////////////////////////////////////////////////////////////////
649   // Declarations -- style rules consisting of a property name and values.
650   ////////////////////////////////////////////////////////////////////////
651   class Declaration : public Has_Block {
652     ADD_PROPERTY(String_Obj, property)
653     ADD_PROPERTY(Expression_Obj, value)
654     ADD_PROPERTY(bool, is_important)
655     ADD_PROPERTY(bool, is_indented)
656   public:
657     Declaration(ParserState pstate,
658                 String_Obj prop, Expression_Obj val, bool i = false, Block_Obj b = 0)
659     : Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_indented_(false)
660     { statement_type(DECLARATION); }
661     Declaration(const Declaration* ptr)
662     : Has_Block(ptr),
663       property_(ptr->property_),
664       value_(ptr->value_),
665       is_important_(ptr->is_important_),
666       is_indented_(ptr->is_indented_)
667     { statement_type(DECLARATION); }
668     ATTACH_AST_OPERATIONS(Declaration)
669     ATTACH_OPERATIONS()
670   };
671
672   /////////////////////////////////////
673   // Assignments -- variable and value.
674   /////////////////////////////////////
675   class Assignment : public Statement {
676     ADD_CONSTREF(std::string, variable)
677     ADD_PROPERTY(Expression_Obj, value)
678     ADD_PROPERTY(bool, is_default)
679     ADD_PROPERTY(bool, is_global)
680   public:
681     Assignment(ParserState pstate,
682                std::string var, Expression_Obj val,
683                bool is_default = false,
684                bool is_global = false)
685     : Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
686     { statement_type(ASSIGNMENT); }
687     Assignment(const Assignment* ptr)
688     : Statement(ptr),
689       variable_(ptr->variable_),
690       value_(ptr->value_),
691       is_default_(ptr->is_default_),
692       is_global_(ptr->is_global_)
693     { statement_type(ASSIGNMENT); }
694     ATTACH_AST_OPERATIONS(Assignment)
695     ATTACH_OPERATIONS()
696   };
697
698   ////////////////////////////////////////////////////////////////////////////
699   // Import directives. CSS and Sass import lists can be intermingled, so it's
700   // necessary to store a list of each in an Import node.
701   ////////////////////////////////////////////////////////////////////////////
702   class Import : public Statement {
703     std::vector<Expression_Obj> urls_;
704     std::vector<Include>     incs_;
705     ADD_PROPERTY(List_Obj,      import_queries);
706   public:
707     Import(ParserState pstate)
708     : Statement(pstate),
709       urls_(std::vector<Expression_Obj>()),
710       incs_(std::vector<Include>()),
711       import_queries_()
712     { statement_type(IMPORT); }
713     Import(const Import* ptr)
714     : Statement(ptr),
715       urls_(ptr->urls_),
716       incs_(ptr->incs_),
717       import_queries_(ptr->import_queries_)
718     { statement_type(IMPORT); }
719     std::vector<Expression_Obj>& urls() { return urls_; }
720     std::vector<Include>& incs() { return incs_; }
721     ATTACH_AST_OPERATIONS(Import)
722     ATTACH_OPERATIONS()
723   };
724
725   // not yet resolved single import
726   // so far we only know requested name
727   class Import_Stub : public Statement {
728     Include resource_;
729   public:
730     std::string abs_path() { return resource_.abs_path; };
731     std::string imp_path() { return resource_.imp_path; };
732     Include resource() { return resource_; };
733
734     Import_Stub(ParserState pstate, Include res)
735     : Statement(pstate), resource_(res)
736     { statement_type(IMPORT_STUB); }
737     Import_Stub(const Import_Stub* ptr)
738     : Statement(ptr), resource_(ptr->resource_)
739     { statement_type(IMPORT_STUB); }
740     ATTACH_AST_OPERATIONS(Import_Stub)
741     ATTACH_OPERATIONS()
742   };
743
744   //////////////////////////////
745   // The Sass `@warn` directive.
746   //////////////////////////////
747   class Warning : public Statement {
748     ADD_PROPERTY(Expression_Obj, message)
749   public:
750     Warning(ParserState pstate, Expression_Obj msg)
751     : Statement(pstate), message_(msg)
752     { statement_type(WARNING); }
753     Warning(const Warning* ptr)
754     : Statement(ptr), message_(ptr->message_)
755     { statement_type(WARNING); }
756     ATTACH_AST_OPERATIONS(Warning)
757     ATTACH_OPERATIONS()
758   };
759
760   ///////////////////////////////
761   // The Sass `@error` directive.
762   ///////////////////////////////
763   class Error : public Statement {
764     ADD_PROPERTY(Expression_Obj, message)
765   public:
766     Error(ParserState pstate, Expression_Obj msg)
767     : Statement(pstate), message_(msg)
768     { statement_type(ERROR); }
769     Error(const Error* ptr)
770     : Statement(ptr), message_(ptr->message_)
771     { statement_type(ERROR); }
772     ATTACH_AST_OPERATIONS(Error)
773     ATTACH_OPERATIONS()
774   };
775
776   ///////////////////////////////
777   // The Sass `@debug` directive.
778   ///////////////////////////////
779   class Debug : public Statement {
780     ADD_PROPERTY(Expression_Obj, value)
781   public:
782     Debug(ParserState pstate, Expression_Obj val)
783     : Statement(pstate), value_(val)
784     { statement_type(DEBUGSTMT); }
785     Debug(const Debug* ptr)
786     : Statement(ptr), value_(ptr->value_)
787     { statement_type(DEBUGSTMT); }
788     ATTACH_AST_OPERATIONS(Debug)
789     ATTACH_OPERATIONS()
790   };
791
792   ///////////////////////////////////////////
793   // CSS comments. These may be interpolated.
794   ///////////////////////////////////////////
795   class Comment : public Statement {
796     ADD_PROPERTY(String_Obj, text)
797     ADD_PROPERTY(bool, is_important)
798   public:
799     Comment(ParserState pstate, String_Obj txt, bool is_important)
800     : Statement(pstate), text_(txt), is_important_(is_important)
801     { statement_type(COMMENT); }
802     Comment(const Comment* ptr)
803     : Statement(ptr),
804       text_(ptr->text_),
805       is_important_(ptr->is_important_)
806     { statement_type(COMMENT); }
807     virtual bool is_invisible() const
808     { return /* is_important() == */ false; }
809     ATTACH_AST_OPERATIONS(Comment)
810     ATTACH_OPERATIONS()
811   };
812
813   ////////////////////////////////////
814   // The Sass `@if` control directive.
815   ////////////////////////////////////
816   class If : public Has_Block {
817     ADD_PROPERTY(Expression_Obj, predicate)
818     ADD_PROPERTY(Block_Obj, alternative)
819   public:
820     If(ParserState pstate, Expression_Obj pred, Block_Obj con, Block_Obj alt = 0)
821     : Has_Block(pstate, con), predicate_(pred), alternative_(alt)
822     { statement_type(IF); }
823     If(const If* ptr)
824     : Has_Block(ptr),
825       predicate_(ptr->predicate_),
826       alternative_(ptr->alternative_)
827     { statement_type(IF); }
828     virtual bool has_content()
829     {
830       return Has_Block::has_content() || (alternative_ && alternative_->has_content());
831     }
832     ATTACH_AST_OPERATIONS(If)
833     ATTACH_OPERATIONS()
834   };
835
836   /////////////////////////////////////
837   // The Sass `@for` control directive.
838   /////////////////////////////////////
839   class For : public Has_Block {
840     ADD_CONSTREF(std::string, variable)
841     ADD_PROPERTY(Expression_Obj, lower_bound)
842     ADD_PROPERTY(Expression_Obj, upper_bound)
843     ADD_PROPERTY(bool, is_inclusive)
844   public:
845     For(ParserState pstate,
846         std::string var, Expression_Obj lo, Expression_Obj hi, Block_Obj b, bool inc)
847     : Has_Block(pstate, b),
848       variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc)
849     { statement_type(FOR); }
850     For(const For* ptr)
851     : Has_Block(ptr),
852       variable_(ptr->variable_),
853       lower_bound_(ptr->lower_bound_),
854       upper_bound_(ptr->upper_bound_),
855       is_inclusive_(ptr->is_inclusive_)
856     { statement_type(FOR); }
857     ATTACH_AST_OPERATIONS(For)
858     ATTACH_OPERATIONS()
859   };
860
861   //////////////////////////////////////
862   // The Sass `@each` control directive.
863   //////////////////////////////////////
864   class Each : public Has_Block {
865     ADD_PROPERTY(std::vector<std::string>, variables)
866     ADD_PROPERTY(Expression_Obj, list)
867   public:
868     Each(ParserState pstate, std::vector<std::string> vars, Expression_Obj lst, Block_Obj b)
869     : Has_Block(pstate, b), variables_(vars), list_(lst)
870     { statement_type(EACH); }
871     Each(const Each* ptr)
872     : Has_Block(ptr), variables_(ptr->variables_), list_(ptr->list_)
873     { statement_type(EACH); }
874     ATTACH_AST_OPERATIONS(Each)
875     ATTACH_OPERATIONS()
876   };
877
878   ///////////////////////////////////////
879   // The Sass `@while` control directive.
880   ///////////////////////////////////////
881   class While : public Has_Block {
882     ADD_PROPERTY(Expression_Obj, predicate)
883   public:
884     While(ParserState pstate, Expression_Obj pred, Block_Obj b)
885     : Has_Block(pstate, b), predicate_(pred)
886     { statement_type(WHILE); }
887     While(const While* ptr)
888     : Has_Block(ptr), predicate_(ptr->predicate_)
889     { statement_type(WHILE); }
890     ATTACH_AST_OPERATIONS(While)
891     ATTACH_OPERATIONS()
892   };
893
894   /////////////////////////////////////////////////////////////
895   // The @return directive for use inside SassScript functions.
896   /////////////////////////////////////////////////////////////
897   class Return : public Statement {
898     ADD_PROPERTY(Expression_Obj, value)
899   public:
900     Return(ParserState pstate, Expression_Obj val)
901     : Statement(pstate), value_(val)
902     { statement_type(RETURN); }
903     Return(const Return* ptr)
904     : Statement(ptr), value_(ptr->value_)
905     { statement_type(RETURN); }
906     ATTACH_AST_OPERATIONS(Return)
907     ATTACH_OPERATIONS()
908   };
909
910   ////////////////////////////////
911   // The Sass `@extend` directive.
912   ////////////////////////////////
913   class Extension : public Statement {
914     ADD_PROPERTY(Selector_List_Obj, selector)
915   public:
916     Extension(ParserState pstate, Selector_List_Obj s)
917     : Statement(pstate), selector_(s)
918     { statement_type(EXTEND); }
919     Extension(const Extension* ptr)
920     : Statement(ptr), selector_(ptr->selector_)
921     { statement_type(EXTEND); }
922     ATTACH_AST_OPERATIONS(Extension)
923     ATTACH_OPERATIONS()
924   };
925
926   /////////////////////////////////////////////////////////////////////////////
927   // Definitions for both mixins and functions. The two cases are distinguished
928   // by a type tag.
929   /////////////////////////////////////////////////////////////////////////////
930   struct Backtrace;
931   typedef const char* Signature;
932   typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtrace*, std::vector<Selector_List_Obj>);
933   class Definition : public Has_Block {
934   public:
935     enum Type { MIXIN, FUNCTION };
936     ADD_CONSTREF(std::string, name)
937     ADD_PROPERTY(Parameters_Obj, parameters)
938     ADD_PROPERTY(Env*, environment)
939     ADD_PROPERTY(Type, type)
940     ADD_PROPERTY(Native_Function, native_function)
941     ADD_PROPERTY(Sass_Function_Entry, c_function)
942     ADD_PROPERTY(void*, cookie)
943     ADD_PROPERTY(bool, is_overload_stub)
944     ADD_PROPERTY(Signature, signature)
945   public:
946     Definition(const Definition* ptr)
947     : Has_Block(ptr),
948       name_(ptr->name_),
949       parameters_(ptr->parameters_),
950       environment_(ptr->environment_),
951       type_(ptr->type_),
952       native_function_(ptr->native_function_),
953       c_function_(ptr->c_function_),
954       cookie_(ptr->cookie_),
955       is_overload_stub_(ptr->is_overload_stub_),
956       signature_(ptr->signature_)
957     { }
958
959     Definition(ParserState pstate,
960                std::string n,
961                Parameters_Obj params,
962                Block_Obj b,
963                Type t)
964     : Has_Block(pstate, b),
965       name_(n),
966       parameters_(params),
967       environment_(0),
968       type_(t),
969       native_function_(0),
970       c_function_(0),
971       cookie_(0),
972       is_overload_stub_(false),
973       signature_(0)
974     { }
975     Definition(ParserState pstate,
976                Signature sig,
977                std::string n,
978                Parameters_Obj params,
979                Native_Function func_ptr,
980                bool overload_stub = false)
981     : Has_Block(pstate, 0),
982       name_(n),
983       parameters_(params),
984       environment_(0),
985       type_(FUNCTION),
986       native_function_(func_ptr),
987       c_function_(0),
988       cookie_(0),
989       is_overload_stub_(overload_stub),
990       signature_(sig)
991     { }
992     Definition(ParserState pstate,
993                Signature sig,
994                std::string n,
995                Parameters_Obj params,
996                Sass_Function_Entry c_func,
997                bool whatever,
998                bool whatever2)
999     : Has_Block(pstate, 0),
1000       name_(n),
1001       parameters_(params),
1002       environment_(0),
1003       type_(FUNCTION),
1004       native_function_(0),
1005       c_function_(c_func),
1006       cookie_(sass_function_get_cookie(c_func)),
1007       is_overload_stub_(false),
1008       signature_(sig)
1009     { }
1010     ATTACH_AST_OPERATIONS(Definition)
1011     ATTACH_OPERATIONS()
1012   };
1013
1014   //////////////////////////////////////
1015   // Mixin calls (i.e., `@include ...`).
1016   //////////////////////////////////////
1017   class Mixin_Call : public Has_Block {
1018     ADD_CONSTREF(std::string, name)
1019     ADD_PROPERTY(Arguments_Obj, arguments)
1020   public:
1021     Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Block_Obj b = 0)
1022     : Has_Block(pstate, b), name_(n), arguments_(args)
1023     { }
1024     Mixin_Call(const Mixin_Call* ptr)
1025     : Has_Block(ptr),
1026       name_(ptr->name_),
1027       arguments_(ptr->arguments_)
1028     { }
1029     ATTACH_AST_OPERATIONS(Mixin_Call)
1030     ATTACH_OPERATIONS()
1031   };
1032
1033   ///////////////////////////////////////////////////
1034   // The @content directive for mixin content blocks.
1035   ///////////////////////////////////////////////////
1036   class Content : public Statement {
1037     ADD_PROPERTY(Media_Block_Ptr, media_block)
1038   public:
1039     Content(ParserState pstate) : Statement(pstate)
1040     { statement_type(CONTENT); }
1041     Content(const Content* ptr) : Statement(ptr)
1042     { statement_type(CONTENT); }
1043     ATTACH_AST_OPERATIONS(Content)
1044     ATTACH_OPERATIONS()
1045   };
1046
1047   ///////////////////////////////////////////////////////////////////////
1048   // Lists of values, both comma- and space-separated (distinguished by a
1049   // type-tag.) Also used to represent variable-length argument lists.
1050   ///////////////////////////////////////////////////////////////////////
1051   class List : public Value, public Vectorized<Expression_Obj> {
1052     void adjust_after_pushing(Expression_Obj e) { is_expanded(false); }
1053   private:
1054     ADD_PROPERTY(enum Sass_Separator, separator)
1055     ADD_PROPERTY(bool, is_arglist)
1056     ADD_PROPERTY(bool, is_bracketed)
1057     ADD_PROPERTY(bool, from_selector)
1058   public:
1059     List(ParserState pstate,
1060          size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false, bool bracket = false)
1061     : Value(pstate),
1062       Vectorized<Expression_Obj>(size),
1063       separator_(sep),
1064       is_arglist_(argl),
1065       is_bracketed_(bracket),
1066       from_selector_(false)
1067     { concrete_type(LIST); }
1068     List(const List* ptr)
1069     : Value(ptr),
1070       Vectorized<Expression_Obj>(*ptr),
1071       separator_(ptr->separator_),
1072       is_arglist_(ptr->is_arglist_),
1073       is_bracketed_(ptr->is_bracketed_),
1074       from_selector_(ptr->from_selector_)
1075     { concrete_type(LIST); }
1076     std::string type() const { return is_arglist_ ? "arglist" : "list"; }
1077     static std::string type_name() { return "list"; }
1078     const char* sep_string(bool compressed = false) const {
1079       return separator() == SASS_SPACE ?
1080         " " : (compressed ? "," : ", ");
1081     }
1082     bool is_invisible() const { return empty() && !is_bracketed(); }
1083     Expression_Obj value_at_index(size_t i);
1084
1085     virtual size_t size() const;
1086
1087     virtual size_t hash()
1088     {
1089       if (hash_ == 0) {
1090         hash_ = std::hash<std::string>()(sep_string());
1091         hash_combine(hash_, std::hash<bool>()(is_bracketed()));
1092         for (size_t i = 0, L = length(); i < L; ++i)
1093           hash_combine(hash_, (elements()[i])->hash());
1094       }
1095       return hash_;
1096     }
1097
1098     virtual void set_delayed(bool delayed)
1099     {
1100       is_delayed(delayed);
1101       // don't set children
1102     }
1103
1104     virtual bool operator== (const Expression& rhs) const;
1105
1106     ATTACH_AST_OPERATIONS(List)
1107     ATTACH_OPERATIONS()
1108   };
1109
1110   ///////////////////////////////////////////////////////////////////////
1111   // Key value paris.
1112   ///////////////////////////////////////////////////////////////////////
1113   class Map : public Value, public Hashed {
1114     void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { is_expanded(false); }
1115   public:
1116     Map(ParserState pstate,
1117          size_t size = 0)
1118     : Value(pstate),
1119       Hashed(size)
1120     { concrete_type(MAP); }
1121     Map(const Map* ptr)
1122     : Value(ptr),
1123       Hashed(*ptr)
1124     { concrete_type(MAP); }
1125     std::string type() const { return "map"; }
1126     static std::string type_name() { return "map"; }
1127     bool is_invisible() const { return empty(); }
1128     List_Obj to_list(Context& ctx, ParserState& pstate);
1129
1130     virtual size_t hash()
1131     {
1132       if (hash_ == 0) {
1133         for (auto key : keys()) {
1134           hash_combine(hash_, key->hash());
1135           hash_combine(hash_, at(key)->hash());
1136         }
1137       }
1138
1139       return hash_;
1140     }
1141
1142     virtual bool operator== (const Expression& rhs) const;
1143
1144     ATTACH_AST_OPERATIONS(Map)
1145     ATTACH_OPERATIONS()
1146   };
1147
1148   inline static const std::string sass_op_to_name(enum Sass_OP op) {
1149     switch (op) {
1150       case AND: return "and"; break;
1151       case OR: return "or"; break;
1152       case EQ: return "eq"; break;
1153       case NEQ: return "neq"; break;
1154       case GT: return "gt"; break;
1155       case GTE: return "gte"; break;
1156       case LT: return "lt"; break;
1157       case LTE: return "lte"; break;
1158       case ADD: return "plus"; break;
1159       case SUB: return "sub"; break;
1160       case MUL: return "times"; break;
1161       case DIV: return "div"; break;
1162       case MOD: return "mod"; break;
1163       // this is only used internally!
1164       case NUM_OPS: return "[OPS]"; break;
1165       default: return "invalid"; break;
1166     }
1167   }
1168
1169   //////////////////////////////////////////////////////////////////////////
1170   // Binary expressions. Represents logical, relational, and arithmetic
1171   // operations. Templatized to avoid large switch statements and repetitive
1172   // subclassing.
1173   //////////////////////////////////////////////////////////////////////////
1174   class Binary_Expression : public PreValue {
1175   private:
1176     HASH_PROPERTY(Operand, op)
1177     HASH_PROPERTY(Expression_Obj, left)
1178     HASH_PROPERTY(Expression_Obj, right)
1179     size_t hash_;
1180   public:
1181     Binary_Expression(ParserState pstate,
1182                       Operand op, Expression_Obj lhs, Expression_Obj rhs)
1183     : PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)
1184     { }
1185     Binary_Expression(const Binary_Expression* ptr)
1186     : PreValue(ptr),
1187       op_(ptr->op_),
1188       left_(ptr->left_),
1189       right_(ptr->right_),
1190       hash_(ptr->hash_)
1191     { }
1192     const std::string type_name() {
1193       switch (optype()) {
1194         case AND: return "and"; break;
1195         case OR: return "or"; break;
1196         case EQ: return "eq"; break;
1197         case NEQ: return "neq"; break;
1198         case GT: return "gt"; break;
1199         case GTE: return "gte"; break;
1200         case LT: return "lt"; break;
1201         case LTE: return "lte"; break;
1202         case ADD: return "add"; break;
1203         case SUB: return "sub"; break;
1204         case MUL: return "mul"; break;
1205         case DIV: return "div"; break;
1206         case MOD: return "mod"; break;
1207         // this is only used internally!
1208         case NUM_OPS: return "[OPS]"; break;
1209         default: return "invalid"; break;
1210       }
1211     }
1212     const std::string separator() {
1213       switch (optype()) {
1214         case AND: return "&&"; break;
1215         case OR: return "||"; break;
1216         case EQ: return "=="; break;
1217         case NEQ: return "!="; break;
1218         case GT: return ">"; break;
1219         case GTE: return ">="; break;
1220         case LT: return "<"; break;
1221         case LTE: return "<="; break;
1222         case ADD: return "+"; break;
1223         case SUB: return "-"; break;
1224         case MUL: return "*"; break;
1225         case DIV: return "/"; break;
1226         case MOD: return "%"; break;
1227         // this is only used internally!
1228         case NUM_OPS: return "[OPS]"; break;
1229         default: return "invalid"; break;
1230       }
1231     }
1232     bool is_left_interpolant(void) const;
1233     bool is_right_interpolant(void) const;
1234     bool has_interpolant() const
1235     {
1236       return is_left_interpolant() ||
1237              is_right_interpolant();
1238     }
1239     virtual void set_delayed(bool delayed)
1240     {
1241       right()->set_delayed(delayed);
1242       left()->set_delayed(delayed);
1243       is_delayed(delayed);
1244     }
1245     virtual bool operator==(const Expression& rhs) const
1246     {
1247       try
1248       {
1249         Binary_Expression_Ptr_Const m = Cast<Binary_Expression>(&rhs);
1250         if (m == 0) return false;
1251         return type() == m->type() &&
1252                *left() == *m->left() &&
1253                *right() == *m->right();
1254       }
1255       catch (std::bad_cast&)
1256       {
1257         return false;
1258       }
1259       catch (...) { throw; }
1260     }
1261     virtual size_t hash()
1262     {
1263       if (hash_ == 0) {
1264         hash_ = std::hash<size_t>()(optype());
1265         hash_combine(hash_, left()->hash());
1266         hash_combine(hash_, right()->hash());
1267       }
1268       return hash_;
1269     }
1270     enum Sass_OP optype() const { return op_.operand; }
1271     ATTACH_AST_OPERATIONS(Binary_Expression)
1272     ATTACH_OPERATIONS()
1273   };
1274
1275   ////////////////////////////////////////////////////////////////////////////
1276   // Arithmetic negation (logical negation is just an ordinary function call).
1277   ////////////////////////////////////////////////////////////////////////////
1278   class Unary_Expression : public Expression {
1279   public:
1280     enum Type { PLUS, MINUS, NOT };
1281   private:
1282     HASH_PROPERTY(Type, optype)
1283     HASH_PROPERTY(Expression_Obj, operand)
1284     size_t hash_;
1285   public:
1286     Unary_Expression(ParserState pstate, Type t, Expression_Obj o)
1287     : Expression(pstate), optype_(t), operand_(o), hash_(0)
1288     { }
1289     Unary_Expression(const Unary_Expression* ptr)
1290     : Expression(ptr),
1291       optype_(ptr->optype_),
1292       operand_(ptr->operand_),
1293       hash_(ptr->hash_)
1294     { }
1295     const std::string type_name() {
1296       switch (optype_) {
1297         case PLUS: return "plus"; break;
1298         case MINUS: return "minus"; break;
1299         case NOT: return "not"; break;
1300         default: return "invalid"; break;
1301       }
1302     }
1303     virtual bool operator==(const Expression& rhs) const
1304     {
1305       try
1306       {
1307         Unary_Expression_Ptr_Const m = Cast<Unary_Expression>(&rhs);
1308         if (m == 0) return false;
1309         return type() == m->type() &&
1310                *operand() == *m->operand();
1311       }
1312       catch (std::bad_cast&)
1313       {
1314         return false;
1315       }
1316       catch (...) { throw; }
1317     }
1318     virtual size_t hash()
1319     {
1320       if (hash_ == 0) {
1321         hash_ = std::hash<size_t>()(optype_);
1322         hash_combine(hash_, operand()->hash());
1323       };
1324       return hash_;
1325     }
1326     ATTACH_AST_OPERATIONS(Unary_Expression)
1327     ATTACH_OPERATIONS()
1328   };
1329
1330   ////////////////////////////////////////////////////////////
1331   // Individual argument objects for mixin and function calls.
1332   ////////////////////////////////////////////////////////////
1333   class Argument : public Expression {
1334     HASH_PROPERTY(Expression_Obj, value)
1335     HASH_CONSTREF(std::string, name)
1336     ADD_PROPERTY(bool, is_rest_argument)
1337     ADD_PROPERTY(bool, is_keyword_argument)
1338     size_t hash_;
1339   public:
1340     Argument(ParserState pstate, Expression_Obj val, std::string n = "", bool rest = false, bool keyword = false)
1341     : Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)
1342     {
1343       if (!name_.empty() && is_rest_argument_) {
1344         error("variable-length argument may not be passed by name", pstate_);
1345       }
1346     }
1347     Argument(const Argument* ptr)
1348     : Expression(ptr),
1349       value_(ptr->value_),
1350       name_(ptr->name_),
1351       is_rest_argument_(ptr->is_rest_argument_),
1352       is_keyword_argument_(ptr->is_keyword_argument_),
1353       hash_(ptr->hash_)
1354     {
1355       if (!name_.empty() && is_rest_argument_) {
1356         error("variable-length argument may not be passed by name", pstate_);
1357       }
1358     }
1359
1360     virtual void set_delayed(bool delayed);
1361     virtual bool operator==(const Expression& rhs) const
1362     {
1363       try
1364       {
1365         Argument_Ptr_Const m = Cast<Argument>(&rhs);
1366         if (!(m && name() == m->name())) return false;
1367         return *value() == *m->value();
1368       }
1369       catch (std::bad_cast&)
1370       {
1371         return false;
1372       }
1373       catch (...) { throw; }
1374     }
1375
1376     virtual size_t hash()
1377     {
1378       if (hash_ == 0) {
1379         hash_ = std::hash<std::string>()(name());
1380         hash_combine(hash_, value()->hash());
1381       }
1382       return hash_;
1383     }
1384
1385     ATTACH_AST_OPERATIONS(Argument)
1386     ATTACH_OPERATIONS()
1387   };
1388
1389   ////////////////////////////////////////////////////////////////////////
1390   // Argument lists -- in their own class to facilitate context-sensitive
1391   // error checking (e.g., ensuring that all ordinal arguments precede all
1392   // named arguments).
1393   ////////////////////////////////////////////////////////////////////////
1394   class Arguments : public Expression, public Vectorized<Argument_Obj> {
1395     ADD_PROPERTY(bool, has_named_arguments)
1396     ADD_PROPERTY(bool, has_rest_argument)
1397     ADD_PROPERTY(bool, has_keyword_argument)
1398   protected:
1399     void adjust_after_pushing(Argument_Obj a);
1400   public:
1401     Arguments(ParserState pstate)
1402     : Expression(pstate),
1403       Vectorized<Argument_Obj>(),
1404       has_named_arguments_(false),
1405       has_rest_argument_(false),
1406       has_keyword_argument_(false)
1407     { }
1408     Arguments(const Arguments* ptr)
1409     : Expression(ptr),
1410       Vectorized<Argument_Obj>(*ptr),
1411       has_named_arguments_(ptr->has_named_arguments_),
1412       has_rest_argument_(ptr->has_rest_argument_),
1413       has_keyword_argument_(ptr->has_keyword_argument_)
1414     { }
1415
1416     virtual void set_delayed(bool delayed);
1417
1418     Argument_Obj get_rest_argument();
1419     Argument_Obj get_keyword_argument();
1420
1421     ATTACH_AST_OPERATIONS(Arguments)
1422     ATTACH_OPERATIONS()
1423   };
1424
1425   //////////////////
1426   // Function calls.
1427   //////////////////
1428   class Function_Call : public PreValue {
1429     HASH_CONSTREF(std::string, name)
1430     HASH_PROPERTY(Arguments_Obj, arguments)
1431     ADD_PROPERTY(bool, via_call)
1432     ADD_PROPERTY(void*, cookie)
1433     size_t hash_;
1434   public:
1435     Function_Call(ParserState pstate, std::string n, Arguments_Obj args, void* cookie)
1436     : PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(cookie), hash_(0)
1437     { concrete_type(FUNCTION); }
1438     Function_Call(ParserState pstate, std::string n, Arguments_Obj args)
1439     : PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)
1440     { concrete_type(FUNCTION); }
1441     Function_Call(const Function_Call* ptr)
1442     : PreValue(ptr),
1443       name_(ptr->name_),
1444       arguments_(ptr->arguments_),
1445       via_call_(ptr->via_call_),
1446       cookie_(ptr->cookie_),
1447       hash_(ptr->hash_)
1448     { concrete_type(FUNCTION); }
1449
1450     virtual bool operator==(const Expression& rhs) const
1451     {
1452       try
1453       {
1454         Function_Call_Ptr_Const m = Cast<Function_Call>(&rhs);
1455         if (!(m && name() == m->name())) return false;
1456         if (!(m && arguments()->length() == m->arguments()->length())) return false;
1457         for (size_t i =0, L = arguments()->length(); i < L; ++i)
1458           if (!(*(*arguments())[i] == *(*m->arguments())[i])) return false;
1459         return true;
1460       }
1461       catch (std::bad_cast&)
1462       {
1463         return false;
1464       }
1465       catch (...) { throw; }
1466     }
1467
1468     virtual size_t hash()
1469     {
1470       if (hash_ == 0) {
1471         hash_ = std::hash<std::string>()(name());
1472         for (auto argument : arguments()->elements())
1473           hash_combine(hash_, argument->hash());
1474       }
1475       return hash_;
1476     }
1477     ATTACH_AST_OPERATIONS(Function_Call)
1478     ATTACH_OPERATIONS()
1479   };
1480
1481   /////////////////////////
1482   // Function call schemas.
1483   /////////////////////////
1484   class Function_Call_Schema : public Expression {
1485     ADD_PROPERTY(String_Obj, name)
1486     ADD_PROPERTY(Arguments_Obj, arguments)
1487   public:
1488     Function_Call_Schema(ParserState pstate, String_Obj n, Arguments_Obj args)
1489     : Expression(pstate), name_(n), arguments_(args)
1490     { concrete_type(STRING); }
1491     Function_Call_Schema(const Function_Call_Schema* ptr)
1492     : Expression(ptr),
1493       name_(ptr->name_),
1494       arguments_(ptr->arguments_)
1495     { concrete_type(STRING); }
1496     ATTACH_AST_OPERATIONS(Function_Call_Schema)
1497     ATTACH_OPERATIONS()
1498   };
1499
1500   ///////////////////////
1501   // Variable references.
1502   ///////////////////////
1503   class Variable : public PreValue {
1504     ADD_CONSTREF(std::string, name)
1505   public:
1506     Variable(ParserState pstate, std::string n)
1507     : PreValue(pstate), name_(n)
1508     { }
1509     Variable(const Variable* ptr)
1510     : PreValue(ptr), name_(ptr->name_)
1511     { }
1512
1513     virtual bool operator==(const Expression& rhs) const
1514     {
1515       try
1516       {
1517         Variable_Ptr_Const e = Cast<Variable>(&rhs);
1518         return e && name() == e->name();
1519       }
1520       catch (std::bad_cast&)
1521       {
1522         return false;
1523       }
1524       catch (...) { throw; }
1525     }
1526
1527     virtual size_t hash()
1528     {
1529       return std::hash<std::string>()(name());
1530     }
1531
1532     ATTACH_AST_OPERATIONS(Variable)
1533     ATTACH_OPERATIONS()
1534   };
1535
1536   ////////////////////////////////////////////////////////////////////////////
1537   // Textual (i.e., unevaluated) numeric data. Variants are distinguished with
1538   // a type tag.
1539   ////////////////////////////////////////////////////////////////////////////
1540   class Textual : public Expression {
1541   public:
1542     enum Type { NUMBER, PERCENTAGE, DIMENSION, HEX };
1543   private:
1544     HASH_PROPERTY(Type, valtype)
1545     HASH_CONSTREF(std::string, value)
1546     size_t hash_;
1547   public:
1548     Textual(ParserState pstate, Type t, std::string val)
1549     : Expression(pstate, DELAYED), valtype_(t), value_(val),
1550       hash_(0)
1551     { }
1552     Textual(const Textual* ptr)
1553     : Expression(ptr),
1554       valtype_(ptr->valtype_),
1555       value_(ptr->value_),
1556       hash_(ptr->hash_)
1557     { }
1558
1559     virtual bool operator==(const Expression& rhs) const
1560     {
1561       try
1562       {
1563         Textual_Ptr_Const e = Cast<Textual>(&rhs);
1564         return e && value() == e->value() && type() == e->type();
1565       }
1566       catch (std::bad_cast&)
1567       {
1568         return false;
1569       }
1570       catch (...) { throw; }
1571     }
1572
1573     virtual size_t hash()
1574     {
1575       if (hash_ == 0) {
1576         hash_ = std::hash<std::string>()(value_);
1577         hash_combine(hash_, std::hash<int>()(valtype_));
1578       }
1579       return hash_;
1580     }
1581
1582     ATTACH_AST_OPERATIONS(Textual)
1583     ATTACH_OPERATIONS()
1584   };
1585
1586   ////////////////////////////////////////////////
1587   // Numbers, percentages, dimensions, and colors.
1588   ////////////////////////////////////////////////
1589   class Number : public Value {
1590     HASH_PROPERTY(double, value)
1591     ADD_PROPERTY(bool, zero)
1592     std::vector<std::string> numerator_units_;
1593     std::vector<std::string> denominator_units_;
1594     size_t hash_;
1595   public:
1596     Number(ParserState pstate, double val, std::string u = "", bool zero = true);
1597
1598     Number(const Number* ptr)
1599     : Value(ptr),
1600       value_(ptr->value_), zero_(ptr->zero_),
1601       numerator_units_(ptr->numerator_units_),
1602       denominator_units_(ptr->denominator_units_),
1603       hash_(ptr->hash_)
1604     { concrete_type(NUMBER); }
1605
1606     bool zero() { return zero_; }
1607     bool is_valid_css_unit() const;
1608     std::vector<std::string>& numerator_units()   { return numerator_units_; }
1609     std::vector<std::string>& denominator_units() { return denominator_units_; }
1610     const std::vector<std::string>& numerator_units() const   { return numerator_units_; }
1611     const std::vector<std::string>& denominator_units() const { return denominator_units_; }
1612     std::string type() const { return "number"; }
1613     static std::string type_name() { return "number"; }
1614     std::string unit() const;
1615
1616     bool is_unitless() const;
1617     double convert_factor(const Number&) const;
1618     bool convert(const std::string& unit = "", bool strict = false);
1619     void normalize(const std::string& unit = "", bool strict = false);
1620     // useful for making one number compatible with another
1621     std::string find_convertible_unit() const;
1622
1623     virtual size_t hash()
1624     {
1625       if (hash_ == 0) {
1626         hash_ = std::hash<double>()(value_);
1627         for (const auto numerator : numerator_units())
1628           hash_combine(hash_, std::hash<std::string>()(numerator));
1629         for (const auto denominator : denominator_units())
1630           hash_combine(hash_, std::hash<std::string>()(denominator));
1631       }
1632       return hash_;
1633     }
1634
1635     virtual bool operator< (const Number& rhs) const;
1636     virtual bool operator== (const Expression& rhs) const;
1637     ATTACH_AST_OPERATIONS(Number)
1638     ATTACH_OPERATIONS()
1639   };
1640
1641   //////////
1642   // Colors.
1643   //////////
1644   class Color : public Value {
1645     HASH_PROPERTY(double, r)
1646     HASH_PROPERTY(double, g)
1647     HASH_PROPERTY(double, b)
1648     HASH_PROPERTY(double, a)
1649     ADD_CONSTREF(std::string, disp)
1650     size_t hash_;
1651   public:
1652     Color(ParserState pstate, double r, double g, double b, double a = 1, const std::string disp = "")
1653     : Value(pstate), r_(r), g_(g), b_(b), a_(a), disp_(disp),
1654       hash_(0)
1655     { concrete_type(COLOR); }
1656     Color(const Color* ptr)
1657     : Value(ptr),
1658       r_(ptr->r_),
1659       g_(ptr->g_),
1660       b_(ptr->b_),
1661       a_(ptr->a_),
1662       disp_(ptr->disp_),
1663       hash_(ptr->hash_)
1664     { concrete_type(COLOR); }
1665     std::string type() const { return "color"; }
1666     static std::string type_name() { return "color"; }
1667
1668     virtual size_t hash()
1669     {
1670       if (hash_ == 0) {
1671         hash_ = std::hash<double>()(a_);
1672         hash_combine(hash_, std::hash<double>()(r_));
1673         hash_combine(hash_, std::hash<double>()(g_));
1674         hash_combine(hash_, std::hash<double>()(b_));
1675       }
1676       return hash_;
1677     }
1678
1679     virtual bool operator== (const Expression& rhs) const;
1680
1681     ATTACH_AST_OPERATIONS(Color)
1682     ATTACH_OPERATIONS()
1683   };
1684
1685   //////////////////////////////
1686   // Errors from Sass_Values.
1687   //////////////////////////////
1688   class Custom_Error : public Value {
1689     ADD_CONSTREF(std::string, message)
1690   public:
1691     Custom_Error(ParserState pstate, std::string msg)
1692     : Value(pstate), message_(msg)
1693     { concrete_type(C_ERROR); }
1694     Custom_Error(const Custom_Error* ptr)
1695     : Value(ptr), message_(ptr->message_)
1696     { concrete_type(C_ERROR); }
1697     virtual bool operator== (const Expression& rhs) const;
1698     ATTACH_AST_OPERATIONS(Custom_Error)
1699     ATTACH_OPERATIONS()
1700   };
1701
1702   //////////////////////////////
1703   // Warnings from Sass_Values.
1704   //////////////////////////////
1705   class Custom_Warning : public Value {
1706     ADD_CONSTREF(std::string, message)
1707   public:
1708     Custom_Warning(ParserState pstate, std::string msg)
1709     : Value(pstate), message_(msg)
1710     { concrete_type(C_WARNING); }
1711     Custom_Warning(const Custom_Warning* ptr)
1712     : Value(ptr), message_(ptr->message_)
1713     { concrete_type(C_WARNING); }
1714     virtual bool operator== (const Expression& rhs) const;
1715     ATTACH_AST_OPERATIONS(Custom_Warning)
1716     ATTACH_OPERATIONS()
1717   };
1718
1719   ////////////
1720   // Booleans.
1721   ////////////
1722   class Boolean : public Value {
1723     HASH_PROPERTY(bool, value)
1724     size_t hash_;
1725   public:
1726     Boolean(ParserState pstate, bool val)
1727     : Value(pstate), value_(val),
1728       hash_(0)
1729     { concrete_type(BOOLEAN); }
1730     Boolean(const Boolean* ptr)
1731     : Value(ptr),
1732       value_(ptr->value_),
1733       hash_(ptr->hash_)
1734     { concrete_type(BOOLEAN); }
1735     virtual operator bool() { return value_; }
1736     std::string type() const { return "bool"; }
1737     static std::string type_name() { return "bool"; }
1738     virtual bool is_false() { return !value_; }
1739
1740     virtual size_t hash()
1741     {
1742       if (hash_ == 0) {
1743         hash_ = std::hash<bool>()(value_);
1744       }
1745       return hash_;
1746     }
1747
1748     virtual bool operator== (const Expression& rhs) const;
1749
1750     ATTACH_AST_OPERATIONS(Boolean)
1751     ATTACH_OPERATIONS()
1752   };
1753
1754   ////////////////////////////////////////////////////////////////////////
1755   // Abstract base class for Sass string values. Includes interpolated and
1756   // "flat" strings.
1757   ////////////////////////////////////////////////////////////////////////
1758   class String : public Value {
1759   public:
1760     String(ParserState pstate, bool delayed = false)
1761     : Value(pstate, delayed)
1762     { concrete_type(STRING); }
1763     String(const String* ptr)
1764     : Value(ptr)
1765     { concrete_type(STRING); }
1766     static std::string type_name() { return "string"; }
1767     virtual ~String() = 0;
1768     virtual void rtrim() = 0;
1769     virtual bool operator==(const Expression& rhs) const = 0;
1770     virtual bool operator<(const Expression& rhs) const {
1771       return this->to_string() < rhs.to_string();
1772     };
1773     ATTACH_VIRTUAL_AST_OPERATIONS(String);
1774     ATTACH_OPERATIONS()
1775   };
1776   inline String::~String() { };
1777
1778   ///////////////////////////////////////////////////////////////////////
1779   // Interpolated strings. Meant to be reduced to flat strings during the
1780   // evaluation phase.
1781   ///////////////////////////////////////////////////////////////////////
1782   class String_Schema : public String, public Vectorized<Expression_Obj> {
1783     // ADD_PROPERTY(bool, has_interpolants)
1784     size_t hash_;
1785   public:
1786     String_Schema(ParserState pstate, size_t size = 0, bool has_interpolants = false)
1787     : String(pstate), Vectorized<Expression_Obj>(size), hash_(0)
1788     { concrete_type(STRING); }
1789     String_Schema(const String_Schema* ptr)
1790     : String(ptr),
1791       Vectorized<Expression_Obj>(*ptr),
1792       hash_(ptr->hash_)
1793     { concrete_type(STRING); }
1794
1795     std::string type() const { return "string"; }
1796     static std::string type_name() { return "string"; }
1797
1798     bool is_left_interpolant(void) const;
1799     bool is_right_interpolant(void) const;
1800     // void has_interpolants(bool tc) { }
1801     bool has_interpolants() {
1802       for (auto el : elements()) {
1803         if (el->is_interpolant()) return true;
1804       }
1805       return false;
1806     }
1807     virtual void rtrim();
1808
1809     virtual size_t hash()
1810     {
1811       if (hash_ == 0) {
1812         for (auto string : elements())
1813           hash_combine(hash_, string->hash());
1814       }
1815       return hash_;
1816     }
1817
1818     virtual void set_delayed(bool delayed) {
1819       is_delayed(delayed);
1820     }
1821
1822     virtual bool operator==(const Expression& rhs) const;
1823     ATTACH_AST_OPERATIONS(String_Schema)
1824     ATTACH_OPERATIONS()
1825   };
1826
1827   ////////////////////////////////////////////////////////
1828   // Flat strings -- the lowest level of raw textual data.
1829   ////////////////////////////////////////////////////////
1830   class String_Constant : public String {
1831     ADD_PROPERTY(char, quote_mark)
1832     ADD_PROPERTY(bool, can_compress_whitespace)
1833     HASH_CONSTREF(std::string, value)
1834   protected:
1835     size_t hash_;
1836   public:
1837     String_Constant(const String_Constant* ptr)
1838     : String(ptr),
1839       quote_mark_(ptr->quote_mark_),
1840       can_compress_whitespace_(ptr->can_compress_whitespace_),
1841       value_(ptr->value_),
1842       hash_(ptr->hash_)
1843     { }
1844     String_Constant(ParserState pstate, std::string val)
1845     : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val)), hash_(0)
1846     { }
1847     String_Constant(ParserState pstate, const char* beg)
1848     : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg))), hash_(0)
1849     { }
1850     String_Constant(ParserState pstate, const char* beg, const char* end)
1851     : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg))), hash_(0)
1852     { }
1853     String_Constant(ParserState pstate, const Token& tok)
1854     : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end))), hash_(0)
1855     { }
1856     std::string type() const { return "string"; }
1857     static std::string type_name() { return "string"; }
1858     virtual bool is_invisible() const;
1859     virtual void rtrim();
1860
1861     virtual size_t hash()
1862     {
1863       if (hash_ == 0) {
1864         hash_ = std::hash<std::string>()(value_);
1865       }
1866       return hash_;
1867     }
1868
1869     virtual bool operator==(const Expression& rhs) const;
1870     virtual std::string inspect() const; // quotes are forced on inspection
1871
1872     // static char auto_quote() { return '*'; }
1873     static char double_quote() { return '"'; }
1874     static char single_quote() { return '\''; }
1875
1876     ATTACH_AST_OPERATIONS(String_Constant)
1877     ATTACH_OPERATIONS()
1878   };
1879
1880   ////////////////////////////////////////////////////////
1881   // Possibly quoted string (unquote on instantiation)
1882   ////////////////////////////////////////////////////////
1883   class String_Quoted : public String_Constant {
1884   public:
1885     String_Quoted(ParserState pstate, std::string val, char q = 0,
1886       bool keep_utf8_escapes = false, bool skip_unquoting = false,
1887       bool strict_unquoting = true)
1888     : String_Constant(pstate, val)
1889     {
1890       if (skip_unquoting == false) {
1891         value_ = unquote(value_, &quote_mark_, keep_utf8_escapes, strict_unquoting);
1892       }
1893       if (q && quote_mark_) quote_mark_ = q;
1894     }
1895     String_Quoted(const String_Quoted* ptr)
1896     : String_Constant(ptr)
1897     { }
1898     virtual bool operator==(const Expression& rhs) const;
1899     virtual std::string inspect() const; // quotes are forced on inspection
1900     ATTACH_AST_OPERATIONS(String_Quoted)
1901     ATTACH_OPERATIONS()
1902   };
1903
1904   /////////////////
1905   // Media queries.
1906   /////////////////
1907   class Media_Query : public Expression,
1908                       public Vectorized<Media_Query_Expression_Obj> {
1909     ADD_PROPERTY(String_Obj, media_type)
1910     ADD_PROPERTY(bool, is_negated)
1911     ADD_PROPERTY(bool, is_restricted)
1912   public:
1913     Media_Query(ParserState pstate,
1914                 String_Obj t = 0, size_t s = 0, bool n = false, bool r = false)
1915     : Expression(pstate), Vectorized<Media_Query_Expression_Obj>(s),
1916       media_type_(t), is_negated_(n), is_restricted_(r)
1917     { }
1918     Media_Query(const Media_Query* ptr)
1919     : Expression(ptr),
1920       Vectorized<Media_Query_Expression_Obj>(*ptr),
1921       media_type_(ptr->media_type_),
1922       is_negated_(ptr->is_negated_),
1923       is_restricted_(ptr->is_restricted_)
1924     { }
1925     ATTACH_AST_OPERATIONS(Media_Query)
1926     ATTACH_OPERATIONS()
1927   };
1928
1929   ////////////////////////////////////////////////////
1930   // Media expressions (for use inside media queries).
1931   ////////////////////////////////////////////////////
1932   class Media_Query_Expression : public Expression {
1933     ADD_PROPERTY(Expression_Obj, feature)
1934     ADD_PROPERTY(Expression_Obj, value)
1935     ADD_PROPERTY(bool, is_interpolated)
1936   public:
1937     Media_Query_Expression(ParserState pstate,
1938                            Expression_Obj f, Expression_Obj v, bool i = false)
1939     : Expression(pstate), feature_(f), value_(v), is_interpolated_(i)
1940     { }
1941     Media_Query_Expression(const Media_Query_Expression* ptr)
1942     : Expression(ptr),
1943       feature_(ptr->feature_),
1944       value_(ptr->value_),
1945       is_interpolated_(ptr->is_interpolated_)
1946     { }
1947     ATTACH_AST_OPERATIONS(Media_Query_Expression)
1948     ATTACH_OPERATIONS()
1949   };
1950
1951   ////////////////////
1952   // `@supports` rule.
1953   ////////////////////
1954   class Supports_Block : public Has_Block {
1955     ADD_PROPERTY(Supports_Condition_Obj, condition)
1956   public:
1957     Supports_Block(ParserState pstate, Supports_Condition_Obj condition, Block_Obj block = 0)
1958     : Has_Block(pstate, block), condition_(condition)
1959     { statement_type(SUPPORTS); }
1960     Supports_Block(const Supports_Block* ptr)
1961     : Has_Block(ptr), condition_(ptr->condition_)
1962     { statement_type(SUPPORTS); }
1963     bool bubbles() { return true; }
1964     ATTACH_AST_OPERATIONS(Supports_Block)
1965     ATTACH_OPERATIONS()
1966   };
1967
1968   //////////////////////////////////////////////////////
1969   // The abstract superclass of all Supports conditions.
1970   //////////////////////////////////////////////////////
1971   class Supports_Condition : public Expression {
1972   public:
1973     Supports_Condition(ParserState pstate)
1974     : Expression(pstate)
1975     { }
1976     Supports_Condition(const Supports_Condition* ptr)
1977     : Expression(ptr)
1978     { }
1979     virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
1980     ATTACH_AST_OPERATIONS(Supports_Condition)
1981     ATTACH_OPERATIONS()
1982   };
1983
1984   ////////////////////////////////////////////////////////////
1985   // An operator condition (e.g. `CONDITION1 and CONDITION2`).
1986   ////////////////////////////////////////////////////////////
1987   class Supports_Operator : public Supports_Condition {
1988   public:
1989     enum Operand { AND, OR };
1990   private:
1991     ADD_PROPERTY(Supports_Condition_Obj, left);
1992     ADD_PROPERTY(Supports_Condition_Obj, right);
1993     ADD_PROPERTY(Operand, operand);
1994   public:
1995     Supports_Operator(ParserState pstate, Supports_Condition_Obj l, Supports_Condition_Obj r, Operand o)
1996     : Supports_Condition(pstate), left_(l), right_(r), operand_(o)
1997     { }
1998     Supports_Operator(const Supports_Operator* ptr)
1999     : Supports_Condition(ptr),
2000       left_(ptr->left_),
2001       right_(ptr->right_),
2002       operand_(ptr->operand_)
2003     { }
2004     virtual bool needs_parens(Supports_Condition_Obj cond) const;
2005     ATTACH_AST_OPERATIONS(Supports_Operator)
2006     ATTACH_OPERATIONS()
2007   };
2008
2009   //////////////////////////////////////////
2010   // A negation condition (`not CONDITION`).
2011   //////////////////////////////////////////
2012   class Supports_Negation : public Supports_Condition {
2013   private:
2014     ADD_PROPERTY(Supports_Condition_Obj, condition);
2015   public:
2016     Supports_Negation(ParserState pstate, Supports_Condition_Obj c)
2017     : Supports_Condition(pstate), condition_(c)
2018     { }
2019     Supports_Negation(const Supports_Negation* ptr)
2020     : Supports_Condition(ptr), condition_(ptr->condition_)
2021     { }
2022     virtual bool needs_parens(Supports_Condition_Obj cond) const;
2023     ATTACH_AST_OPERATIONS(Supports_Negation)
2024     ATTACH_OPERATIONS()
2025   };
2026
2027   /////////////////////////////////////////////////////
2028   // A declaration condition (e.g. `(feature: value)`).
2029   /////////////////////////////////////////////////////
2030   class Supports_Declaration : public Supports_Condition {
2031   private:
2032     ADD_PROPERTY(Expression_Obj, feature);
2033     ADD_PROPERTY(Expression_Obj, value);
2034   public:
2035     Supports_Declaration(ParserState pstate, Expression_Obj f, Expression_Obj v)
2036     : Supports_Condition(pstate), feature_(f), value_(v)
2037     { }
2038     Supports_Declaration(const Supports_Declaration* ptr)
2039     : Supports_Condition(ptr),
2040       feature_(ptr->feature_),
2041       value_(ptr->value_)
2042     { }
2043     virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
2044     ATTACH_AST_OPERATIONS(Supports_Declaration)
2045     ATTACH_OPERATIONS()
2046   };
2047
2048   ///////////////////////////////////////////////
2049   // An interpolation condition (e.g. `#{$var}`).
2050   ///////////////////////////////////////////////
2051   class Supports_Interpolation : public Supports_Condition {
2052   private:
2053     ADD_PROPERTY(Expression_Obj, value);
2054   public:
2055     Supports_Interpolation(ParserState pstate, Expression_Obj v)
2056     : Supports_Condition(pstate), value_(v)
2057     { }
2058     Supports_Interpolation(const Supports_Interpolation* ptr)
2059     : Supports_Condition(ptr),
2060       value_(ptr->value_)
2061     { }
2062     virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
2063     ATTACH_AST_OPERATIONS(Supports_Interpolation)
2064     ATTACH_OPERATIONS()
2065   };
2066
2067   /////////////////////////////////////////////////
2068   // At root expressions (for use inside @at-root).
2069   /////////////////////////////////////////////////
2070   class At_Root_Query : public Expression {
2071   private:
2072     ADD_PROPERTY(Expression_Obj, feature)
2073     ADD_PROPERTY(Expression_Obj, value)
2074   public:
2075     At_Root_Query(ParserState pstate, Expression_Obj f = 0, Expression_Obj v = 0, bool i = false)
2076     : Expression(pstate), feature_(f), value_(v)
2077     { }
2078     At_Root_Query(const At_Root_Query* ptr)
2079     : Expression(ptr),
2080       feature_(ptr->feature_),
2081       value_(ptr->value_)
2082     { }
2083     bool exclude(std::string str);
2084     ATTACH_AST_OPERATIONS(At_Root_Query)
2085     ATTACH_OPERATIONS()
2086   };
2087
2088   ///////////
2089   // At-root.
2090   ///////////
2091   class At_Root_Block : public Has_Block {
2092     ADD_PROPERTY(At_Root_Query_Obj, expression)
2093   public:
2094     At_Root_Block(ParserState pstate, Block_Obj b = 0, At_Root_Query_Obj e = 0)
2095     : Has_Block(pstate, b), expression_(e)
2096     { statement_type(ATROOT); }
2097     At_Root_Block(const At_Root_Block* ptr)
2098     : Has_Block(ptr), expression_(ptr->expression_)
2099     { statement_type(ATROOT); }
2100     bool bubbles() { return true; }
2101     bool exclude_node(Statement_Obj s) {
2102       if (expression() == 0)
2103       {
2104         return s->statement_type() == Statement::RULESET;
2105       }
2106
2107       if (s->statement_type() == Statement::DIRECTIVE)
2108       {
2109         if (Directive_Obj dir = Cast<Directive>(s))
2110         {
2111           std::string keyword(dir->keyword());
2112           if (keyword.length() > 0) keyword.erase(0, 1);
2113           return expression()->exclude(keyword);
2114         }
2115       }
2116       if (s->statement_type() == Statement::MEDIA)
2117       {
2118         return expression()->exclude("media");
2119       }
2120       if (s->statement_type() == Statement::RULESET)
2121       {
2122         return expression()->exclude("rule");
2123       }
2124       if (s->statement_type() == Statement::SUPPORTS)
2125       {
2126         return expression()->exclude("supports");
2127       }
2128       if (Directive_Obj dir = Cast<Directive>(s))
2129       {
2130         if (dir->is_keyframes()) return expression()->exclude("keyframes");
2131       }
2132       return false;
2133     }
2134     ATTACH_AST_OPERATIONS(At_Root_Block)
2135     ATTACH_OPERATIONS()
2136   };
2137
2138   //////////////////
2139   // The null value.
2140   //////////////////
2141   class Null : public Value {
2142   public:
2143     Null(ParserState pstate) : Value(pstate) { concrete_type(NULL_VAL); }
2144     Null(const Null* ptr) : Value(ptr) { concrete_type(NULL_VAL); }
2145     std::string type() const { return "null"; }
2146     static std::string type_name() { return "null"; }
2147     bool is_invisible() const { return true; }
2148     operator bool() { return false; }
2149     bool is_false() { return true; }
2150
2151     virtual size_t hash()
2152     {
2153       return -1;
2154     }
2155
2156     virtual bool operator== (const Expression& rhs) const;
2157
2158     ATTACH_AST_OPERATIONS(Null)
2159     ATTACH_OPERATIONS()
2160   };
2161
2162   /////////////////////////////////
2163   // Thunks for delayed evaluation.
2164   /////////////////////////////////
2165   class Thunk : public Expression {
2166     ADD_PROPERTY(Expression_Obj, expression)
2167     ADD_PROPERTY(Env*, environment)
2168   public:
2169     Thunk(ParserState pstate, Expression_Obj exp, Env* env = 0)
2170     : Expression(pstate), expression_(exp), environment_(env)
2171     { }
2172   };
2173
2174   /////////////////////////////////////////////////////////
2175   // Individual parameter objects for mixins and functions.
2176   /////////////////////////////////////////////////////////
2177   class Parameter : public AST_Node {
2178     ADD_CONSTREF(std::string, name)
2179     ADD_PROPERTY(Expression_Obj, default_value)
2180     ADD_PROPERTY(bool, is_rest_parameter)
2181   public:
2182     Parameter(ParserState pstate,
2183               std::string n, Expression_Obj def = 0, bool rest = false)
2184     : AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)
2185     {
2186       // tried to come up with a spec test for this, but it does no longer
2187       // get  past the parser (it error out earlier). A spec test was added!
2188       // if (default_value_ && is_rest_parameter_) {
2189       //   error("variable-length parameter may not have a default value", pstate_);
2190       // }
2191     }
2192     Parameter(const Parameter* ptr)
2193     : AST_Node(ptr),
2194       name_(ptr->name_),
2195       default_value_(ptr->default_value_),
2196       is_rest_parameter_(ptr->is_rest_parameter_)
2197     {
2198       // tried to come up with a spec test for this, but it does no longer
2199       // get  past the parser (it error out earlier). A spec test was added!
2200       // if (default_value_ && is_rest_parameter_) {
2201       //   error("variable-length parameter may not have a default value", pstate_);
2202       // }
2203     }
2204     ATTACH_AST_OPERATIONS(Parameter)
2205     ATTACH_OPERATIONS()
2206   };
2207
2208   /////////////////////////////////////////////////////////////////////////
2209   // Parameter lists -- in their own class to facilitate context-sensitive
2210   // error checking (e.g., ensuring that all optional parameters follow all
2211   // required parameters).
2212   /////////////////////////////////////////////////////////////////////////
2213   class Parameters : public AST_Node, public Vectorized<Parameter_Obj> {
2214     ADD_PROPERTY(bool, has_optional_parameters)
2215     ADD_PROPERTY(bool, has_rest_parameter)
2216   protected:
2217     void adjust_after_pushing(Parameter_Obj p)
2218     {
2219       if (p->default_value()) {
2220         if (has_rest_parameter_) {
2221           error("optional parameters may not be combined with variable-length parameters", p->pstate());
2222         }
2223         has_optional_parameters_ = true;
2224       }
2225       else if (p->is_rest_parameter()) {
2226         if (has_rest_parameter_) {
2227           error("functions and mixins cannot have more than one variable-length parameter", p->pstate());
2228         }
2229         has_rest_parameter_ = true;
2230       }
2231       else {
2232         if (has_rest_parameter_) {
2233           error("required parameters must precede variable-length parameters", p->pstate());
2234         }
2235         if (has_optional_parameters_) {
2236           error("required parameters must precede optional parameters", p->pstate());
2237         }
2238       }
2239     }
2240   public:
2241     Parameters(ParserState pstate)
2242     : AST_Node(pstate),
2243       Vectorized<Parameter_Obj>(),
2244       has_optional_parameters_(false),
2245       has_rest_parameter_(false)
2246     { }
2247     Parameters(const Parameters* ptr)
2248     : AST_Node(ptr),
2249       Vectorized<Parameter_Obj>(*ptr),
2250       has_optional_parameters_(ptr->has_optional_parameters_),
2251       has_rest_parameter_(ptr->has_rest_parameter_)
2252     { }
2253     ATTACH_AST_OPERATIONS(Parameters)
2254     ATTACH_OPERATIONS()
2255   };
2256
2257   /////////////////////////////////////////
2258   // Abstract base class for CSS selectors.
2259   /////////////////////////////////////////
2260   class Selector : public Expression {
2261     // ADD_PROPERTY(bool, has_reference)
2262     // line break before list separator
2263     ADD_PROPERTY(bool, has_line_feed)
2264     // line break after list separator
2265     ADD_PROPERTY(bool, has_line_break)
2266     // maybe we have optional flag
2267     ADD_PROPERTY(bool, is_optional)
2268     // parent block pointers
2269
2270     // must not be a reference counted object
2271     // otherwise we create circular references
2272     ADD_PROPERTY(Media_Block_Ptr, media_block)
2273   protected:
2274     size_t hash_;
2275   public:
2276     Selector(ParserState pstate)
2277     : Expression(pstate),
2278       has_line_feed_(false),
2279       has_line_break_(false),
2280       is_optional_(false),
2281       media_block_(0),
2282       hash_(0)
2283     { concrete_type(SELECTOR); }
2284     Selector(const Selector* ptr)
2285     : Expression(ptr),
2286       // has_reference_(ptr->has_reference_),
2287       has_line_feed_(ptr->has_line_feed_),
2288       has_line_break_(ptr->has_line_break_),
2289       is_optional_(ptr->is_optional_),
2290       media_block_(ptr->media_block_),
2291       hash_(ptr->hash_)
2292     { concrete_type(SELECTOR); }
2293     virtual ~Selector() = 0;
2294     virtual size_t hash() = 0;
2295     virtual unsigned long specificity() const = 0;
2296     virtual void set_media_block(Media_Block_Ptr mb) {
2297       media_block(mb);
2298     }
2299     virtual bool has_parent_ref() const {
2300       return false;
2301     }
2302     virtual bool has_real_parent_ref() const {
2303       return false;
2304     }
2305     // dispatch to correct handlers
2306     virtual bool operator<(const Selector& rhs) const = 0;
2307     virtual bool operator==(const Selector& rhs) const = 0;
2308     ATTACH_VIRTUAL_AST_OPERATIONS(Selector);
2309   };
2310   inline Selector::~Selector() { }
2311
2312   /////////////////////////////////////////////////////////////////////////
2313   // Interpolated selectors -- the interpolated String will be expanded and
2314   // re-parsed into a normal selector class.
2315   /////////////////////////////////////////////////////////////////////////
2316   class Selector_Schema : public AST_Node {
2317     ADD_PROPERTY(String_Obj, contents)
2318     ADD_PROPERTY(bool, connect_parent);
2319     // must not be a reference counted object
2320     // otherwise we create circular references
2321     ADD_PROPERTY(Media_Block_Ptr, media_block)
2322     // store computed hash
2323     size_t hash_;
2324   public:
2325     Selector_Schema(ParserState pstate, String_Obj c)
2326     : AST_Node(pstate),
2327       contents_(c),
2328       connect_parent_(true),
2329       media_block_(NULL)
2330     { }
2331     Selector_Schema(const Selector_Schema* ptr)
2332     : AST_Node(ptr),
2333       contents_(ptr->contents_),
2334       connect_parent_(ptr->connect_parent_),
2335       media_block_(ptr->media_block_)
2336     { }
2337     virtual bool has_parent_ref() const;
2338     virtual bool has_real_parent_ref() const;
2339     virtual bool operator<(const Selector& rhs) const;
2340     virtual bool operator==(const Selector& rhs) const;
2341     // selector schema is not yet a final selector, so we do not
2342     // have a specificity for it yet. We need to
2343     virtual unsigned long specificity() const { return 0; }
2344     virtual size_t hash() {
2345       if (hash_ == 0) {
2346         hash_combine(hash_, contents_->hash());
2347       }
2348       return hash_;
2349     }
2350     ATTACH_AST_OPERATIONS(Selector_Schema)
2351     ATTACH_OPERATIONS()
2352   };
2353
2354   ////////////////////////////////////////////
2355   // Abstract base class for simple selectors.
2356   ////////////////////////////////////////////
2357   class Simple_Selector : public Selector {
2358     ADD_CONSTREF(std::string, ns)
2359     ADD_CONSTREF(std::string, name)
2360     ADD_PROPERTY(Simple_Type, simple_type)
2361     ADD_PROPERTY(bool, has_ns)
2362   public:
2363     Simple_Selector(ParserState pstate, std::string n = "")
2364     : Selector(pstate), ns_(""), name_(n), has_ns_(false)
2365     {
2366       simple_type(SIMPLE);
2367       size_t pos = n.find('|');
2368       // found some namespace
2369       if (pos != std::string::npos) {
2370         has_ns_ = true;
2371         ns_ = n.substr(0, pos);
2372         name_ = n.substr(pos + 1);
2373       }
2374     }
2375     Simple_Selector(const Simple_Selector* ptr)
2376     : Selector(ptr),
2377       ns_(ptr->ns_),
2378       name_(ptr->name_),
2379       has_ns_(ptr->has_ns_)
2380     { simple_type(SIMPLE); }
2381     virtual std::string ns_name() const
2382     {
2383       std::string name("");
2384       if (has_ns_)
2385         name += ns_ + "|";
2386       return name + name_;
2387     }
2388     virtual size_t hash()
2389     {
2390       if (hash_ == 0) {
2391         hash_combine(hash_, std::hash<int>()(SELECTOR));
2392         hash_combine(hash_, std::hash<std::string>()(ns()));
2393         hash_combine(hash_, std::hash<std::string>()(name()));
2394       }
2395       return hash_;
2396     }
2397     // namespace compare functions
2398     bool is_ns_eq(const Simple_Selector& r) const;
2399     // namespace query functions
2400     bool is_universal_ns() const
2401     {
2402       return has_ns_ && ns_ == "*";
2403     }
2404     bool has_universal_ns() const
2405     {
2406       return !has_ns_ || ns_ == "*";
2407     }
2408     bool is_empty_ns() const
2409     {
2410       return !has_ns_ || ns_ == "";
2411     }
2412     bool has_empty_ns() const
2413     {
2414       return has_ns_ && ns_ == "";
2415     }
2416     bool has_qualified_ns() const
2417     {
2418       return has_ns_ && ns_ != "" && ns_ != "*";
2419     }
2420     // name query functions
2421     bool is_universal() const
2422     {
2423       return name_ == "*";
2424     }
2425
2426     virtual bool has_placeholder() {
2427       return false;
2428     }
2429
2430     virtual ~Simple_Selector() = 0;
2431     virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2432     virtual bool has_parent_ref() const { return false; };
2433     virtual bool has_real_parent_ref() const  { return false; };
2434     virtual bool is_pseudo_element() const { return false; }
2435
2436     virtual bool is_superselector_of(Compound_Selector_Obj sub) { return false; }
2437
2438     virtual bool operator==(const Selector& rhs) const;
2439     virtual bool operator==(const Simple_Selector& rhs) const;
2440     inline bool operator!=(const Simple_Selector& rhs) const { return !(*this == rhs); }
2441
2442     bool operator<(const Selector& rhs) const;
2443     bool operator<(const Simple_Selector& rhs) const;
2444     // default implementation should work for most of the simple selectors (otherwise overload)
2445     ATTACH_VIRTUAL_AST_OPERATIONS(Simple_Selector);
2446     ATTACH_OPERATIONS();
2447   };
2448   inline Simple_Selector::~Simple_Selector() { }
2449
2450
2451   //////////////////////////////////
2452   // The Parent Selector Expression.
2453   //////////////////////////////////
2454   // parent selectors can occur in selectors but also
2455   // inside strings in declarations (Compound_Selector).
2456   // only one simple parent selector means the first case.
2457   class Parent_Selector : public Simple_Selector {
2458     ADD_PROPERTY(bool, real)
2459   public:
2460     Parent_Selector(ParserState pstate, bool r = true)
2461     : Simple_Selector(pstate, "&"), real_(r)
2462     { /* has_reference(true); */ }
2463     Parent_Selector(const Parent_Selector* ptr)
2464     : Simple_Selector(ptr), real_(ptr->real_)
2465     { /* has_reference(true); */ }
2466     bool is_real_parent_ref() const { return real(); };
2467     virtual bool has_parent_ref() const { return true; };
2468     virtual bool has_real_parent_ref() const { return is_real_parent_ref(); };
2469     virtual unsigned long specificity() const
2470     {
2471       return 0;
2472     }
2473     std::string type() const { return "selector"; }
2474     static std::string type_name() { return "selector"; }
2475     ATTACH_AST_OPERATIONS(Parent_Selector)
2476     ATTACH_OPERATIONS()
2477   };
2478
2479   /////////////////////////////////////////////////////////////////////////
2480   // Placeholder selectors (e.g., "%foo") for use in extend-only selectors.
2481   /////////////////////////////////////////////////////////////////////////
2482   class Placeholder_Selector : public Simple_Selector {
2483   public:
2484     Placeholder_Selector(ParserState pstate, std::string n)
2485     : Simple_Selector(pstate, n)
2486     { }
2487     Placeholder_Selector(const Placeholder_Selector* ptr)
2488     : Simple_Selector(ptr)
2489     { }
2490     virtual unsigned long specificity() const
2491     {
2492       return Constants::Specificity_Base;
2493     }
2494     virtual bool has_placeholder() {
2495       return true;
2496     }
2497     virtual ~Placeholder_Selector() {};
2498     ATTACH_AST_OPERATIONS(Placeholder_Selector)
2499     ATTACH_OPERATIONS()
2500   };
2501
2502   /////////////////////////////////////////////////////////////////////
2503   // Element selectors (and the universal selector) -- e.g., div, span, *.
2504   /////////////////////////////////////////////////////////////////////
2505   class Element_Selector : public Simple_Selector {
2506   public:
2507     Element_Selector(ParserState pstate, std::string n)
2508     : Simple_Selector(pstate, n)
2509     { }
2510     Element_Selector(const Element_Selector* ptr)
2511     : Simple_Selector(ptr)
2512     { }
2513     virtual unsigned long specificity() const
2514     {
2515       if (name() == "*") return 0;
2516       else               return Constants::Specificity_Element;
2517     }
2518     virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr, Context&);
2519     virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2520     ATTACH_AST_OPERATIONS(Element_Selector)
2521     ATTACH_OPERATIONS()
2522   };
2523
2524   ////////////////////////////////////////////////
2525   // Class selectors  -- i.e., .foo.
2526   ////////////////////////////////////////////////
2527   class Class_Selector : public Simple_Selector {
2528   public:
2529     Class_Selector(ParserState pstate, std::string n)
2530     : Simple_Selector(pstate, n)
2531     { }
2532     Class_Selector(const Class_Selector* ptr)
2533     : Simple_Selector(ptr)
2534     { }
2535     virtual unsigned long specificity() const
2536     {
2537       return Constants::Specificity_Class;
2538     }
2539     virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2540     ATTACH_AST_OPERATIONS(Class_Selector)
2541     ATTACH_OPERATIONS()
2542   };
2543
2544   ////////////////////////////////////////////////
2545   // ID selectors -- i.e., #foo.
2546   ////////////////////////////////////////////////
2547   class Id_Selector : public Simple_Selector {
2548   public:
2549     Id_Selector(ParserState pstate, std::string n)
2550     : Simple_Selector(pstate, n)
2551     { }
2552     Id_Selector(const Id_Selector* ptr)
2553     : Simple_Selector(ptr)
2554     { }
2555     virtual unsigned long specificity() const
2556     {
2557       return Constants::Specificity_ID;
2558     }
2559     virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2560     ATTACH_AST_OPERATIONS(Id_Selector)
2561     ATTACH_OPERATIONS()
2562   };
2563
2564   ///////////////////////////////////////////////////
2565   // Attribute selectors -- e.g., [src*=".jpg"], etc.
2566   ///////////////////////////////////////////////////
2567   class Attribute_Selector : public Simple_Selector {
2568     ADD_CONSTREF(std::string, matcher)
2569     // this cannot be changed to obj atm!!!!!!????!!!!!!!
2570     ADD_PROPERTY(String_Obj, value) // might be interpolated
2571   public:
2572     Attribute_Selector(ParserState pstate, std::string n, std::string m, String_Obj v)
2573     : Simple_Selector(pstate, n), matcher_(m), value_(v)
2574     { simple_type(ATTR_SEL); }
2575     Attribute_Selector(const Attribute_Selector* ptr)
2576     : Simple_Selector(ptr),
2577       matcher_(ptr->matcher_),
2578       value_(ptr->value_)
2579     { simple_type(ATTR_SEL); }
2580     virtual size_t hash()
2581     {
2582       if (hash_ == 0) {
2583         hash_combine(hash_, Simple_Selector::hash());
2584         hash_combine(hash_, std::hash<std::string>()(matcher()));
2585         if (value_) hash_combine(hash_, value_->hash());
2586       }
2587       return hash_;
2588     }
2589     virtual unsigned long specificity() const
2590     {
2591       return Constants::Specificity_Attr;
2592     }
2593     virtual bool operator==(const Simple_Selector& rhs) const;
2594     virtual bool operator==(const Attribute_Selector& rhs) const;
2595     virtual bool operator<(const Simple_Selector& rhs) const;
2596     virtual bool operator<(const Attribute_Selector& rhs) const;
2597     ATTACH_AST_OPERATIONS(Attribute_Selector)
2598     ATTACH_OPERATIONS()
2599   };
2600
2601   //////////////////////////////////////////////////////////////////
2602   // Pseudo selectors -- e.g., :first-child, :nth-of-type(...), etc.
2603   //////////////////////////////////////////////////////////////////
2604   /* '::' starts a pseudo-element, ':' a pseudo-class */
2605   /* Except :first-line, :first-letter, :before and :after */
2606   /* Note that pseudo-elements are restricted to one per selector */
2607   /* and occur only in the last simple_selector_sequence. */
2608   inline bool is_pseudo_class_element(const std::string& name)
2609   {
2610     return name == ":before"       ||
2611            name == ":after"        ||
2612            name == ":first-line"   ||
2613            name == ":first-letter";
2614   }
2615
2616   // Pseudo Selector cannot have any namespace?
2617   class Pseudo_Selector : public Simple_Selector {
2618     ADD_PROPERTY(String_Obj, expression)
2619   public:
2620     Pseudo_Selector(ParserState pstate, std::string n, String_Obj expr = 0)
2621     : Simple_Selector(pstate, n), expression_(expr)
2622     { simple_type(PSEUDO_SEL); }
2623     Pseudo_Selector(const Pseudo_Selector* ptr)
2624     : Simple_Selector(ptr), expression_(ptr->expression_)
2625     { simple_type(PSEUDO_SEL); }
2626
2627     // A pseudo-element is made of two colons (::) followed by the name.
2628     // The `::` notation is introduced by the current document in order to
2629     // establish a discrimination between pseudo-classes and pseudo-elements.
2630     // For compatibility with existing style sheets, user agents must also
2631     // accept the previous one-colon notation for pseudo-elements introduced
2632     // in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and
2633     // :after). This compatibility is not allowed for the new pseudo-elements
2634     // introduced in this specification.
2635     virtual bool is_pseudo_element() const
2636     {
2637       return (name_[0] == ':' && name_[1] == ':')
2638              || is_pseudo_class_element(name_);
2639     }
2640     virtual size_t hash()
2641     {
2642       if (hash_ == 0) {
2643         hash_combine(hash_, Simple_Selector::hash());
2644         if (expression_) hash_combine(hash_, expression_->hash());
2645       }
2646       return hash_;
2647     }
2648     virtual unsigned long specificity() const
2649     {
2650       if (is_pseudo_element())
2651         return Constants::Specificity_Element;
2652       return Constants::Specificity_Pseudo;
2653     }
2654     virtual bool operator==(const Simple_Selector& rhs) const;
2655     virtual bool operator==(const Pseudo_Selector& rhs) const;
2656     virtual bool operator<(const Simple_Selector& rhs) const;
2657     virtual bool operator<(const Pseudo_Selector& rhs) const;
2658     virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2659     ATTACH_AST_OPERATIONS(Pseudo_Selector)
2660     ATTACH_OPERATIONS()
2661   };
2662
2663   /////////////////////////////////////////////////
2664   // Wrapped selector -- pseudo selector that takes a list of selectors as argument(s) e.g., :not(:first-of-type), :-moz-any(ol p.blah, ul, menu, dir)
2665   /////////////////////////////////////////////////
2666   class Wrapped_Selector : public Simple_Selector {
2667     ADD_PROPERTY(Selector_List_Obj, selector)
2668   public:
2669     Wrapped_Selector(ParserState pstate, std::string n, Selector_List_Obj sel)
2670     : Simple_Selector(pstate, n), selector_(sel)
2671     { simple_type(WRAPPED_SEL); }
2672     Wrapped_Selector(const Wrapped_Selector* ptr)
2673     : Simple_Selector(ptr), selector_(ptr->selector_)
2674     { simple_type(WRAPPED_SEL); }
2675     virtual bool is_superselector_of(Wrapped_Selector_Obj sub);
2676     // Selectors inside the negation pseudo-class are counted like any
2677     // other, but the negation itself does not count as a pseudo-class.
2678     virtual size_t hash();
2679     virtual bool has_parent_ref() const;
2680     virtual bool has_real_parent_ref() const;
2681     virtual unsigned long specificity() const;
2682     virtual bool operator==(const Simple_Selector& rhs) const;
2683     virtual bool operator==(const Wrapped_Selector& rhs) const;
2684     virtual bool operator<(const Simple_Selector& rhs) const;
2685     virtual bool operator<(const Wrapped_Selector& rhs) const;
2686     virtual void cloneChildren();
2687     ATTACH_AST_OPERATIONS(Wrapped_Selector)
2688     ATTACH_OPERATIONS()
2689   };
2690
2691   ////////////////////////////////////////////////////////////////////////////
2692   // Simple selector sequences. Maintains flags indicating whether it contains
2693   // any parent references or placeholders, to simplify expansion.
2694   ////////////////////////////////////////////////////////////////////////////
2695   class Compound_Selector : public Selector, public Vectorized<Simple_Selector_Obj> {
2696   private:
2697     ComplexSelectorSet sources_;
2698     ADD_PROPERTY(bool, extended);
2699     ADD_PROPERTY(bool, has_parent_reference);
2700   protected:
2701     void adjust_after_pushing(Simple_Selector_Obj s)
2702     {
2703       // if (s->has_reference())   has_reference(true);
2704       // if (s->has_placeholder()) has_placeholder(true);
2705     }
2706   public:
2707     Compound_Selector(ParserState pstate, size_t s = 0)
2708     : Selector(pstate),
2709       Vectorized<Simple_Selector_Obj>(s),
2710       extended_(false),
2711       has_parent_reference_(false)
2712     { }
2713     Compound_Selector(const Compound_Selector* ptr)
2714     : Selector(ptr),
2715       Vectorized<Simple_Selector_Obj>(*ptr),
2716       extended_(ptr->extended_),
2717       has_parent_reference_(ptr->has_parent_reference_)
2718     { }
2719     bool contains_placeholder() {
2720       for (size_t i = 0, L = length(); i < L; ++i) {
2721         if ((*this)[i]->has_placeholder()) return true;
2722       }
2723       return false;
2724     };
2725
2726     void append(Simple_Selector_Ptr element);
2727
2728     bool is_universal() const
2729     {
2730       return length() == 1 && (*this)[0]->is_universal();
2731     }
2732
2733     Complex_Selector_Obj to_complex();
2734     Compound_Selector_Ptr unify_with(Compound_Selector_Ptr rhs, Context& ctx);
2735     // virtual Placeholder_Selector_Ptr find_placeholder();
2736     virtual bool has_parent_ref() const;
2737     virtual bool has_real_parent_ref() const;
2738     Simple_Selector_Ptr base() const {
2739       if (length() == 0) return 0;
2740       // ToDo: why is this needed?
2741       if (Cast<Element_Selector>((*this)[0]))
2742         return (*this)[0];
2743       return 0;
2744     }
2745     virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapped = "");
2746     virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapped = "");
2747     virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapped = "");
2748     virtual size_t hash()
2749     {
2750       if (Selector::hash_ == 0) {
2751         hash_combine(Selector::hash_, std::hash<int>()(SELECTOR));
2752         if (length()) hash_combine(Selector::hash_, Vectorized::hash());
2753       }
2754       return Selector::hash_;
2755     }
2756     virtual unsigned long specificity() const
2757     {
2758       int sum = 0;
2759       for (size_t i = 0, L = length(); i < L; ++i)
2760       { sum += (*this)[i]->specificity(); }
2761       return sum;
2762     }
2763
2764     virtual bool has_placeholder()
2765     {
2766       if (length() == 0) return false;
2767       if (Simple_Selector_Obj ss = elements().front()) {
2768         if (ss->has_placeholder()) return true;
2769       }
2770       return false;
2771     }
2772
2773     bool is_empty_reference()
2774     {
2775       return length() == 1 &&
2776              Cast<Parent_Selector>((*this)[0]);
2777     }
2778
2779     virtual bool operator<(const Selector& rhs) const;
2780     virtual bool operator==(const Selector& rhs) const;
2781     virtual bool operator<(const Compound_Selector& rhs) const;
2782     virtual bool operator==(const Compound_Selector& rhs) const;
2783     inline bool operator!=(const Compound_Selector& rhs) const { return !(*this == rhs); }
2784
2785     ComplexSelectorSet& sources() { return sources_; }
2786     void clearSources() { sources_.clear(); }
2787     void mergeSources(ComplexSelectorSet& sources, Context& ctx);
2788
2789     Compound_Selector_Ptr minus(Compound_Selector_Ptr rhs, Context& ctx);
2790     virtual void cloneChildren();
2791     ATTACH_AST_OPERATIONS(Compound_Selector)
2792     ATTACH_OPERATIONS()
2793   };
2794
2795   ////////////////////////////////////////////////////////////////////////////
2796   // General selectors -- i.e., simple sequences combined with one of the four
2797   // CSS selector combinators (">", "+", "~", and whitespace). Essentially a
2798   // linked list.
2799   ////////////////////////////////////////////////////////////////////////////
2800   class Complex_Selector : public Selector {
2801   public:
2802     enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE };
2803   private:
2804     HASH_CONSTREF(Combinator, combinator)
2805     HASH_PROPERTY(Compound_Selector_Obj, head)
2806     HASH_PROPERTY(Complex_Selector_Obj, tail)
2807     HASH_PROPERTY(String_Obj, reference);
2808   public:
2809     bool contains_placeholder() {
2810       if (head() && head()->contains_placeholder()) return true;
2811       if (tail() && tail()->contains_placeholder()) return true;
2812       return false;
2813     };
2814     Complex_Selector(ParserState pstate,
2815                      Combinator c = ANCESTOR_OF,
2816                      Compound_Selector_Obj h = 0,
2817                      Complex_Selector_Obj t = 0,
2818                      String_Obj r = 0)
2819     : Selector(pstate),
2820       combinator_(c),
2821       head_(h), tail_(t),
2822       reference_(r)
2823     {}
2824     Complex_Selector(const Complex_Selector* ptr)
2825     : Selector(ptr),
2826       combinator_(ptr->combinator_),
2827       head_(ptr->head_), tail_(ptr->tail_),
2828       reference_(ptr->reference_)
2829     {};
2830     virtual bool has_parent_ref() const;
2831     virtual bool has_real_parent_ref() const;
2832
2833     Complex_Selector_Obj skip_empty_reference()
2834     {
2835       if ((!head_ || !head_->length() || head_->is_empty_reference()) &&
2836           combinator() == Combinator::ANCESTOR_OF)
2837       {
2838         if (!tail_) return 0;
2839         tail_->has_line_feed_ = this->has_line_feed_;
2840         // tail_->has_line_break_ = this->has_line_break_;
2841         return tail_->skip_empty_reference();
2842       }
2843       return this;
2844     }
2845
2846     // can still have a tail
2847     bool is_empty_ancestor() const
2848     {
2849       return (!head() || head()->length() == 0) &&
2850              combinator() == Combinator::ANCESTOR_OF;
2851     }
2852
2853     Selector_List_Ptr tails(Context& ctx, Selector_List_Ptr tails);
2854
2855     // front returns the first real tail
2856     // skips over parent and empty ones
2857     Complex_Selector_Obj first();
2858     // last returns the last real tail
2859     Complex_Selector_Obj last();
2860
2861     // some shortcuts that should be removed
2862     Complex_Selector_Obj innermost() { return last(); };
2863
2864     size_t length() const;
2865     Selector_List_Ptr resolve_parent_refs(Context& ctx, std::vector<Selector_List_Obj>& pstack, bool implicit_parent = true);
2866     virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = "");
2867     virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = "");
2868     virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = "");
2869     Selector_List_Ptr unify_with(Complex_Selector_Ptr rhs, Context& ctx);
2870     Combinator clear_innermost();
2871     void append(Context&, Complex_Selector_Obj);
2872     void set_innermost(Complex_Selector_Obj, Combinator);
2873     virtual size_t hash()
2874     {
2875       if (hash_ == 0) {
2876         hash_combine(hash_, std::hash<int>()(SELECTOR));
2877         hash_combine(hash_, std::hash<int>()(combinator_));
2878         if (head_) hash_combine(hash_, head_->hash());
2879         if (tail_) hash_combine(hash_, tail_->hash());
2880       }
2881       return hash_;
2882     }
2883     virtual unsigned long specificity() const
2884     {
2885       int sum = 0;
2886       if (head()) sum += head()->specificity();
2887       if (tail()) sum += tail()->specificity();
2888       return sum;
2889     }
2890     virtual void set_media_block(Media_Block_Ptr mb) {
2891       media_block(mb);
2892       if (tail_) tail_->set_media_block(mb);
2893       if (head_) head_->set_media_block(mb);
2894     }
2895     virtual bool has_placeholder() {
2896       if (head_ && head_->has_placeholder()) return true;
2897       if (tail_ && tail_->has_placeholder()) return true;
2898       return false;
2899     }
2900     virtual bool operator<(const Selector& rhs) const;
2901     virtual bool operator==(const Selector& rhs) const;
2902     virtual bool operator<(const Complex_Selector& rhs) const;
2903     virtual bool operator==(const Complex_Selector& rhs) const;
2904     inline bool operator!=(const Complex_Selector& rhs) const { return !(*this == rhs); }
2905     const ComplexSelectorSet sources()
2906     {
2907       //s = Set.new
2908       //seq.map {|sseq_or_op| s.merge sseq_or_op.sources if sseq_or_op.is_a?(SimpleSequence)}
2909       //s
2910
2911       ComplexSelectorSet srcs;
2912
2913       Compound_Selector_Obj pHead = head();
2914       Complex_Selector_Obj  pTail = tail();
2915
2916       if (pHead) {
2917         const ComplexSelectorSet& headSources = pHead->sources();
2918         srcs.insert(headSources.begin(), headSources.end());
2919       }
2920
2921       if (pTail) {
2922         const ComplexSelectorSet& tailSources = pTail->sources();
2923         srcs.insert(tailSources.begin(), tailSources.end());
2924       }
2925
2926       return srcs;
2927     }
2928     void addSources(ComplexSelectorSet& sources, Context& ctx) {
2929       // members.map! {|m| m.is_a?(SimpleSequence) ? m.with_more_sources(sources) : m}
2930       Complex_Selector_Ptr pIter = this;
2931       while (pIter) {
2932         Compound_Selector_Ptr pHead = pIter->head();
2933
2934         if (pHead) {
2935           pHead->mergeSources(sources, ctx);
2936         }
2937
2938         pIter = pIter->tail();
2939       }
2940     }
2941     void clearSources() {
2942       Complex_Selector_Ptr pIter = this;
2943       while (pIter) {
2944         Compound_Selector_Ptr pHead = pIter->head();
2945
2946         if (pHead) {
2947           pHead->clearSources();
2948         }
2949
2950         pIter = pIter->tail();
2951       }
2952     }
2953
2954     virtual void cloneChildren();
2955     ATTACH_AST_OPERATIONS(Complex_Selector)
2956     ATTACH_OPERATIONS()
2957   };
2958
2959   ///////////////////////////////////
2960   // Comma-separated selector groups.
2961   ///////////////////////////////////
2962   class Selector_List : public Selector, public Vectorized<Complex_Selector_Obj> {
2963     ADD_PROPERTY(Selector_Schema_Obj, schema)
2964     ADD_CONSTREF(std::vector<std::string>, wspace)
2965   protected:
2966     void adjust_after_pushing(Complex_Selector_Obj c);
2967   public:
2968     Selector_List(ParserState pstate, size_t s = 0)
2969     : Selector(pstate),
2970       Vectorized<Complex_Selector_Obj>(s),
2971       schema_(NULL),
2972       wspace_(0)
2973     { }
2974     Selector_List(const Selector_List* ptr)
2975     : Selector(ptr),
2976       Vectorized<Complex_Selector_Obj>(*ptr),
2977       schema_(ptr->schema_),
2978       wspace_(ptr->wspace_)
2979     { }
2980     std::string type() const { return "list"; }
2981     // remove parent selector references
2982     // basically unwraps parsed selectors
2983     virtual bool has_parent_ref() const;
2984     virtual bool has_real_parent_ref() const;
2985     void remove_parent_selectors();
2986     Selector_List_Ptr resolve_parent_refs(Context& ctx, std::vector<Selector_List_Obj>& pstack, bool implicit_parent = true);
2987     virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = "");
2988     virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = "");
2989     virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = "");
2990     Selector_List_Ptr unify_with(Selector_List_Ptr, Context&);
2991     void populate_extends(Selector_List_Obj, Context&, Subset_Map&);
2992     Selector_List_Obj eval(Eval& eval);
2993     virtual size_t hash()
2994     {
2995       if (Selector::hash_ == 0) {
2996         hash_combine(Selector::hash_, std::hash<int>()(SELECTOR));
2997         hash_combine(Selector::hash_, Vectorized::hash());
2998       }
2999       return Selector::hash_;
3000     }
3001     virtual unsigned long specificity() const
3002     {
3003       unsigned long sum = 0;
3004       unsigned long specificity = 0;
3005       for (size_t i = 0, L = length(); i < L; ++i)
3006       {
3007         specificity = (*this)[i]->specificity();
3008         if (sum < specificity) sum = specificity;
3009       }
3010       return sum;
3011     }
3012     virtual void set_media_block(Media_Block_Ptr mb) {
3013       media_block(mb);
3014       for (Complex_Selector_Obj cs : elements()) {
3015         cs->set_media_block(mb);
3016       }
3017     }
3018     virtual bool has_placeholder() {
3019       for (Complex_Selector_Obj cs : elements()) {
3020         if (cs->has_placeholder()) return true;
3021       }
3022       return false;
3023     }
3024     virtual bool operator<(const Selector& rhs) const;
3025     virtual bool operator==(const Selector& rhs) const;
3026     virtual bool operator<(const Selector_List& rhs) const;
3027     virtual bool operator==(const Selector_List& rhs) const;
3028     // Selector Lists can be compared to comma lists
3029     virtual bool operator==(const Expression& rhs) const;
3030     virtual void cloneChildren();
3031     ATTACH_AST_OPERATIONS(Selector_List)
3032     ATTACH_OPERATIONS()
3033   };
3034
3035   // compare function for sorting and probably other other uses
3036   struct cmp_complex_selector { inline bool operator() (const Complex_Selector_Obj l, const Complex_Selector_Obj r) { return (*l < *r); } };
3037   struct cmp_compound_selector { inline bool operator() (const Compound_Selector_Obj l, const Compound_Selector_Obj r) { return (*l < *r); } };
3038   struct cmp_simple_selector { inline bool operator() (const Simple_Selector_Obj l, const Simple_Selector_Obj r) { return (*l < *r); } };
3039
3040 }
3041
3042 #ifdef __clang__
3043
3044 #pragma clang diagnostic pop
3045
3046 #endif
3047
3048 #endif