Skip to content

Commit dfbbca0

Browse files
committed
Implement initial parts for reference combinators
1 parent 104da1d commit dfbbca0

File tree

10 files changed

+43
-12
lines changed

10 files changed

+43
-12
lines changed

ast.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,11 +1979,12 @@ namespace Sass {
19791979
////////////////////////////////////////////////////////////////////////////
19801980
class Complex_Selector : public Selector {
19811981
public:
1982-
enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO };
1982+
enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE };
19831983
private:
19841984
ADD_PROPERTY(Combinator, combinator)
19851985
ADD_PROPERTY(Compound_Selector*, head)
19861986
ADD_PROPERTY(Complex_Selector*, tail)
1987+
ADD_PROPERTY(String*, reference);
19871988
public:
19881989
bool contains_placeholder() {
19891990
if (head() && head()->contains_placeholder()) return true;
@@ -1994,7 +1995,7 @@ namespace Sass {
19941995
Combinator c = ANCESTOR_OF,
19951996
Compound_Selector* h = 0,
19961997
Complex_Selector* t = 0)
1997-
: Selector(pstate), combinator_(c), head_(h), tail_(t)
1998+
: Selector(pstate), combinator_(c), head_(h), tail_(t), reference_(0)
19981999
{
19992000
if ((h && h->has_reference()) || (t && t->has_reference())) has_reference(true);
20002001
if ((h && h->has_placeholder()) || (t && t->has_placeholder())) has_placeholder(true);

debugger.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
123123
case Complex_Selector::PRECEDES: del = "~"; break;
124124
case Complex_Selector::ADJACENT_TO: del = "+"; break;
125125
case Complex_Selector::ANCESTOR_OF: del = " "; break;
126+
case Complex_Selector::REFERENCE: del = "//"; break;
126127
}
128+
// if (del = "/") del += selector->reference()->perform(&to_string) + "/";
127129
cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
128130
debug_ast(selector->head(), ind + " " /* + "[" + del + "]" */, env);
129131
if (selector->tail()) {

eval.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,8 +1402,11 @@ namespace Sass {
14021402
bool parentized = false;
14031403
Complex_Selector* tail = s->tail();
14041404
Compound_Selector* head = s->head();
1405+
String* reference = s->reference();
14051406
Complex_Selector::Combinator combinator = s->combinator();
14061407
Selector_List* sl = new (ctx.mem) Selector_List(s->pstate());
1408+
if (reference) reference = (String*) reference->perform(this);
1409+
14071410
if (head) {
14081411
// check if we have a parent selector reference (expands to list)
14091412
if (head->length() > 1 && dynamic_cast<Parent_Selector*>((*head)[0])) {
@@ -1418,6 +1421,7 @@ namespace Sass {
14181421
for (size_t i = 1, L = head->length(); i < L; ++i) *lst_h << (*head)[i];
14191422
lst_t->tail(tail); // now connect old tail back to new intermediate
14201423
lst_t->combinator(combinator); // and dont forget the combinator
1424+
lst_t->reference(reference);
14211425
// if (s->has_line_feed()) lst_t->has_line_feed(true); // and dont forget the combinator
14221426
}
14231427
return ns;
@@ -1450,6 +1454,7 @@ namespace Sass {
14501454
lst->tail(ins);
14511455
} else {
14521456
lst->combinator(combinator);
1457+
lst->reference(reference);
14531458
}
14541459
}
14551460
if (s->has_line_feed()) (*ns)[n]->has_line_feed(true);

extend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ namespace Sass {
7676
case Complex_Selector::PARENT_OF: os << "\">\""; break;
7777
case Complex_Selector::PRECEDES: os << "\"~\""; break;
7878
case Complex_Selector::ADJACENT_TO: os << "\"+\""; break;
79+
case Complex_Selector::REFERENCE: os << "\"/\""; break;
7980
}
8081

8182
return os;

inspect.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,13 @@ namespace Sass {
925925
append_string("+");
926926
append_optional_space();
927927
break;
928+
case Complex_Selector::REFERENCE:
929+
append_mandatory_space();
930+
append_string("/");
931+
c->reference()->perform(this);
932+
append_string("/");
933+
append_mandatory_space();
934+
break;
928935
case Complex_Selector::PRECEDES:
929936
if (is_empty) append_optional_space();
930937
else append_mandatory_space();

listize.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ namespace Sass {
4545
if (hh) *l << hh;
4646
}
4747

48+
To_String to_string;
49+
string reference = ! sel->reference() ? ""
50+
: sel->reference()->perform(&to_string);
4851
switch(sel->combinator())
4952
{
5053
case Complex_Selector::PARENT_OF:
@@ -53,6 +56,9 @@ namespace Sass {
5356
case Complex_Selector::ADJACENT_TO:
5457
*l << new (ctx.mem) String_Quoted(sel->pstate(), "+");
5558
break;
59+
case Complex_Selector::REFERENCE:
60+
*l << new (ctx.mem) String_Quoted(sel->pstate(), "/" + reference + "/");
61+
break;
5662
case Complex_Selector::PRECEDES:
5763
*l << new (ctx.mem) String_Quoted(sel->pstate(), "~");
5864
break;

node.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ namespace Sass {
142142
case Complex_Selector::PARENT_OF: os << "\">\""; break;
143143
case Complex_Selector::PRECEDES: os << "\"~\""; break;
144144
case Complex_Selector::ADJACENT_TO: os << "\"+\""; break;
145+
case Complex_Selector::REFERENCE: os << "\"/\""; break;
145146
}
146147

147148
} else if (node.isNil()) {

parser.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ namespace Sass {
151151
// loop until end of string
152152
while (position < end) {
153153

154-
// parse comment blocks
154+
// we should be able to refactor this
155155
parse_block_comments();
156156
lex < css_whitespace >();
157157

@@ -717,6 +717,7 @@ namespace Sass {
717717
Complex_Selector* Parser::parse_complex_selector(bool in_root)
718718
{
719719

720+
String* reference = 0;
720721
lex < block_comment >();
721722
// parse the left hand side
722723
Compound_Selector* lhs = 0;
@@ -734,6 +735,13 @@ namespace Sass {
734735
if (lex< exactly<'+'> >()) combinator = Complex_Selector::ADJACENT_TO;
735736
else if (lex< exactly<'~'> >()) combinator = Complex_Selector::PRECEDES;
736737
else if (lex< exactly<'>'> >()) combinator = Complex_Selector::PARENT_OF;
738+
else if (lex< sequence < exactly<'/'>, negate < exactly < '*' > > > >()) {
739+
// comments are allowed, but not spaces?
740+
combinator = Complex_Selector::REFERENCE;
741+
if (!lex < identifier >()) return 0; // ToDo: error msg?
742+
reference = new (ctx.mem) String_Quoted(pstate, lexed);
743+
if (!lex < exactly < '/' > >()) return 0; // ToDo: error msg?
744+
}
737745
else /* if (lex< zero >()) */ combinator = Complex_Selector::ANCESTOR_OF;
738746

739747
if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return 0;
@@ -742,6 +750,7 @@ namespace Sass {
742750
// source position of a complex selector points to the combinator
743751
// ToDo: make sure we update pstate for ancestor of (lex < zero >());
744752
Complex_Selector* sel = new (ctx.mem) Complex_Selector(pstate, combinator, lhs);
753+
if (combinator == Complex_Selector::REFERENCE) sel->reference(reference);
745754
// has linfeed after combinator?
746755
sel->has_line_break(peek_newline());
747756
// sel->has_line_feed(has_line_feed);
@@ -841,7 +850,7 @@ namespace Sass {
841850
else if (lex< quoted_string >()) {
842851
return new (ctx.mem) Type_Selector(pstate, unquote(lexed));
843852
}
844-
else if (lex< alternatives < variable, number, kwd_sel_deep > >()) {
853+
else if (lex< alternatives < variable, number, re_reference_selector > >()) {
845854
return new (ctx.mem) Type_Selector(pstate, lexed);
846855
}
847856
else if (peek< pseudo_not >()) {
@@ -939,7 +948,7 @@ namespace Sass {
939948
ParserState p = pstate;
940949
if (!lex_css< attribute_name >()) error("invalid attribute name in attribute selector", pstate);
941950
string name(lexed);
942-
if (lex_css< exactly<']'> >()) return new (ctx.mem) Attribute_Selector(p, name, "", 0);
951+
if (lex_css< alternatives < exactly<']'>, exactly<'/'> > >()) return new (ctx.mem) Attribute_Selector(p, name, "", 0);
943952
if (!lex_css< alternatives< exact_match, class_match, dash_match,
944953
prefix_match, suffix_match, substring_match > >()) {
945954
error("invalid operator in attribute selector for " + name, pstate);
@@ -957,7 +966,7 @@ namespace Sass {
957966
error("expected a string constant or identifier in attribute selector for " + name, pstate);
958967
}
959968

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

@@ -2137,7 +2146,7 @@ namespace Sass {
21372146
spaces, block_comment, line_comment,
21382147
// match `/deep/` selector (pass-trough)
21392148
// there is no functionality for it yet
2140-
exactly<sel_deep_kwd>,
2149+
re_reference_selector,
21412150
// match selector ops /[*&%,()\[\]]/
21422151
class_char < selector_lookahead_ops >,
21432152
// match selector combinators /[>+~]/

prelexer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ namespace Sass {
214214
return sequence<exactly<'@'>, identifier>(src);
215215
}
216216

217-
const char* kwd_sel_deep(const char* src) {
218-
return word<sel_deep_kwd>(src);
217+
const char* re_reference_selector(const char* src) {
218+
return sequence < exactly <'/'>, identifier, exactly <'/'> >(src);
219219
}
220220

221221
const char* kwd_import(const char* src) {

prelexer.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,8 @@ namespace Sass {
196196
const char* identifier_alpha(const char* src);
197197
const char* identifier_alnum(const char* src);
198198
const char* identifier_alnums(const char* src);
199-
// Match selector names.
200-
// const char* sel_ident(const char* src);
201-
const char* kwd_sel_deep(const char* src);
199+
// Match reference selector.
200+
const char* re_reference_selector(const char* src);
202201

203202
// Match interpolant schemas
204203
const char* identifier_schema(const char* src);

0 commit comments

Comments
 (0)