Skip to content

Commit eadae5b

Browse files
committed
Merge pull request #1431 from xzyfer/fix/better-selector-errors
Better mirror Ruby Sass errors for null params to selector functions
2 parents 4aa12e9 + 68cd236 commit eadae5b

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

src/functions.cpp

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ namespace Sass {
7171
false, true);
7272
}
7373

74+
std::string function_name(Signature sig)
75+
{
76+
std::string str(sig);
77+
return str.substr(0, str.find('('));
78+
}
79+
7480
namespace Functions {
7581

7682
inline void handle_utf8_error (const ParserState& pstate, Backtrace* backtrace)
@@ -147,6 +153,12 @@ namespace Sass {
147153
Selector_List* get_arg_sel(const string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
148154
To_String to_string(&ctx, false);
149155
Expression* exp = ARG(argname, Expression);
156+
if (exp->concrete_type() == Expression::NULL_VAL) {
157+
stringstream msg;
158+
msg << argname << ": null is not a valid selector: it must be a string,\n";
159+
msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
160+
error(msg.str(), pstate);
161+
}
150162
string exp_src = exp->perform(&to_string) + "{";
151163
return Parser::parse_selector(exp_src.c_str(), ctx);
152164
}
@@ -155,6 +167,12 @@ namespace Sass {
155167
Complex_Selector* get_arg_sel(const string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
156168
To_String to_string(&ctx, false);
157169
Expression* exp = ARG(argname, Expression);
170+
if (exp->concrete_type() == Expression::NULL_VAL) {
171+
stringstream msg;
172+
msg << argname << ": null is not a valid selector: it must be a string,\n";
173+
msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
174+
error(msg.str(), pstate);
175+
}
158176
string exp_src = exp->perform(&to_string) + "{";
159177
Selector_List* sel_list = Parser::parse_selector(exp_src.c_str(), ctx);
160178
return (sel_list->length() > 0) ? sel_list->first() : 0;
@@ -164,6 +182,12 @@ namespace Sass {
164182
Compound_Selector* get_arg_sel(const string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
165183
To_String to_string(&ctx, false);
166184
Expression* exp = ARG(argname, Expression);
185+
if (exp->concrete_type() == Expression::NULL_VAL) {
186+
stringstream msg;
187+
msg << argname << ": null is not a valid selector: it must be a string,\n";
188+
msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
189+
error(msg.str(), pstate);
190+
}
167191
string exp_src = exp->perform(&to_string) + "{";
168192
Selector_List* sel_list = Parser::parse_selector(exp_src.c_str(), ctx);
169193
return (sel_list->length() > 0) ? sel_list->first()->tail()->head() : 0;
@@ -1601,6 +1625,12 @@ namespace Sass {
16011625
vector<Selector_List*> parsedSelectors;
16021626
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
16031627
Expression* exp = dynamic_cast<Expression*>(arglist->value_at_index(i));
1628+
if (exp->concrete_type() == Expression::NULL_VAL) {
1629+
stringstream msg;
1630+
msg << "$selectors: null is not a valid selector: it must be a string,\n";
1631+
msg << "a list of strings, or a list of lists of strings for 'selector-nest'";
1632+
error(msg.str(), pstate);
1633+
}
16041634
string exp_src = exp->perform(&to_string) + "{";
16051635
Selector_List* sel = Parser::parse_selector(exp_src.c_str(), ctx);
16061636
parsedSelectors.push_back(sel);
@@ -1655,6 +1685,12 @@ namespace Sass {
16551685
vector<Selector_List*> parsedSelectors;
16561686
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
16571687
Expression* exp = dynamic_cast<Expression*>(arglist->value_at_index(i));
1688+
if (exp->concrete_type() == Expression::NULL_VAL) {
1689+
stringstream msg;
1690+
msg << "$selectors: null is not a valid selector: it must be a string,\n";
1691+
msg << "a list of strings, or a list of lists of strings for 'selector-append'";
1692+
error(msg.str(), pstate);
1693+
}
16581694
string exp_src = exp->perform(&to_string) + "{";
16591695
Selector_List* sel = Parser::parse_selector(exp_src.c_str(), ctx);
16601696
parsedSelectors.push_back(sel);
@@ -1759,8 +1795,6 @@ namespace Sass {
17591795
Signature selector_extend_sig = "selector-extend($selector, $extendee, $extender)";
17601796
BUILT_IN(selector_extend)
17611797
{
1762-
To_String to_string;
1763-
17641798
Selector_List* selector = ARGSEL("$selector", Selector_List, p_contextualize);
17651799
Selector_List* extendee = ARGSEL("$extendee", Selector_List, p_contextualize);
17661800
Selector_List* extender = ARGSEL("$extender", Selector_List, p_contextualize);
@@ -1795,10 +1829,7 @@ namespace Sass {
17951829
Signature selector_parse_sig = "selector-parse($selector)";
17961830
BUILT_IN(selector_parse)
17971831
{
1798-
To_String to_string(&ctx, false);
1799-
Expression* exp = ARG("$selector", Expression);
1800-
string sel_src = exp->perform(&to_string) + "{";
1801-
Selector_List* sel = Parser::parse_selector(sel_src.c_str(), ctx);
1832+
Selector_List* sel = ARGSEL("$selector", Selector_List, p_contextualize);
18021833

18031834
Listize listize(ctx);
18041835
return sel->perform(&listize);

src/functions.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ namespace Sass {
2323
Definition* make_native_function(Signature, Native_Function, Context& ctx);
2424
Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx);
2525

26+
std::string function_name(Signature);
27+
2628
namespace Functions {
2729

2830
extern Signature rgb_sig;

0 commit comments

Comments
 (0)