Skip to content

Commit d675a84

Browse files
committed
Split Selector_Qualifier AST node into Class_Selector and Id_Selector
This better matches the Ruby Sass implementation.
1 parent 97e6200 commit d675a84

File tree

9 files changed

+81
-31
lines changed

9 files changed

+81
-31
lines changed

src/ast.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ namespace Sass {
469469
(*cpy)[0] = this->unify_with(ts, ctx);
470470
return cpy;
471471
}
472-
else if (dynamic_cast<Selector_Qualifier*>(rhs_0)) {
472+
else if (dynamic_cast<Class_Selector*>(rhs_0) || dynamic_cast<Id_Selector*>(rhs_0)) {
473473
// qualifier is `.class`, so we can prefix with `ns|*.class`
474474
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
475475
if (has_ns() && !rhs_0->has_ns()) {
@@ -501,17 +501,19 @@ namespace Sass {
501501
return cpy;
502502
}
503503

504-
SimpleSequence_Selector* Selector_Qualifier::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
504+
SimpleSequence_Selector* Class_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
505505
{
506-
if (name()[0] == '#')
506+
rhs->has_line_break(has_line_break());
507+
return Simple_Selector::unify_with(rhs, ctx);
508+
}
509+
510+
SimpleSequence_Selector* Id_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
511+
{
512+
for (size_t i = 0, L = rhs->length(); i < L; ++i)
507513
{
508-
for (size_t i = 0, L = rhs->length(); i < L; ++i)
509-
{
510-
Simple_Selector* rhs_i = (*rhs)[i];
511-
if (typeid(*rhs_i) == typeid(Selector_Qualifier) &&
512-
static_cast<Selector_Qualifier*>(rhs_i)->name()[0] == '#' &&
513-
static_cast<Selector_Qualifier*>(rhs_i)->name() != name())
514-
return 0;
514+
Simple_Selector* rhs_i = (*rhs)[i];
515+
if (typeid(*rhs_i) == typeid(Id_Selector) && static_cast<Id_Selector*>(rhs_i)->name() != name()) {
516+
return 0;
515517
}
516518
}
517519
rhs->has_line_break(has_line_break());
@@ -1037,8 +1039,13 @@ namespace Sass {
10371039
SimpleSequence_Selector* rh = last()->head();
10381040
size_t i = 0, L = h->length();
10391041
if (dynamic_cast<Element_Selector*>(h->first())) {
1040-
if (Selector_Qualifier* sq = dynamic_cast<Selector_Qualifier*>(rh->last())) {
1041-
Selector_Qualifier* sqs = new Selector_Qualifier(*sq);
1042+
if (Class_Selector* sq = dynamic_cast<Class_Selector*>(rh->last())) {
1043+
Class_Selector* sqs = new Class_Selector(*sq);
1044+
sqs->name(sqs->name() + (*h)[0]->name());
1045+
(*rh)[rh->length()-1] = sqs;
1046+
for (i = 1; i < L; ++i) *rh << (*h)[i];
1047+
} else if (Id_Selector* sq = dynamic_cast<Id_Selector*>(rh->last())) {
1048+
Id_Selector* sqs = new Id_Selector(*sq);
10421049
sqs->name(sqs->name() + (*h)[0]->name());
10431050
(*rh)[rh->length()-1] = sqs;
10441051
for (i = 1; i < L; ++i) *rh << (*h)[i];

src/ast.hpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,23 +2066,40 @@ namespace Sass {
20662066
};
20672067

20682068
////////////////////////////////////////////////
2069-
// Selector qualifiers -- i.e., classes and ids.
2069+
// Class selectors -- i.e., .foo.
20702070
////////////////////////////////////////////////
2071-
class Selector_Qualifier : public Simple_Selector {
2071+
class Class_Selector : public Simple_Selector {
20722072
public:
2073-
Selector_Qualifier(ParserState pstate, std::string n)
2073+
Class_Selector(ParserState pstate, std::string n)
20742074
: Simple_Selector(pstate, n)
20752075
{ }
20762076
virtual bool unique() const
20772077
{
2078-
if (name()[0] == '#') return true;
2079-
else return false;
2078+
return false;
2079+
}
2080+
virtual unsigned long specificity()
2081+
{
2082+
return Constants::Specificity_Class;
2083+
}
2084+
virtual SimpleSequence_Selector* unify_with(SimpleSequence_Selector*, Context&);
2085+
ATTACH_OPERATIONS()
2086+
};
2087+
2088+
////////////////////////////////////////////////
2089+
// ID selectors -- i.e., #foo.
2090+
////////////////////////////////////////////////
2091+
class Id_Selector : public Simple_Selector {
2092+
public:
2093+
Id_Selector(ParserState pstate, std::string n)
2094+
: Simple_Selector(pstate, n)
2095+
{ }
2096+
virtual bool unique() const
2097+
{
2098+
return true;
20802099
}
20812100
virtual unsigned long specificity()
20822101
{
2083-
if (name()[0] == '#') return Constants::Specificity_ID;
2084-
if (name()[0] == '.') return Constants::Specificity_Class;
2085-
else return Constants::Specificity_Element;
2102+
return Constants::Specificity_ID;
20862103
}
20872104
virtual SimpleSequence_Selector* unify_with(SimpleSequence_Selector*, Context&);
20882105
ATTACH_OPERATIONS()

src/ast_fwd_decl.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ namespace Sass {
7575
class Selector_Schema;
7676
class Placeholder_Selector;
7777
class Element_Selector;
78-
class Selector_Qualifier;
78+
class Class_Selector;
79+
class Id_Selector;
7980
class Attribute_Selector;
8081
class Pseudo_Selector;
8182
class Wrapped_Selector;

src/debugger.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,20 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
188188
std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
189189
std::cerr << std::endl;
190190
debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env);
191-
} else if (dynamic_cast<Selector_Qualifier*>(node)) {
192-
Selector_Qualifier* selector = dynamic_cast<Selector_Qualifier*>(node);
193-
std::cerr << ind << "Selector_Qualifier " << selector;
191+
} else if (dynamic_cast<Class_Selector*>(node)) {
192+
Class_Selector* selector = dynamic_cast<Class_Selector*>(node);
193+
std::cerr << ind << "Class_Selector " << selector;
194+
std::cerr << " (" << pstate_source_position(node) << ")";
195+
std::cerr << " <" << selector->hash() << ">";
196+
std::cerr << " <<" << selector->ns_name() << ">>";
197+
std::cerr << (selector->is_optional() ? " [is_optional]": " -");
198+
std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
199+
std::cerr << (selector->has_line_break() ? " [line-break]": " -");
200+
std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
201+
std::cerr << std::endl;
202+
} else if (dynamic_cast<Id_Selector*>(node)) {
203+
Id_Selector* selector = dynamic_cast<Id_Selector*>(node);
204+
std::cerr << ind << "Id_Selector " << selector;
194205
std::cerr << " (" << pstate_source_position(node) << ")";
195206
std::cerr << " <" << selector->hash() << ">";
196207
std::cerr << " <<" << selector->ns_name() << ">>";

src/eval.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ namespace Sass {
7777
Element_Selector* operator()(Element_Selector* s) { return s; };
7878
Pseudo_Selector* operator()(Pseudo_Selector* s) { return s; };
7979
Wrapped_Selector* operator()(Wrapped_Selector* s) { return s; };
80-
Selector_Qualifier* operator()(Selector_Qualifier* s) { return s; };
80+
Class_Selector* operator()(Class_Selector* s) { return s; };
81+
Id_Selector* operator()(Id_Selector* s) { return s; };
8182
Placeholder_Selector* operator()(Placeholder_Selector* s) { return s; };
8283
// actual evaluated selectors
8384
CommaSequence_Selector* operator()(Selector_Schema*);

src/inspect.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,14 @@ namespace Sass {
892892
append_token(s->ns_name(), s);
893893
}
894894

895-
void Inspect::operator()(Selector_Qualifier* s)
895+
void Inspect::operator()(Class_Selector* s)
896+
{
897+
append_token(s->ns_name(), s);
898+
if (s->has_line_break()) append_optional_linefeed();
899+
if (s->has_line_break()) append_indentation();
900+
}
901+
902+
void Inspect::operator()(Id_Selector* s)
896903
{
897904
append_token(s->ns_name(), s);
898905
if (s->has_line_break()) append_optional_linefeed();

src/inspect.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ namespace Sass {
8383
virtual void operator()(Selector_Schema*);
8484
virtual void operator()(Placeholder_Selector*);
8585
virtual void operator()(Element_Selector*);
86-
virtual void operator()(Selector_Qualifier*);
86+
virtual void operator()(Class_Selector*);
87+
virtual void operator()(Id_Selector*);
8788
virtual void operator()(Attribute_Selector*);
8889
virtual void operator()(Pseudo_Selector*);
8990
virtual void operator()(Wrapped_Selector*);

src/operation.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ namespace Sass {
7373
virtual T operator()(Selector_Schema* x) = 0;
7474
virtual T operator()(Placeholder_Selector* x) = 0;
7575
virtual T operator()(Element_Selector* x) = 0;
76-
virtual T operator()(Selector_Qualifier* x) = 0;
76+
virtual T operator()(Class_Selector* x) = 0;
77+
virtual T operator()(Id_Selector* x) = 0;
7778
virtual T operator()(Attribute_Selector* x) = 0;
7879
virtual T operator()(Pseudo_Selector* x) = 0;
7980
virtual T operator()(Wrapped_Selector* x) = 0;
@@ -154,7 +155,8 @@ namespace Sass {
154155
T operator()(Selector_Schema* x) { return static_cast<D*>(this)->fallback(x); }
155156
T operator()(Placeholder_Selector* x) { return static_cast<D*>(this)->fallback(x); }
156157
T operator()(Element_Selector* x) { return static_cast<D*>(this)->fallback(x); }
157-
T operator()(Selector_Qualifier* x) { return static_cast<D*>(this)->fallback(x); }
158+
T operator()(Class_Selector* x) { return static_cast<D*>(this)->fallback(x); }
159+
T operator()(Id_Selector* x) { return static_cast<D*>(this)->fallback(x); }
158160
T operator()(Attribute_Selector* x) { return static_cast<D*>(this)->fallback(x); }
159161
T operator()(Pseudo_Selector* x) { return static_cast<D*>(this)->fallback(x); }
160162
T operator()(Wrapped_Selector* x) { return static_cast<D*>(this)->fallback(x); }

src/parser.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,8 +799,11 @@ namespace Sass {
799799
Simple_Selector* Parser::parse_simple_selector()
800800
{
801801
lex < css_comments >(false);
802-
if (lex< alternatives < id_name, class_name > >()) {
803-
return SASS_MEMORY_NEW(ctx.mem, Selector_Qualifier, pstate, lexed);
802+
if (lex< class_name >()) {
803+
return SASS_MEMORY_NEW(ctx.mem, Class_Selector, pstate, lexed);
804+
}
805+
else if (lex< id_name >()) {
806+
return SASS_MEMORY_NEW(ctx.mem, Id_Selector, pstate, lexed);
804807
}
805808
else if (lex< quoted_string >()) {
806809
return SASS_MEMORY_NEW(ctx.mem, Element_Selector, pstate, unquote(lexed));

0 commit comments

Comments
 (0)