From aa7386f2fc5f9c3681fbe861220c40b5a7a910b5 Mon Sep 17 00:00:00 2001 From: Marcel Greter Date: Sat, 17 Mar 2018 03:12:15 +0100 Subject: [PATCH] Cleanup CRTP implementation --- src/ast.hpp | 140 ++++++++++++++++++------------------ src/ast_def_macros.hpp | 10 --- src/check_nesting.cpp | 7 -- src/check_nesting.hpp | 11 +-- src/cssize.cpp | 5 -- src/cssize.hpp | 6 +- src/eval.cpp | 5 -- src/eval.hpp | 20 +++--- src/expand.cpp | 9 --- src/expand.hpp | 6 +- src/extend.hpp | 6 +- src/inspect.cpp | 4 -- src/inspect.hpp | 4 -- src/listize.cpp | 5 -- src/listize.hpp | 6 +- src/operation.hpp | 44 +++++++++--- src/remove_placeholders.hpp | 5 +- src/to_value.cpp | 7 -- src/to_value.hpp | 5 -- 19 files changed, 133 insertions(+), 172 deletions(-) diff --git a/src/ast.hpp b/src/ast.hpp index e5b0f06d9..3a62cbcef 100644 --- a/src/ast.hpp +++ b/src/ast.hpp @@ -135,7 +135,7 @@ namespace Sass { public: Offset off() { return pstate(); } Position pos() { return pstate(); } - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; inline AST_Node::~AST_Node() { } @@ -504,7 +504,7 @@ namespace Sass { return Statement::has_content(); } ATTACH_AST_OPERATIONS(Block) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////////////////// @@ -545,7 +545,7 @@ namespace Sass { { statement_type(RULESET); } bool is_invisible() const; ATTACH_AST_OPERATIONS(Ruleset) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////// @@ -565,7 +565,7 @@ namespace Sass { { } bool bubbles() { return true; } ATTACH_AST_OPERATIONS(Bubble) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////// @@ -584,7 +584,7 @@ namespace Sass { name_(ptr->name_) { } ATTACH_AST_OPERATIONS(Trace) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////// @@ -602,7 +602,7 @@ namespace Sass { bool bubbles() { return true; } bool is_invisible() const; ATTACH_AST_OPERATIONS(Media_Block) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////////////////////////////////////// @@ -637,7 +637,7 @@ namespace Sass { keyword_.compare("@keyframes") == 0; } ATTACH_AST_OPERATIONS(Directive) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////////////////////////////////////// @@ -655,7 +655,7 @@ namespace Sass { : Has_Block(ptr), name_(ptr->name_) { statement_type(KEYFRAMERULE); } ATTACH_AST_OPERATIONS(Keyframe_Rule) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////////////////// @@ -682,7 +682,7 @@ namespace Sass { { statement_type(DECLARATION); } virtual bool is_invisible() const; ATTACH_AST_OPERATIONS(Declaration) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////// @@ -708,7 +708,7 @@ namespace Sass { is_global_(ptr->is_global_) { statement_type(ASSIGNMENT); } ATTACH_AST_OPERATIONS(Assignment) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////////////////////// @@ -735,7 +735,7 @@ namespace Sass { std::vector& urls() { return urls_; } std::vector& incs() { return incs_; } ATTACH_AST_OPERATIONS(Import) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; // not yet resolved single import @@ -754,7 +754,7 @@ namespace Sass { : Statement(ptr), resource_(ptr->resource_) { statement_type(IMPORT_STUB); } ATTACH_AST_OPERATIONS(Import_Stub) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////////////////// @@ -770,7 +770,7 @@ namespace Sass { : Statement(ptr), message_(ptr->message_) { statement_type(WARNING); } ATTACH_AST_OPERATIONS(Warning) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////// @@ -786,7 +786,7 @@ namespace Sass { : Statement(ptr), message_(ptr->message_) { statement_type(ERROR); } ATTACH_AST_OPERATIONS(Error) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////// @@ -802,7 +802,7 @@ namespace Sass { : Statement(ptr), value_(ptr->value_) { statement_type(DEBUGSTMT); } ATTACH_AST_OPERATIONS(Debug) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////////// @@ -823,7 +823,7 @@ namespace Sass { virtual bool is_invisible() const { return /* is_important() == */ false; } ATTACH_AST_OPERATIONS(Comment) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////// @@ -846,7 +846,7 @@ namespace Sass { return Has_Block::has_content() || (alternative_ && alternative_->has_content()); } ATTACH_AST_OPERATIONS(If) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////// @@ -871,7 +871,7 @@ namespace Sass { is_inclusive_(ptr->is_inclusive_) { statement_type(FOR); } ATTACH_AST_OPERATIONS(For) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////////////////////////// @@ -888,7 +888,7 @@ namespace Sass { : Has_Block(ptr), variables_(ptr->variables_), list_(ptr->list_) { statement_type(EACH); } ATTACH_AST_OPERATIONS(Each) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////// @@ -904,7 +904,7 @@ namespace Sass { : Has_Block(ptr), predicate_(ptr->predicate_) { statement_type(WHILE); } ATTACH_AST_OPERATIONS(While) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////////////////////////// @@ -920,7 +920,7 @@ namespace Sass { : Statement(ptr), value_(ptr->value_) { statement_type(RETURN); } ATTACH_AST_OPERATIONS(Return) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////// @@ -936,7 +936,7 @@ namespace Sass { : Statement(ptr), selector_(ptr->selector_) { statement_type(EXTEND); } ATTACH_AST_OPERATIONS(Extension) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////////////////////////////////////////// @@ -1023,7 +1023,7 @@ namespace Sass { signature_(sig) { } ATTACH_AST_OPERATIONS(Definition) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////////////////////////// @@ -1042,7 +1042,7 @@ namespace Sass { arguments_(ptr->arguments_) { } ATTACH_AST_OPERATIONS(Mixin_Call) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////////////////// @@ -1060,7 +1060,7 @@ namespace Sass { media_block_(ptr->media_block_) { statement_type(CONTENT); } ATTACH_AST_OPERATIONS(Content) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////////////////////////////////////// @@ -1123,7 +1123,7 @@ namespace Sass { virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(List) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////////////////////////////////////// @@ -1161,7 +1161,7 @@ namespace Sass { virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(Map) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; inline static const std::string sass_op_to_name(enum Sass_OP op) { @@ -1275,7 +1275,7 @@ namespace Sass { } enum Sass_OP optype() const { return op_.operand; } ATTACH_AST_OPERATIONS(Binary_Expression) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////////////////////// @@ -1331,7 +1331,7 @@ namespace Sass { return hash_; } ATTACH_AST_OPERATIONS(Unary_Expression) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////// @@ -1390,7 +1390,7 @@ namespace Sass { } ATTACH_AST_OPERATIONS(Argument) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////////////////// @@ -1426,7 +1426,7 @@ namespace Sass { Argument_Obj get_keyword_argument(); ATTACH_AST_OPERATIONS(Arguments) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////// @@ -1458,7 +1458,7 @@ namespace Sass { virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(Function) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////// @@ -1524,7 +1524,7 @@ namespace Sass { return hash_; } ATTACH_AST_OPERATIONS(Function_Call) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////// @@ -1543,7 +1543,7 @@ namespace Sass { arguments_(ptr->arguments_) { concrete_type(STRING); } ATTACH_AST_OPERATIONS(Function_Call_Schema) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////// @@ -1579,7 +1579,7 @@ namespace Sass { } ATTACH_AST_OPERATIONS(Variable) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////// @@ -1622,7 +1622,7 @@ namespace Sass { virtual bool operator== (const Number& rhs) const; virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(Number) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////// @@ -1666,7 +1666,7 @@ namespace Sass { virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(Color) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////////////////// @@ -1683,7 +1683,7 @@ namespace Sass { { concrete_type(C_ERROR); } virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(Custom_Error) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////////////////// @@ -1700,7 +1700,7 @@ namespace Sass { { concrete_type(C_WARNING); } virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(Custom_Warning) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////// @@ -1735,7 +1735,7 @@ namespace Sass { virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(Boolean) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////////////////// @@ -1758,7 +1758,7 @@ namespace Sass { return this->to_string() < rhs.to_string(); }; ATTACH_VIRTUAL_AST_OPERATIONS(String); - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; inline String::~String() { }; @@ -1809,7 +1809,7 @@ namespace Sass { virtual bool operator==(const Expression& rhs) const; ATTACH_AST_OPERATIONS(String_Schema) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////// @@ -1862,7 +1862,7 @@ namespace Sass { static char single_quote() { return '\''; } ATTACH_AST_OPERATIONS(String_Constant) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////// @@ -1886,7 +1886,7 @@ namespace Sass { virtual bool operator==(const Expression& rhs) const; virtual std::string inspect() const; // quotes are forced on inspection ATTACH_AST_OPERATIONS(String_Quoted) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////// @@ -1911,7 +1911,7 @@ namespace Sass { is_restricted_(ptr->is_restricted_) { } ATTACH_AST_OPERATIONS(Media_Query) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////// @@ -1933,7 +1933,7 @@ namespace Sass { is_interpolated_(ptr->is_interpolated_) { } ATTACH_AST_OPERATIONS(Media_Query_Expression) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////// @@ -1950,7 +1950,7 @@ namespace Sass { { statement_type(SUPPORTS); } bool bubbles() { return true; } ATTACH_AST_OPERATIONS(Supports_Block) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////////////////////////////////////////// @@ -1966,7 +1966,7 @@ namespace Sass { { } virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; } ATTACH_AST_OPERATIONS(Supports_Condition) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////// @@ -1991,7 +1991,7 @@ namespace Sass { { } virtual bool needs_parens(Supports_Condition_Obj cond) const; ATTACH_AST_OPERATIONS(Supports_Operator) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////////////////////////////// @@ -2009,7 +2009,7 @@ namespace Sass { { } virtual bool needs_parens(Supports_Condition_Obj cond) const; ATTACH_AST_OPERATIONS(Supports_Negation) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////////////////// @@ -2030,7 +2030,7 @@ namespace Sass { { } virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; } ATTACH_AST_OPERATIONS(Supports_Declaration) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////////////// @@ -2049,7 +2049,7 @@ namespace Sass { { } virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; } ATTACH_AST_OPERATIONS(Supports_Interpolation) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////////////// @@ -2070,7 +2070,7 @@ namespace Sass { { } bool exclude(std::string str); ATTACH_AST_OPERATIONS(At_Root_Query) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////// @@ -2120,7 +2120,7 @@ namespace Sass { return false; } ATTACH_AST_OPERATIONS(At_Root_Block) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////// @@ -2144,7 +2144,7 @@ namespace Sass { virtual bool operator== (const Expression& rhs) const; ATTACH_AST_OPERATIONS(Null) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////// @@ -2190,7 +2190,7 @@ namespace Sass { // } } ATTACH_AST_OPERATIONS(Parameter) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////////////////////////////////////// @@ -2239,7 +2239,7 @@ namespace Sass { has_rest_parameter_(ptr->has_rest_parameter_) { } ATTACH_AST_OPERATIONS(Parameters) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////// @@ -2338,7 +2338,7 @@ namespace Sass { return hash_; } ATTACH_AST_OPERATIONS(Selector_Schema) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////// @@ -2433,7 +2433,7 @@ namespace Sass { bool operator<(const Simple_Selector& rhs) const; // default implementation should work for most of the simple selectors (otherwise overload) ATTACH_VIRTUAL_AST_OPERATIONS(Simple_Selector); - ATTACH_OPERATIONS(); + ATTACH_CRTP_PERFORM_METHODS(); }; inline Simple_Selector::~Simple_Selector() { } @@ -2463,7 +2463,7 @@ namespace Sass { std::string type() const { return "selector"; } static std::string type_name() { return "selector"; } ATTACH_AST_OPERATIONS(Parent_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////////////////////////////////////// @@ -2486,7 +2486,7 @@ namespace Sass { } virtual ~Placeholder_Selector() {}; ATTACH_AST_OPERATIONS(Placeholder_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////////////////////////////////// @@ -2512,7 +2512,7 @@ namespace Sass { virtual bool operator<(const Simple_Selector& rhs) const; virtual bool operator<(const Element_Selector& rhs) const; ATTACH_AST_OPERATIONS(Element_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////// @@ -2532,7 +2532,7 @@ namespace Sass { } virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr); ATTACH_AST_OPERATIONS(Class_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////// @@ -2552,7 +2552,7 @@ namespace Sass { } virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr); ATTACH_AST_OPERATIONS(Id_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////////////////////// @@ -2591,7 +2591,7 @@ namespace Sass { virtual bool operator<(const Simple_Selector& rhs) const; virtual bool operator<(const Attribute_Selector& rhs) const; ATTACH_AST_OPERATIONS(Attribute_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ////////////////////////////////////////////////////////////////// @@ -2653,7 +2653,7 @@ namespace Sass { virtual bool operator<(const Pseudo_Selector& rhs) const; virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr); ATTACH_AST_OPERATIONS(Pseudo_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; ///////////////////////////////////////////////// @@ -2682,7 +2682,7 @@ namespace Sass { virtual bool operator<(const Wrapped_Selector& rhs) const; virtual void cloneChildren(); ATTACH_AST_OPERATIONS(Wrapped_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////////////////////// @@ -2787,7 +2787,7 @@ namespace Sass { Compound_Selector_Ptr minus(Compound_Selector_Ptr rhs); virtual void cloneChildren(); ATTACH_AST_OPERATIONS(Compound_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; //////////////////////////////////////////////////////////////////////////// @@ -2952,7 +2952,7 @@ namespace Sass { virtual void cloneChildren(); ATTACH_AST_OPERATIONS(Complex_Selector) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; /////////////////////////////////// @@ -3029,7 +3029,7 @@ namespace Sass { virtual bool operator==(const Expression& rhs) const; virtual void cloneChildren(); ATTACH_AST_OPERATIONS(Selector_List) - ATTACH_OPERATIONS() + ATTACH_CRTP_PERFORM_METHODS() }; // compare function for sorting and probably other other uses diff --git a/src/ast_def_macros.hpp b/src/ast_def_macros.hpp index b3a7f8d16..61e982156 100644 --- a/src/ast_def_macros.hpp +++ b/src/ast_def_macros.hpp @@ -35,16 +35,6 @@ class LocalOption { LocalOption cnt_##name(name, name + 1); \ if (name > MAX_NESTING) throw Exception::NestingLimitError(pstate, traces); \ -#define ATTACH_OPERATIONS()\ -virtual void perform(Operation* op) { (*op)(this); }\ -virtual AST_Node_Ptr perform(Operation* op) { return (*op)(this); }\ -virtual Statement_Ptr perform(Operation* op) { return (*op)(this); }\ -virtual Expression_Ptr perform(Operation* op) { return (*op)(this); }\ -virtual Selector_Ptr perform(Operation* op) { return (*op)(this); }\ -virtual std::string perform(Operation* op) { return (*op)(this); }\ -virtual union Sass_Value* perform(Operation* op) { return (*op)(this); }\ -virtual Value_Ptr perform(Operation* op) { return (*op)(this); } - #define ADD_PROPERTY(type, name)\ protected:\ type name##_;\ diff --git a/src/check_nesting.cpp b/src/check_nesting.cpp index 880bcca37..b43b03197 100644 --- a/src/check_nesting.cpp +++ b/src/check_nesting.cpp @@ -132,13 +132,6 @@ namespace Sass { return i; } - Statement_Ptr CheckNesting::fallback_impl(Statement_Ptr s) - { - Block_Ptr b1 = Cast(s); - Has_Block_Ptr b2 = Cast(s); - return b1 || b2 ? visit_children(s) : s; - } - bool CheckNesting::should_visit(Statement_Ptr node) { if (!this->parent) return true; diff --git a/src/check_nesting.hpp b/src/check_nesting.hpp index 62c38d9dc..687f4afdd 100644 --- a/src/check_nesting.hpp +++ b/src/check_nesting.hpp @@ -13,7 +13,6 @@ namespace Sass { Statement_Ptr parent; Definition_Ptr current_mixin_definition; - Statement_Ptr fallback_impl(Statement_Ptr); Statement_Ptr before(Statement_Ptr); Statement_Ptr visit_children(Statement_Ptr); @@ -27,11 +26,13 @@ namespace Sass { template Statement_Ptr fallback(U x) { - Statement_Ptr n = Cast(x); - if (this->should_visit(n)) { - return fallback_impl(n); + Statement_Ptr s = Cast(x); + if (s && this->should_visit(s)) { + Block_Ptr b1 = Cast(s); + Has_Block_Ptr b2 = Cast(s); + if (b1 || b2) return visit_children(s); } - return NULL; + return s; } private: diff --git a/src/cssize.cpp b/src/cssize.cpp index d5780dd70..cb4ab2c99 100644 --- a/src/cssize.cpp +++ b/src/cssize.cpp @@ -509,11 +509,6 @@ namespace Sass { return flatten(result); } - Statement_Ptr Cssize::fallback_impl(AST_Node_Ptr n) - { - return static_cast(n); - } - void Cssize::append_block(Block_Ptr b, Block_Ptr cur) { for (size_t i = 0, L = b->length(); i < L; ++i) { diff --git a/src/cssize.hpp b/src/cssize.hpp index 4dad47579..d6962fbf3 100644 --- a/src/cssize.hpp +++ b/src/cssize.hpp @@ -17,8 +17,6 @@ namespace Sass { BlockStack block_stack; std::vector p_stack; - Statement_Ptr fallback_impl(AST_Node_Ptr n); - public: Cssize(Context&); ~Cssize() { } @@ -66,8 +64,10 @@ namespace Sass { List_Ptr merge_media_queries(Media_Block_Ptr, Media_Block_Ptr); Media_Query_Ptr merge_media_query(Media_Query_Ptr, Media_Query_Ptr); + // generic fallback template - Statement_Ptr fallback(U x) { return fallback_impl(x); } + Statement_Ptr fallback(U x) + { return Cast(x); } void append_block(Block_Ptr, Block_Ptr); }; diff --git a/src/eval.cpp b/src/eval.cpp index 010cb9bb9..1a0c7a8bd 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -1467,11 +1467,6 @@ namespace Sass { return 0; } - inline Expression_Ptr Eval::fallback_impl(AST_Node_Ptr n) - { - return static_cast(n); - } - // All the binary helpers. Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtraces traces, ParserState pstate) diff --git a/src/eval.hpp b/src/eval.hpp index aeaada87e..a5895fd89 100644 --- a/src/eval.hpp +++ b/src/eval.hpp @@ -14,9 +14,6 @@ namespace Sass { class Eval : public Operation_CRTP { - private: - Expression_Ptr fallback_impl(AST_Node_Ptr n); - public: Expand& exp; Context& ctx; @@ -78,18 +75,23 @@ namespace Sass { Compound_Selector_Ptr operator()(Compound_Selector_Ptr); Simple_Selector_Ptr operator()(Simple_Selector_Ptr s); Wrapped_Selector_Ptr operator()(Wrapped_Selector_Ptr s); + // they don't have any specific implementation (yet) - // Element_Selector_Ptr operator()(Element_Selector_Ptr s) { return s; }; - // Pseudo_Selector_Ptr operator()(Pseudo_Selector_Ptr s) { return s; }; - // Class_Selector_Ptr operator()(Class_Selector_Ptr s) { return s; }; - // Id_Selector_Ptr operator()(Id_Selector_Ptr s) { return s; }; - // Placeholder_Selector_Ptr operator()(Placeholder_Selector_Ptr s) { return s; }; + Id_Selector_Ptr operator()(Id_Selector_Ptr s) { return s; }; + Class_Selector_Ptr operator()(Class_Selector_Ptr s) { return s; }; + Pseudo_Selector_Ptr operator()(Pseudo_Selector_Ptr s) { return s; }; + Element_Selector_Ptr operator()(Element_Selector_Ptr s) { return s; }; + Attribute_Selector_Ptr operator()(Attribute_Selector_Ptr s) { return s; }; + Placeholder_Selector_Ptr operator()(Placeholder_Selector_Ptr s) { return s; }; + // actual evaluated selectors Selector_List_Ptr operator()(Selector_Schema_Ptr); Expression_Ptr operator()(Parent_Selector_Ptr); + // generic fallback template - Expression_Ptr fallback(U x) { return fallback_impl(x); } + Expression_Ptr fallback(U x) + { return Cast(x); } private: void interpolation(Context& ctx, std::string& res, Expression_Obj ex, bool into_quotes, bool was_itpl = false); diff --git a/src/expand.cpp b/src/expand.cpp index 0bf0b78eb..7db489c57 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -792,15 +792,6 @@ namespace Sass { return trace.detach(); } - // produce an error if something is not implemented - inline Statement_Ptr Expand::fallback_impl(AST_Node_Ptr n) - { - std::string err =std:: string("`Expand` doesn't handle ") + typeid(*n).name(); - String_Quoted_Obj msg = SASS_MEMORY_NEW(String_Quoted, ParserState("[WARN]"), err); - error("unknown internal error; please contact the LibSass maintainers", n->pstate(), traces); - return SASS_MEMORY_NEW(Warning, ParserState("[WARN]"), msg); - } - // process and add to last block on stack inline void Expand::append_block(Block_Ptr b) { diff --git a/src/expand.hpp b/src/expand.hpp index 3d6d1eb6b..d88305e09 100644 --- a/src/expand.hpp +++ b/src/expand.hpp @@ -38,8 +38,6 @@ namespace Sass { Boolean_Obj bool_true; - Statement_Ptr fallback_impl(AST_Node_Ptr n); - private: void expand_selector_list(Selector_Obj, Selector_List_Obj extender); @@ -71,10 +69,8 @@ namespace Sass { Statement_Ptr operator()(Mixin_Call_Ptr); Statement_Ptr operator()(Content_Ptr); - template - Statement_Ptr fallback(U x) { return fallback_impl(x); } - void append_block(Block_Ptr); + }; } diff --git a/src/extend.hpp b/src/extend.hpp index 03042f3e2..e222359e3 100644 --- a/src/extend.hpp +++ b/src/extend.hpp @@ -20,8 +20,6 @@ namespace Sass { Subset_Map& subset_map; Eval* eval; - void fallback_impl(AST_Node_Ptr n) { } - private: std::unordered_map< @@ -77,8 +75,10 @@ namespace Sass { void operator()(Media_Block_Ptr); void operator()(Directive_Ptr); + // ignore missed types template - void fallback(U x) { return fallback_impl(x); } + void fallback(U x) {} + }; } diff --git a/src/inspect.cpp b/src/inspect.cpp index 273ff8fb1..c82ae0757 100644 --- a/src/inspect.cpp +++ b/src/inspect.cpp @@ -1131,8 +1131,4 @@ namespace Sass { } - void Inspect::fallback_impl(AST_Node_Ptr n) - { - } - } diff --git a/src/inspect.hpp b/src/inspect.hpp index c36790b80..8f5e8af76 100644 --- a/src/inspect.hpp +++ b/src/inspect.hpp @@ -13,8 +13,6 @@ namespace Sass { // import all the class-specific methods and override as desired using Operation_CRTP::operator(); - void fallback_impl(AST_Node_Ptr n); - public: Inspect(const Emitter& emi); @@ -95,8 +93,6 @@ namespace Sass { virtual std::string lbracket(List_Ptr); virtual std::string rbracket(List_Ptr); - // template - // void fallback(U x) { fallback_impl(reinterpret_cast(x)); } }; } diff --git a/src/listize.cpp b/src/listize.cpp index cb921ae67..a18724e45 100644 --- a/src/listize.cpp +++ b/src/listize.cpp @@ -78,9 +78,4 @@ namespace Sass { return l.detach(); } - Expression_Ptr Listize::fallback_impl(AST_Node_Ptr n) - { - return Cast(n); - } - } diff --git a/src/listize.hpp b/src/listize.hpp index 9716ebefc..8fa148816 100644 --- a/src/listize.hpp +++ b/src/listize.hpp @@ -15,8 +15,6 @@ namespace Sass { class Listize : public Operation_CRTP { - Expression_Ptr fallback_impl(AST_Node_Ptr n); - public: Listize(); ~Listize() { } @@ -25,8 +23,10 @@ namespace Sass { Expression_Ptr operator()(Complex_Selector_Ptr); Expression_Ptr operator()(Compound_Selector_Ptr); + // generic fallback template - Expression_Ptr fallback(U x) { return fallback_impl(x); } + Expression_Ptr fallback(U x) + { return Cast(x); } }; } diff --git a/src/operation.hpp b/src/operation.hpp index 2d4fbec9d..02e604ac6 100644 --- a/src/operation.hpp +++ b/src/operation.hpp @@ -1,15 +1,33 @@ #ifndef SASS_OPERATION_H #define SASS_OPERATION_H +// base classes to implement curiously recurring template pattern (CRTP) +// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern + #include "ast_fwd_decl.hpp" +#include "ast_def_macros.hpp" namespace Sass { + // you must add operators to every class + // ensures `this` of actual instance type + // we therefore call the specific operator + // they are virtual so most specific is used + #define ATTACH_CRTP_PERFORM_METHODS()\ + virtual void perform(Operation* op) { return (*op)(this); } \ + virtual Value_Ptr perform(Operation* op) { return (*op)(this); } \ + virtual std::string perform(Operation* op) { return (*op)(this); } \ + virtual AST_Node_Ptr perform(Operation* op) { return (*op)(this); } \ + virtual Selector_Ptr perform(Operation* op) { return (*op)(this); } \ + virtual Statement_Ptr perform(Operation* op) { return (*op)(this); } \ + virtual Expression_Ptr perform(Operation* op) { return (*op)(this); } \ + virtual union Sass_Value* perform(Operation* op) { return (*op)(this); } \ + virtual Supports_Condition_Ptr perform(Operation* op) { return (*op)(this); } \ + template class Operation { public: virtual T operator()(AST_Node_Ptr x) = 0; - virtual ~Operation() { } // statements virtual T operator()(Block_Ptr x) = 0; virtual T operator()(Ruleset_Ptr x) = 0; @@ -38,6 +56,7 @@ namespace Sass { virtual T operator()(Definition_Ptr x) = 0; virtual T operator()(Mixin_Call_Ptr x) = 0; // expressions + virtual T operator()(Null_Ptr x) = 0; virtual T operator()(List_Ptr x) = 0; virtual T operator()(Map_Ptr x) = 0; virtual T operator()(Function_Ptr x) = 0; @@ -62,7 +81,6 @@ namespace Sass { virtual T operator()(Media_Query_Ptr x) = 0; virtual T operator()(Media_Query_Expression_Ptr x) = 0; virtual T operator()(At_Root_Query_Ptr x) = 0; - virtual T operator()(Null_Ptr x) = 0; virtual T operator()(Parent_Selector_Ptr x) = 0; // parameters and arguments virtual T operator()(Parameter_Ptr x) = 0; @@ -81,15 +99,14 @@ namespace Sass { virtual T operator()(Compound_Selector_Ptr x)= 0; virtual T operator()(Complex_Selector_Ptr x) = 0; virtual T operator()(Selector_List_Ptr x) = 0; - - template - T fallback(U x) { return T(); } }; + // example: Operation_CRTP + // T is the base return type of all visitors + // D is the class derived visitor class + // normaly you want to implement all operators template class Operation_CRTP : public Operation { - public: - D& impl() { return static_cast(*this); } public: T operator()(AST_Node_Ptr x) { return static_cast(this)->fallback(x); } // statements @@ -120,6 +137,7 @@ namespace Sass { T operator()(Definition_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Mixin_Call_Ptr x) { return static_cast(this)->fallback(x); } // expressions + T operator()(Null_Ptr x) { return static_cast(this)->fallback(x); } T operator()(List_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Map_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Function_Ptr x) { return static_cast(this)->fallback(x); } @@ -144,7 +162,6 @@ namespace Sass { T operator()(Media_Query_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Media_Query_Expression_Ptr x) { return static_cast(this)->fallback(x); } T operator()(At_Root_Query_Ptr x) { return static_cast(this)->fallback(x); } - T operator()(Null_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Parent_Selector_Ptr x) { return static_cast(this)->fallback(x); } // parameters and arguments T operator()(Parameter_Ptr x) { return static_cast(this)->fallback(x); } @@ -164,8 +181,15 @@ namespace Sass { T operator()(Complex_Selector_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Selector_List_Ptr x) { return static_cast(this)->fallback(x); } - template - T fallback(U x) { return T(); } + // fallback with specific type U + // will be called if not overloaded + template T fallback(U x) + { + std::string msg(typeid(*this).name()); + msg += ": CRTP not implemented for "; + throw std::runtime_error(msg + typeid(*x).name()); + } + }; } diff --git a/src/remove_placeholders.hpp b/src/remove_placeholders.hpp index c13b63134..690b0f3eb 100644 --- a/src/remove_placeholders.hpp +++ b/src/remove_placeholders.hpp @@ -11,8 +11,6 @@ namespace Sass { class Remove_Placeholders : public Operation_CRTP { - void fallback_impl(AST_Node_Ptr n) {} - public: Selector_List_Ptr remove_placeholders(Selector_List_Ptr); @@ -26,8 +24,9 @@ namespace Sass { void operator()(Supports_Block_Ptr); void operator()(Directive_Ptr); + // ignore missed types template - void fallback(U x) { return fallback_impl(x); } + void fallback(U x) {} }; } diff --git a/src/to_value.cpp b/src/to_value.cpp index 3912c5510..f94c09a69 100644 --- a/src/to_value.cpp +++ b/src/to_value.cpp @@ -4,13 +4,6 @@ namespace Sass { - Value_Ptr To_Value::fallback_impl(AST_Node_Ptr n) - { - // throw a runtime error if this happens - // we want a well defined set of possible nodes - throw std::runtime_error("invalid node for to_value"); - } - // Custom_Error is a valid value Value_Ptr To_Value::operator()(Custom_Error_Ptr e) { diff --git a/src/to_value.hpp b/src/to_value.hpp index 8f64128c4..ba422b3d4 100644 --- a/src/to_value.hpp +++ b/src/to_value.hpp @@ -9,8 +9,6 @@ namespace Sass { class To_Value : public Operation_CRTP { - Value_Ptr fallback_impl(AST_Node_Ptr n); - private: Context& ctx; @@ -40,9 +38,6 @@ namespace Sass { Value_Ptr operator()(Selector_List_Ptr); Value_Ptr operator()(Binary_Expression_Ptr); - // fallback throws error - template - Value_Ptr fallback(U x) { return fallback_impl(x); } }; }