Skip to content

Commit

Permalink
Merge pull request #1848 from mgreter/bugfix/import-errors
Browse files Browse the repository at this point in the history
Implement missing error checks
  • Loading branch information
mgreter committed Jan 11, 2016
2 parents c13dfc0 + 3695d75 commit a6386bd
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 39 deletions.
9 changes: 8 additions & 1 deletion src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,7 @@ namespace Sass {
Complex_Selector* Complex_Selector::clone(Context& ctx) const
{
Complex_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Complex_Selector, *this);
cpy->is_optional(this->is_optional());
cpy->media_block(this->media_block());
if (tail()) cpy->tail(tail()->clone(ctx));
return cpy;
Expand All @@ -1176,7 +1177,8 @@ namespace Sass {
Complex_Selector* Complex_Selector::cloneFully(Context& ctx) const
{
Complex_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Complex_Selector, *this);

cpy->is_optional(this->is_optional());
cpy->media_block(this->media_block());
if (head()) {
cpy->head(head()->clone(ctx));
}
Expand All @@ -1191,20 +1193,25 @@ namespace Sass {
Compound_Selector* Compound_Selector::clone(Context& ctx) const
{
Compound_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, *this);
cpy->is_optional(this->is_optional());
cpy->media_block(this->media_block());
cpy->extended(this->extended());
return cpy;
}

Selector_List* Selector_List::clone(Context& ctx) const
{
Selector_List* cpy = SASS_MEMORY_NEW(ctx.mem, Selector_List, *this);
cpy->is_optional(this->is_optional());
cpy->media_block(this->media_block());
return cpy;
}

Selector_List* Selector_List::cloneFully(Context& ctx) const
{
Selector_List* cpy = SASS_MEMORY_NEW(ctx.mem, Selector_List, pstate());
cpy->is_optional(this->is_optional());
cpy->media_block(this->media_block());
for (size_t i = 0, L = length(); i < L; ++i) {
*cpy << (*this)[i]->cloneFully(ctx);
}
Expand Down
2 changes: 2 additions & 0 deletions src/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2177,6 +2177,7 @@ namespace Sass {
class Compound_Selector : public Selector, public Vectorized<Simple_Selector*> {
private:
SourcesSet sources_;
ADD_PROPERTY(bool, extended);
ADD_PROPERTY(bool, has_parent_reference);
protected:
void adjust_after_pushing(Simple_Selector* s)
Expand All @@ -2188,6 +2189,7 @@ namespace Sass {
Compound_Selector(ParserState pstate, size_t s = 0)
: Selector(pstate),
Vectorized<Simple_Selector*>(s),
extended_(false),
has_parent_reference_(false)
{ }
bool contains_placeholder() {
Expand Down
5 changes: 1 addition & 4 deletions src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,7 @@ namespace Sass {
if (const char* proto = sequence< identifier, exactly<':'>, exactly<'/'>, exactly<'/'> >(imp_path.c_str())) {

protocol = std::string(imp_path.c_str(), proto - 3);
// std::cerr << "==================== " << protocol << "\n";
if (protocol.compare("file") && true) {

}
// if (protocol.compare("file") && true) { }
}

// add urls (protocol other than file) and urls without procotol to `urls` member
Expand Down
1 change: 1 addition & 0 deletions src/debugger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
std::cerr << " <" << selector->hash() << ">";
std::cerr << " [weight:" << longToHex(selector->specificity()) << "]";
std::cerr << " [@media:" << selector->media_block() << "]";
std::cerr << (selector->extended() ? " [extended]": " -");
std::cerr << (selector->is_optional() ? " [is_optional]": " -");
std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
std::cerr << (selector->has_line_break() ? " [line-break]": " -");
Expand Down
17 changes: 17 additions & 0 deletions src/expand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Sass {
eval(Eval(*this)),
env_stack(std::vector<Env*>()),
block_stack(std::vector<Block*>()),
call_stack(std::vector<AST_Node*>()),
property_stack(std::vector<String*>()),
selector_stack(std::vector<Selector_List*>()),
backtrace_stack(std::vector<Backtrace*>()),
Expand All @@ -28,6 +29,7 @@ namespace Sass {
env_stack.push_back(0);
env_stack.push_back(env);
block_stack.push_back(0);
call_stack.push_back(0);
// import_stack.push_back(0);
property_stack.push_back(0);
selector_stack.push_back(0);
Expand Down Expand Up @@ -327,6 +329,11 @@ namespace Sass {

Statement* Expand::operator()(Import_Stub* i)
{
// get parent node from call stack
AST_Node* parent = call_stack.back();
if (parent && dynamic_cast<Block*>(parent) == NULL) {
error("Import directives may not be used within control directives or mixins.", i->pstate());
}
// we don't seem to need that actually afterall
Sass_Import_Entry import = sass_make_import(
i->imp_path().c_str(),
Expand Down Expand Up @@ -372,13 +379,15 @@ namespace Sass {
{
Env env(environment(), true);
env_stack.push_back(&env);
call_stack.push_back(i);
if (*i->predicate()->perform(&eval)) {
append_block(i->block());
}
else {
Block* alt = i->alternative();
if (alt) append_block(alt);
}
call_stack.pop_back();
env_stack.pop_back();
return 0;
}
Expand Down Expand Up @@ -410,6 +419,7 @@ namespace Sass {
// only create iterator once in this environment
Env env(environment(), true);
env_stack.push_back(&env);
call_stack.push_back(f);
Number* it = SASS_MEMORY_NEW(env.mem, Number, low->pstate(), start, sass_end->unit());
env.set_local(variable, it);
Block* body = f->block();
Expand All @@ -432,6 +442,7 @@ namespace Sass {
append_block(body);
}
}
call_stack.pop_back();
env_stack.pop_back();
return 0;
}
Expand All @@ -457,6 +468,7 @@ namespace Sass {
// remember variables and then reset them
Env env(environment(), true);
env_stack.push_back(&env);
call_stack.push_back(e);
Block* body = e->block();

if (map) {
Expand Down Expand Up @@ -511,6 +523,7 @@ namespace Sass {
append_block(body);
}
}
call_stack.pop_back();
env_stack.pop_back();
return 0;
}
Expand All @@ -521,9 +534,11 @@ namespace Sass {
Block* body = w->block();
Env env(environment(), true);
env_stack.push_back(&env);
call_stack.push_back(w);
while (*pred->perform(&eval)) {
append_block(body);
}
call_stack.pop_back();
env_stack.pop_back();
return 0;
}
Expand Down Expand Up @@ -693,10 +708,12 @@ namespace Sass {
// process and add to last block on stack
inline void Expand::append_block(Block* b)
{
if (b->is_root()) call_stack.push_back(b);
for (size_t i = 0, L = b->length(); i < L; ++i) {
Statement* ith = (*b)[i]->perform(this);
if (ith) *block_stack.back() << ith;
}
if (b->is_root()) call_stack.pop_back();
}

}
1 change: 1 addition & 0 deletions src/expand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace Sass {
// it's easier to work with vectors
std::vector<Env*> env_stack;
std::vector<Block*> block_stack;
std::vector<AST_Node*> call_stack;
std::vector<String*> property_stack;
std::vector<Selector_List*> selector_stack;
std::vector<Backtrace*>backtrace_stack;
Expand Down
43 changes: 20 additions & 23 deletions src/extend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,7 @@ namespace Sass {
for (size_t index = 0; index < pCompound->length(); index++) {
Simple_Selector* pSimpleSelector = (*pCompound)[index];
(*pSels) << pSimpleSelector;
pCompound->extended(true);
}
}

Expand Down Expand Up @@ -1779,29 +1780,6 @@ namespace Sass {
pIter = pIter->tail();
}

if (!hasExtension) {
/* ToDo: don't break stuff
std::stringstream err;
To_String to_string(&ctx);
std::string cwd(Sass::File::get_cwd());
std::string sel1(pComplexSelector->perform(&to_string));
Compound_Selector* pExtendSelector = 0;
for (auto i : subset_map.values()) {
if (i.first == pComplexSelector) {
pExtendSelector = i.second;
break;
}
}
if (!pExtendSelector || !pExtendSelector->is_optional()) {
std::string sel2(pExtendSelector ? pExtendSelector->perform(&to_string) : "[unknown]");
err << "\"" << sel1 << "\" failed to @extend \"" << sel2 << "\"\n";
err << "The selector \"" << sel2 << "\" was not found.\n";
err << "Use \"@extend " << sel2 << " !optional\" if the extend should be able to fail.";
error(err.str(), pExtendSelector ? pExtendSelector->pstate() : pComplexSelector->pstate());
}
*/
}

return hasExtension;
}

Expand Down Expand Up @@ -2071,6 +2049,25 @@ namespace Sass {
for (size_t i = 0, L = b->length(); i < L; ++i) {
(*b)[i]->perform(this);
}
// do final check if everything was extended
// we set `extended` flag on extended selectors
if (b->is_root()) {
// debug_subset_map(subset_map);
for(auto const &it : subset_map.values()) {
Complex_Selector* sel = it.first ? it.first->first() : NULL;
Compound_Selector* ext = it.second ? it.second : NULL;
if (ext && (ext->extended() || ext->is_optional())) continue;
std::string str_sel(sel->to_string());
std::string str_ext(ext->to_string());
// debug_ast(sel, "sel: ");
// debug_ast(ext, "ext: ");
error("\"" + str_sel + "\" failed to @extend \"" + str_ext + "\".\n"
"The selector \"" + str_ext + "\" was not found.\n"
"Use \"@extend " + str_ext + " !optional\" if the"
" extend should be able to fail.", ext->pstate());
}
}

}

void Extend::operator()(Ruleset* pRuleset)
Expand Down
2 changes: 1 addition & 1 deletion src/operation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Sass {
virtual T operator()(Ruleset* x) = 0;
virtual T operator()(Propset* x) = 0;
virtual T operator()(Bubble* x) = 0;
virtual T operator()(Supports_Block* x) = 0;
virtual T operator()(Supports_Block* x) = 0;
virtual T operator()(Media_Block* x) = 0;
virtual T operator()(At_Root_Block* x) = 0;
virtual T operator()(At_Rule* x) = 0;
Expand Down
Loading

0 comments on commit a6386bd

Please sign in to comment.