Skip to content

Commit

Permalink
Implement initial parts for reference combinators
Browse files Browse the repository at this point in the history
  • Loading branch information
mgreter committed Jul 1, 2015
1 parent 86b8f36 commit 2f07ba3
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 5 deletions.
5 changes: 3 additions & 2 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2008,11 +2008,12 @@ namespace Sass {
////////////////////////////////////////////////////////////////////////////
class Complex_Selector : public Selector {
public:
enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO };
enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE };
private:
ADD_PROPERTY(Combinator, combinator)
ADD_PROPERTY(Compound_Selector*, head)
ADD_PROPERTY(Complex_Selector*, tail)
ADD_PROPERTY(String*, reference);
public:
bool contains_placeholder() {
if (head() && head()->contains_placeholder()) return true;
Expand All @@ -2023,7 +2024,7 @@ namespace Sass {
Combinator c = ANCESTOR_OF,
Compound_Selector* h = 0,
Complex_Selector* t = 0)
: Selector(pstate), combinator_(c), head_(h), tail_(t)
: Selector(pstate), combinator_(c), head_(h), tail_(t), reference_(0)
{
if ((h && h->has_reference()) || (t && t->has_reference())) has_reference(true);
if ((h && h->has_placeholder()) || (t && t->has_placeholder())) has_placeholder(true);
Expand Down
2 changes: 2 additions & 0 deletions debugger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
case Complex_Selector::PRECEDES: del = "~"; break;
case Complex_Selector::ADJACENT_TO: del = "+"; break;
case Complex_Selector::ANCESTOR_OF: del = " "; break;
case Complex_Selector::REFERENCE: del = "//"; break;
}
// if (del = "/") del += selector->reference()->perform(&to_string) + "/";
cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
debug_ast(selector->head(), ind + " " /* + "[" + del + "]" */, env);
if (selector->tail()) {
Expand Down
4 changes: 4 additions & 0 deletions eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1397,8 +1397,10 @@ namespace Sass {
bool parentized = false;
Complex_Selector* tail = s->tail();
Compound_Selector* head = s->head();
String* reference = s->reference();
Complex_Selector::Combinator combinator = s->combinator();
Selector_List* sl = new (ctx.mem) Selector_List(s->pstate());
if (reference) reference = (String*) reference->perform(this);

if (head) {
// check if we have a parent selector reference (expands to list)
Expand All @@ -1420,6 +1422,7 @@ namespace Sass {
cp = new (ctx.mem) Complex_Selector(s->pstate());
cp->head(head); cp->tail(tt);
cp->combinator(combinator);
cp->reference(reference);
last->tail(cp);
} else {
last->tail(tt);
Expand All @@ -1435,6 +1438,7 @@ namespace Sass {
Complex_Selector* ns = (*pr)[n]->cloneFully(ctx);
Complex_Selector* last = ns->last();
ns->combinator(combinator);
ns->reference(reference);
for (size_t i = 1, iL = head->length(); i < iL; ++i) {
// add simple selectors
*last->head() << (*head)[i];
Expand Down
1 change: 1 addition & 0 deletions extend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ namespace Sass {
case Complex_Selector::PARENT_OF: os << "\">\""; break;
case Complex_Selector::PRECEDES: os << "\"~\""; break;
case Complex_Selector::ADJACENT_TO: os << "\"+\""; break;
case Complex_Selector::REFERENCE: os << "\"/\""; break;
}

return os;
Expand Down
7 changes: 7 additions & 0 deletions inspect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,13 @@ namespace Sass {
append_string("+");
append_optional_space();
break;
case Complex_Selector::REFERENCE:
append_mandatory_space();
append_string("/");
c->reference()->perform(this);
append_string("/");
append_mandatory_space();
break;
case Complex_Selector::PRECEDES:
if (is_empty) append_optional_space();
else append_mandatory_space();
Expand Down
6 changes: 6 additions & 0 deletions listize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ namespace Sass {
if (hh) *l << hh;
}

To_String to_string;
string reference = ! sel->reference() ? ""
: sel->reference()->perform(&to_string);
switch(sel->combinator())
{
case Complex_Selector::PARENT_OF:
Expand All @@ -53,6 +56,9 @@ namespace Sass {
case Complex_Selector::ADJACENT_TO:
*l << new (ctx.mem) String_Quoted(sel->pstate(), "+");
break;
case Complex_Selector::REFERENCE:
*l << new (ctx.mem) String_Quoted(sel->pstate(), "/" + reference + "/");
break;
case Complex_Selector::PRECEDES:
*l << new (ctx.mem) String_Quoted(sel->pstate(), "~");
break;
Expand Down
1 change: 1 addition & 0 deletions node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ namespace Sass {
case Complex_Selector::PARENT_OF: os << "\">\""; break;
case Complex_Selector::PRECEDES: os << "\"~\""; break;
case Complex_Selector::ADJACENT_TO: os << "\"+\""; break;
case Complex_Selector::REFERENCE: os << "\"/\""; break;
}

} else if (node.isNil()) {
Expand Down
20 changes: 17 additions & 3 deletions parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ namespace Sass {
// loop until end of string
while (position < end) {

// parse comment blocks
// we should be able to refactor this
parse_block_comments();
lex < css_whitespace >();

Expand Down Expand Up @@ -715,6 +715,7 @@ namespace Sass {
Complex_Selector* Parser::parse_complex_selector(bool in_root)
{

String* reference = 0;
lex < block_comment >();
// parse the left hand side
Compound_Selector* lhs = 0;
Expand All @@ -732,6 +733,13 @@ namespace Sass {
if (lex< exactly<'+'> >()) combinator = Complex_Selector::ADJACENT_TO;
else if (lex< exactly<'~'> >()) combinator = Complex_Selector::PRECEDES;
else if (lex< exactly<'>'> >()) combinator = Complex_Selector::PARENT_OF;
else if (lex< sequence < exactly<'/'>, negate < exactly < '*' > > > >()) {
// comments are allowed, but not spaces?
combinator = Complex_Selector::REFERENCE;
if (!lex < identifier >()) return 0; // ToDo: error msg?
reference = new (ctx.mem) String_Quoted(pstate, lexed);
if (!lex < exactly < '/' > >()) return 0; // ToDo: error msg?
}
else /* if (lex< zero >()) */ combinator = Complex_Selector::ANCESTOR_OF;

if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return 0;
Expand All @@ -740,6 +748,7 @@ namespace Sass {
// source position of a complex selector points to the combinator
// ToDo: make sure we update pstate for ancestor of (lex < zero >());
Complex_Selector* sel = new (ctx.mem) Complex_Selector(pstate, combinator, lhs);
if (combinator == Complex_Selector::REFERENCE) sel->reference(reference);
// has linfeed after combinator?
sel->has_line_break(peek_newline());
// sel->has_line_feed(has_line_feed);
Expand Down Expand Up @@ -937,7 +946,7 @@ namespace Sass {
ParserState p = pstate;
if (!lex_css< attribute_name >()) error("invalid attribute name in attribute selector", pstate);
string name(lexed);
if (lex_css< exactly<']'> >()) return new (ctx.mem) Attribute_Selector(p, name, "", 0);
if (lex_css< alternatives < exactly<']'>, exactly<'/'> > >()) return new (ctx.mem) Attribute_Selector(p, name, "", 0);
if (!lex_css< alternatives< exact_match, class_match, dash_match,
prefix_match, suffix_match, substring_match > >()) {
error("invalid operator in attribute selector for " + name, pstate);
Expand All @@ -955,7 +964,7 @@ namespace Sass {
error("expected a string constant or identifier in attribute selector for " + name, pstate);
}

if (!lex_css< exactly<']'> >()) error("unterminated attribute selector for " + name, pstate);
if (!lex_css< alternatives < exactly<']'>, exactly<'/'> > >()) error("unterminated attribute selector for " + name, pstate);
return new (ctx.mem) Attribute_Selector(p, name, matcher, value);
}

Expand Down Expand Up @@ -2133,6 +2142,11 @@ namespace Sass {
// match `/deep/` selector (pass-trough)
// there is no functionality for it yet
exactly<sel_deep_kwd>,
sequence <
exactly <'/'>,
identifier,
exactly <'/'>
>,
// match selector ops /[*&%,()\[\]]/
class_char < selector_lookahead_ops >,
// match selector combinators /[>+~]/
Expand Down

0 comments on commit 2f07ba3

Please sign in to comment.