From 3e60b123a0704577c6da5123c16669ee55f08561 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sun, 18 Nov 2018 15:16:32 +0000 Subject: [PATCH] Add and use a `unification_order` method --- src/ast.cpp | 17 ++--------------- src/ast.hpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/constants.cpp | 9 +++++++++ src/constants.hpp | 10 ++++++++++ 4 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/ast.cpp b/src/ast.cpp index d4a7ac0aa..da3540a91 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -505,27 +505,14 @@ namespace Sass { return false; } - namespace { - - int SelectorOrder(Simple_Selector_Ptr sel) { - if (Cast(sel)) return 1; - if (Cast(sel) || Cast(sel)) return 2; - if (Cast(sel)) return 3; - if (Cast(sel)) return Cast(sel)->is_pseudo_element() ? 6 : 4; - if (Cast(sel)) return 5; - return 7; - } - - } // namespace - Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs) { const size_t rsize = rhs->length(); for (size_t i = 0; i < rsize; ++i) { if (to_string() == rhs->at(i)->to_string()) return rhs; } - const int lhs_order = SelectorOrder(this); + const int lhs_order = this->unification_order(); size_t i = rsize; - while (i > 0 && lhs_order < SelectorOrder(rhs->at(i - 1))) --i; + while (i > 0 && lhs_order < rhs->at(i - 1)->unification_order()) --i; rhs->elements().insert(rhs->elements().begin() + i, this); return rhs; } diff --git a/src/ast.hpp b/src/ast.hpp index b6097ab88..ba3ac889e 100644 --- a/src/ast.hpp +++ b/src/ast.hpp @@ -2215,6 +2215,7 @@ namespace Sass { virtual ~Selector() = 0; virtual size_t hash() = 0; virtual unsigned long specificity() const = 0; + virtual int unification_order() const = 0; virtual void set_media_block(Media_Block_Ptr mb) { media_block(mb); } @@ -2394,6 +2395,10 @@ namespace Sass { { return 0; } + int unification_order() const + { + throw std::runtime_error("unification_order for Parent_Selector is undefined"); + } std::string type() const { return "selector"; } static std::string type_name() { return "selector"; } ATTACH_AST_OPERATIONS(Parent_Selector) @@ -2433,6 +2438,10 @@ namespace Sass { { return Constants::Specificity_Base; } + int unification_order() const + { + return Constants::UnificationOrder_Placeholder; + } virtual bool has_placeholder() { return true; } @@ -2457,6 +2466,10 @@ namespace Sass { if (name() == "*") return 0; else return Constants::Specificity_Element; } + int unification_order() const + { + return Constants::UnificationOrder_Element; + } virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr); virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr); virtual bool operator==(const Simple_Selector& rhs) const; @@ -2482,6 +2495,10 @@ namespace Sass { { return Constants::Specificity_Class; } + int unification_order() const + { + return Constants::UnificationOrder_Class; + } virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr); ATTACH_AST_OPERATIONS(Class_Selector) ATTACH_CRTP_PERFORM_METHODS() @@ -2502,6 +2519,10 @@ namespace Sass { { return Constants::Specificity_ID; } + int unification_order() const + { + return Constants::UnificationOrder_Id; + } virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr); ATTACH_AST_OPERATIONS(Id_Selector) ATTACH_CRTP_PERFORM_METHODS() @@ -2538,6 +2559,10 @@ namespace Sass { { return Constants::Specificity_Attr; } + int unification_order() const + { + return Constants::UnificationOrder_Attribute; + } virtual bool operator==(const Simple_Selector& rhs) const; virtual bool operator==(const Attribute_Selector& rhs) const; virtual bool operator<(const Simple_Selector& rhs) const; @@ -2599,6 +2624,12 @@ namespace Sass { return Constants::Specificity_Element; return Constants::Specificity_Pseudo; } + int unification_order() const + { + if (is_pseudo_element()) + return Constants::UnificationOrder_PseudoElement; + return Constants::UnificationOrder_PseudoClass; + } virtual bool operator==(const Simple_Selector& rhs) const; virtual bool operator==(const Pseudo_Selector& rhs) const; virtual bool operator<(const Simple_Selector& rhs) const; @@ -2627,6 +2658,10 @@ namespace Sass { virtual bool has_parent_ref() const; virtual bool has_real_parent_ref() const; virtual unsigned long specificity() const; + int unification_order() const + { + return Constants::UnificationOrder_Wrapped; + } virtual bool find ( bool (*f)(AST_Node_Obj) ); virtual bool operator==(const Simple_Selector& rhs) const; virtual bool operator==(const Wrapped_Selector& rhs) const; @@ -2709,6 +2744,10 @@ namespace Sass { { sum += (*this)[i]->specificity(); } return sum; } + int unification_order() const + { + throw std::runtime_error("unification_order for Compound_Selector is undefined"); + } virtual bool has_placeholder() { @@ -2837,6 +2876,10 @@ namespace Sass { if (tail()) sum += tail()->specificity(); return sum; } + int unification_order() const + { + throw std::runtime_error("unification_order for Complex_Selector is undefined"); + } virtual void set_media_block(Media_Block_Ptr mb) { media_block(mb); if (tail_) tail_->set_media_block(mb); @@ -2960,6 +3003,10 @@ namespace Sass { } return sum; } + int unification_order() const + { + throw std::runtime_error("unification_order for Selector_List is undefined"); + } virtual void set_media_block(Media_Block_Ptr mb) { media_block(mb); for (Complex_Selector_Obj cs : elements()) { diff --git a/src/constants.cpp b/src/constants.cpp index 0ba28e20c..ad6e0f62e 100644 --- a/src/constants.cpp +++ b/src/constants.cpp @@ -18,6 +18,15 @@ namespace Sass { extern const unsigned long Specificity_Pseudo = 1000; extern const unsigned long Specificity_ID = 1000000; + extern const int UnificationOrder_Element = 1; + extern const int UnificationOrder_Id = 2; + extern const int UnificationOrder_Class = 2; + extern const int UnificationOrder_Attribute = 3; + extern const int UnificationOrder_PseudoClass = 4; + extern const int UnificationOrder_Wrapped = 5; + extern const int UnificationOrder_PseudoElement = 6; + extern const int UnificationOrder_Placeholder = 7; + // sass keywords extern const char at_root_kwd[] = "@at-root"; extern const char import_kwd[] = "@import"; diff --git a/src/constants.hpp b/src/constants.hpp index 4fe93571e..4a9327469 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -18,6 +18,16 @@ namespace Sass { extern const unsigned long Specificity_Pseudo; extern const unsigned long Specificity_ID; + // Selector unification order; + extern const int UnificationOrder_Element; + extern const int UnificationOrder_Id; + extern const int UnificationOrder_Class; + extern const int UnificationOrder_Attribute; + extern const int UnificationOrder_PseudoClass; + extern const int UnificationOrder_Wrapped; + extern const int UnificationOrder_PseudoElement; + extern const int UnificationOrder_Placeholder; + // sass keywords extern const char at_root_kwd[]; extern const char import_kwd[];