Skip to content

Commit

Permalink
Add distinct Parent_Reference class for values
Browse files Browse the repository at this point in the history
  • Loading branch information
mgreter committed Mar 17, 2018
1 parent 4c34d16 commit bbfcf49
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/ast.cpp
Expand Up @@ -1590,8 +1590,8 @@ namespace Sass {
bool Selector_Schema::has_real_parent_ref() const
{
if (String_Schema_Obj schema = Cast<String_Schema>(contents())) {
Parent_Selector_Obj p = Cast<Parent_Selector>(schema->at(0));
return schema->length() > 0 && p && p->is_real_parent_ref();
if (schema->length() == 0) return false;
return Cast<Parent_Reference>(schema->at(0));
}
return false;
}
Expand Down Expand Up @@ -2188,6 +2188,7 @@ namespace Sass {
IMPLEMENT_AST_OPERATORS(Color);
IMPLEMENT_AST_OPERATORS(Null);
IMPLEMENT_AST_OPERATORS(Parent_Selector);
IMPLEMENT_AST_OPERATORS(Parent_Reference);
IMPLEMENT_AST_OPERATORS(Import);
IMPLEMENT_AST_OPERATORS(Import_Stub);
IMPLEMENT_AST_OPERATORS(Function_Call);
Expand Down
18 changes: 18 additions & 0 deletions src/ast.hpp
Expand Up @@ -2403,6 +2403,24 @@ namespace Sass {
ATTACH_CRTP_PERFORM_METHODS()
};

//////////////////////////////////
// The Parent Reference Expression.
//////////////////////////////////
class Parent_Reference : public Value {
public:
Parent_Reference(ParserState pstate)
: Value(pstate) {}
Parent_Reference(const Parent_Reference* ptr)
: Value(ptr) {}
std::string type() const { return "parent"; }
static std::string type_name() { return "parent"; }
virtual bool operator==(const Expression& rhs) const {
return true; // can they ever be not equal?
};
ATTACH_AST_OPERATIONS(Parent_Reference)
ATTACH_CRTP_PERFORM_METHODS()
};

/////////////////////////////////////////////////////////////////////////
// Placeholder selectors (e.g., "%foo") for use in extend-only selectors.
/////////////////////////////////////////////////////////////////////////
Expand Down
5 changes: 5 additions & 0 deletions src/ast_fwd_decl.hpp
Expand Up @@ -30,6 +30,10 @@ namespace Sass {
typedef Simple_Selector* Simple_Selector_Ptr;
typedef Simple_Selector const* Simple_Selector_Ptr_Const;

class Parent_Reference;
typedef Parent_Reference* Parent_Reference_Ptr;
typedef Parent_Reference const* Parent_Reference_Ptr_Const;

class PreValue;
typedef PreValue* PreValue_Ptr;
typedef PreValue const* PreValue_Ptr_Const;
Expand Down Expand Up @@ -336,6 +340,7 @@ namespace Sass {
IMPL_MEM_OBJ(At_Root_Query);
IMPL_MEM_OBJ(Null);
IMPL_MEM_OBJ(Parent_Selector);
IMPL_MEM_OBJ(Parent_Reference);
IMPL_MEM_OBJ(Parameter);
IMPL_MEM_OBJ(Parameters);
IMPL_MEM_OBJ(Argument);
Expand Down
9 changes: 9 additions & 0 deletions src/debugger.hpp
Expand Up @@ -111,6 +111,15 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
// Expression_Ptr expression = Cast<Expression>(node);
// std::cerr << ind << "Expression " << expression << " " << expression->concrete_type() << std::endl;

} else if (Cast<Parent_Reference>(node)) {
Parent_Reference_Ptr selector = Cast<Parent_Reference>(node);
std::cerr << ind << "Parent_Reference " << selector;
// if (selector->not_selector()) cerr << " [in_declaration]";
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " <" << selector->hash() << ">";
std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
// debug_ast(selector->selector(), ind + "->", env);

} else if (Cast<Parent_Selector>(node)) {
Parent_Selector_Ptr selector = Cast<Parent_Selector>(node);
std::cerr << ind << "Parent_Selector " << selector;
Expand Down
17 changes: 17 additions & 0 deletions src/eval.cpp
Expand Up @@ -1173,6 +1173,11 @@ namespace Sass {
// XXX: this is never hit via spec tests
ex = ex->perform(this);
}
// parent selector needs another go
if (Cast<Parent_Reference>(ex)) {
// XXX: this is never hit via spec tests
ex = ex->perform(this);
}

if (List_Ptr l = Cast<List>(ex)) {
List_Obj ll = SASS_MEMORY_NEW(List, l->pstate(), 0, l->separator());
Expand Down Expand Up @@ -1575,6 +1580,18 @@ namespace Sass {
}
}

Expression_Ptr Eval::operator()(Parent_Reference_Ptr p)
{
if (Selector_List_Obj pr = selector()) {
exp.selector_stack.pop_back();
Selector_List_Obj rv = operator()(pr);
exp.selector_stack.push_back(rv);
return rv.detach();
} else {
return SASS_MEMORY_NEW(Null, p->pstate());
}
}

Simple_Selector_Ptr Eval::operator()(Simple_Selector_Ptr s)
{
return s;
Expand Down
1 change: 1 addition & 0 deletions src/eval.hpp
Expand Up @@ -86,6 +86,7 @@ namespace Sass {
// actual evaluated selectors
Selector_List_Ptr operator()(Selector_Schema_Ptr);
Expression_Ptr operator()(Parent_Selector_Ptr);
Expression_Ptr operator()(Parent_Reference_Ptr);

// generic fallback
template <typename U>
Expand Down
2 changes: 2 additions & 0 deletions src/operation.hpp
Expand Up @@ -81,6 +81,7 @@ namespace Sass {
virtual T operator()(Media_Query_Expression_Ptr x) = 0;
virtual T operator()(At_Root_Query_Ptr x) = 0;
virtual T operator()(Parent_Selector_Ptr x) = 0;
virtual T operator()(Parent_Reference_Ptr x) = 0;
// parameters and arguments
virtual T operator()(Parameter_Ptr x) = 0;
virtual T operator()(Parameters_Ptr x) = 0;
Expand Down Expand Up @@ -161,6 +162,7 @@ namespace Sass {
T operator()(Media_Query_Expression_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(At_Root_Query_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Parent_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Parent_Reference_Ptr x) { return static_cast<D*>(this)->fallback(x); }
// parameters and arguments
T operator()(Parameter_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Parameters_Ptr x) { return static_cast<D*>(this)->fallback(x); }
Expand Down
2 changes: 1 addition & 1 deletion src/parser.cpp
Expand Up @@ -1637,7 +1637,7 @@ namespace Sass {
if (match< ampersand >()) {
warning("In Sass, \"&&\" means two copies of the parent selector. You probably want to use \"and\" instead.", pstate);
}
return SASS_MEMORY_NEW(Parent_Selector, pstate); }
return SASS_MEMORY_NEW(Parent_Reference, pstate); }

if (lex< kwd_important >())
{ return SASS_MEMORY_NEW(String_Constant, pstate, "!important"); }
Expand Down

0 comments on commit bbfcf49

Please sign in to comment.