Skip to content

Commit 0d7c6b0

Browse files
committed
Merge remote-tracking branch 'origin' into 3.4-stable
2 parents dba57b2 + 9eb7b33 commit 0d7c6b0

File tree

6 files changed

+90
-18
lines changed

6 files changed

+90
-18
lines changed

src/ast.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ namespace Sass {
379379
// solve the double dispatch problem by using RTTI information via dynamic cast
380380
if (const Pseudo_Selector* lhs = Cast<Pseudo_Selector>(this)) {return *lhs == rhs; }
381381
else if (const Wrapped_Selector* lhs = Cast<Wrapped_Selector>(this)) {return *lhs == rhs; }
382+
else if (const Element_Selector* lhs = Cast<Element_Selector>(this)) {return *lhs == rhs; }
382383
else if (const Attribute_Selector* lhs = Cast<Attribute_Selector>(this)) {return *lhs == rhs; }
383384
else if (name_ == rhs.name_)
384385
{ return is_ns_eq(rhs); }
@@ -390,6 +391,7 @@ namespace Sass {
390391
// solve the double dispatch problem by using RTTI information via dynamic cast
391392
if (const Pseudo_Selector* lhs = Cast<Pseudo_Selector>(this)) {return *lhs < rhs; }
392393
else if (const Wrapped_Selector* lhs = Cast<Wrapped_Selector>(this)) {return *lhs < rhs; }
394+
else if (const Element_Selector* lhs = Cast<Element_Selector>(this)) {return *lhs < rhs; }
393395
else if (const Attribute_Selector* lhs = Cast<Attribute_Selector>(this)) {return *lhs < rhs; }
394396
if (is_ns_eq(rhs))
395397
{ return name_ < rhs.name_; }
@@ -661,12 +663,48 @@ namespace Sass {
661663
{
662664
if (Attribute_Selector_Ptr_Const w = Cast<Attribute_Selector>(&rhs))
663665
{
664-
return *this == *w;
666+
return is_ns_eq(rhs) &&
667+
name() == rhs.name() &&
668+
*this == *w;
669+
}
670+
return false;
671+
}
672+
673+
bool Element_Selector::operator< (const Element_Selector& rhs) const
674+
{
675+
if (is_ns_eq(rhs))
676+
{ return name() < rhs.name(); }
677+
return ns() < rhs.ns();
678+
}
679+
680+
bool Element_Selector::operator< (const Simple_Selector& rhs) const
681+
{
682+
if (Element_Selector_Ptr_Const w = Cast<Element_Selector>(&rhs))
683+
{
684+
return *this < *w;
665685
}
686+
if (is_ns_eq(rhs))
687+
{ return name() < rhs.name(); }
688+
return ns() < rhs.ns();
689+
}
690+
691+
bool Element_Selector::operator== (const Element_Selector& rhs) const
692+
{
666693
return is_ns_eq(rhs) &&
667694
name() == rhs.name();
668695
}
669696

697+
bool Element_Selector::operator== (const Simple_Selector& rhs) const
698+
{
699+
if (Element_Selector_Ptr_Const w = Cast<Element_Selector>(&rhs))
700+
{
701+
return is_ns_eq(rhs) &&
702+
name() == rhs.name() &&
703+
*this == *w;
704+
}
705+
return false;
706+
}
707+
670708
bool Pseudo_Selector::operator== (const Pseudo_Selector& rhs) const
671709
{
672710
if (is_ns_eq(rhs) && name() == rhs.name())

src/ast.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,6 +2473,10 @@ namespace Sass {
24732473
}
24742474
virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr);
24752475
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2476+
virtual bool operator==(const Simple_Selector& rhs) const;
2477+
virtual bool operator==(const Element_Selector& rhs) const;
2478+
virtual bool operator<(const Simple_Selector& rhs) const;
2479+
virtual bool operator<(const Element_Selector& rhs) const;
24762480
ATTACH_AST_OPERATIONS(Element_Selector)
24772481
ATTACH_OPERATIONS()
24782482
};

src/bind.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,17 @@ namespace Sass {
9595
env->local_frame()[p->name()] = arglist;
9696
Map_Obj argmap = Cast<Map>(a->value());
9797
for (auto key : argmap->keys()) {
98-
std::string param = unquote(Cast<String_Constant>(key)->value());
99-
arglist->append(SASS_MEMORY_NEW(Argument,
100-
key->pstate(),
101-
argmap->at(key),
102-
"$" + param,
103-
false,
104-
false));
98+
if (String_Constant_Obj str = Cast<String_Constant>(key)) {
99+
std::string param = unquote(str->value());
100+
arglist->append(SASS_MEMORY_NEW(Argument,
101+
key->pstate(),
102+
argmap->at(key),
103+
"$" + param,
104+
false,
105+
false));
106+
} else {
107+
throw Exception::InvalidVarKwdType(key->pstate(), key->inspect(), a);
108+
}
105109
}
106110

107111
} else {

src/error_handling.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ namespace Sass {
3131
msg += "\"";
3232
}
3333

34+
InvalidVarKwdType::InvalidVarKwdType(ParserState pstate, std::string name, const Argument_Ptr arg)
35+
: Base(pstate), name(name), arg(arg)
36+
{
37+
msg = "Variable keyword argument map must have string keys.\n";
38+
msg += name + " is not a string in " + arg->to_string() + ".";
39+
}
40+
3441
InvalidArgumentType::InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value_Ptr value)
3542
: Base(pstate), fn(fn), arg(arg), type(type), value(value)
3643
{

src/error_handling.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ namespace Sass {
6868
virtual ~InvalidArgumentType() throw() {};
6969
};
7070

71+
class InvalidVarKwdType : public Base {
72+
protected:
73+
std::string name;
74+
const Argument_Ptr arg;
75+
public:
76+
InvalidVarKwdType(ParserState pstate, std::string name, const Argument_Ptr arg = 0);
77+
virtual ~InvalidVarKwdType() throw() {};
78+
};
79+
7180
class InvalidSyntax : public Base {
7281
public:
7382
InvalidSyntax(ParserState pstate, std::string msg, std::vector<Sass_Import_Entry>* import_stack = 0);

src/parser.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -385,22 +385,27 @@ namespace Sass {
385385

386386
Parameters_Obj Parser::parse_parameters()
387387
{
388-
std::string name(lexed);
389-
Position position = after_token;
390388
Parameters_Obj params = SASS_MEMORY_NEW(Parameters, pstate);
391389
if (lex_css< exactly<'('> >()) {
392390
// if there's anything there at all
393391
if (!peek_css< exactly<')'> >()) {
394-
do params->append(parse_parameter());
395-
while (lex_css< exactly<','> >());
392+
do {
393+
if (peek< exactly<')'> >()) break;
394+
params->append(parse_parameter());
395+
} while (lex_css< exactly<','> >());
396+
}
397+
if (!lex_css< exactly<')'> >()) {
398+
css_error("Invalid CSS", " after ", ": expected \")\", was ");
396399
}
397-
if (!lex_css< exactly<')'> >()) error("expected a variable name (e.g. $x) or ')' for the parameter list for " + name, position);
398400
}
399401
return params;
400402
}
401403

402404
Parameter_Obj Parser::parse_parameter()
403405
{
406+
if (peek< alternatives< exactly<','>, exactly< '{' >, exactly<';'> > >()) {
407+
css_error("Invalid CSS", " after ", ": expected variable (e.g. $foo), was ");
408+
}
404409
while (lex< alternatives < spaces, block_comment > >());
405410
lex < variable >();
406411
std::string name(Util::normalize_underscores(lexed));
@@ -420,22 +425,27 @@ namespace Sass {
420425

421426
Arguments_Obj Parser::parse_arguments()
422427
{
423-
std::string name(lexed);
424-
Position position = after_token;
425428
Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
426429
if (lex_css< exactly<'('> >()) {
427430
// if there's anything there at all
428431
if (!peek_css< exactly<')'> >()) {
429-
do args->append(parse_argument());
430-
while (lex_css< exactly<','> >());
432+
do {
433+
if (peek< exactly<')'> >()) break;
434+
args->append(parse_argument());
435+
} while (lex_css< exactly<','> >());
436+
}
437+
if (!lex_css< exactly<')'> >()) {
438+
css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
431439
}
432-
if (!lex_css< exactly<')'> >()) error("expected a variable name (e.g. $x) or ')' for the parameter list for " + name, position);
433440
}
434441
return args;
435442
}
436443

437444
Argument_Obj Parser::parse_argument()
438445
{
446+
if (peek< alternatives< exactly<','>, exactly< '{' >, exactly<';'> > >()) {
447+
css_error("Invalid CSS", " after ", ": expected \")\", was ");
448+
}
439449
if (peek_css< sequence < exactly< hash_lbrace >, exactly< rbrace > > >()) {
440450
position += 2;
441451
css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");

0 commit comments

Comments
 (0)