Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix regressions 3.3.3 #1925

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,7 @@ namespace Sass {

Selector_List* Selector_List::parentize(Selector_List* ps, Context& ctx)
{
if (!this->has_parent_ref()) return this;
Selector_List* ss = SASS_MEMORY_NEW(ctx.mem, Selector_List, pstate());
for (size_t pi = 0, pL = ps->length(); pi < pL; ++pi) {
Selector_List* list = SASS_MEMORY_NEW(ctx.mem, Selector_List, pstate());
Expand All @@ -960,6 +961,38 @@ namespace Sass {
return ss;
}

Compound_Selector* Compound_Selector::parentize(Selector_List* parents, Context& ctx)
{
Compound_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, this->pstate());
for (Simple_Selector* sel : this->elements()) {
if (Wrapped_Selector* ws = dynamic_cast<Wrapped_Selector*>(sel)) {
if (Selector_List* sl = dynamic_cast<Selector_List*>(ws->selector())) {
Selector_List* prl = sl->parentize(parents, ctx);
if (sl->length() > 1) {
*cpy << SASS_MEMORY_NEW(ctx.mem,
Wrapped_Selector,
ws->pstate(),
ws->name(),
prl);
} else {
for (Complex_Selector* prs : *prl) {
*cpy << SASS_MEMORY_NEW(ctx.mem,
Wrapped_Selector,
ws->pstate(),
ws->name(),
prs);
}
}
} else {
*cpy << sel;
}
} else {
*cpy << sel;
}
}
return cpy;
}

Selector_List* Complex_Selector::parentize(Selector_List* parents, Context& ctx)
{

Expand Down Expand Up @@ -1006,7 +1039,7 @@ namespace Sass {
throw Exception::InvalidParent(parent, ss);
}
ss->tail(tail ? tail->clone(ctx) : 0);
Compound_Selector* h = head_->clone(ctx);
Compound_Selector* h = head_->parentize(parents, ctx);
if (h->length()) h->erase(h->begin());
ss->head(h->length() ? h : 0);
// \/ IMO ruby sass bug \/
Expand Down Expand Up @@ -1085,18 +1118,16 @@ namespace Sass {
Complex_Selector* Complex_Selector::first()
{
// declare variables used in loop
Complex_Selector* cur = this->tail_;
const Compound_Selector* head = head_;
Complex_Selector* cur = this;
const Compound_Selector* head;
// processing loop
while (cur)
{
// get the head
head = cur->head_;
// check for single parent ref
if (head && head->length() == 1)
{
// abort (and return) if it is not a parent selector
if (!dynamic_cast<Parent_Selector*>((*head)[0])) break;
// abort (and return) if it is not a parent selector
if (!head || head->length() != 1 || !dynamic_cast<Parent_Selector*>((*head)[0])) {
break;
}
// advance to next
cur = cur->tail_;
Expand Down Expand Up @@ -1897,6 +1928,10 @@ namespace Sass {
return false;
}

bool String_Constant::is_invisible() const {
return value_.empty() && quote_mark_ == 0;
}

bool String_Constant::operator== (const Expression& rhs) const
{
if (const String_Quoted* qstr = dynamic_cast<const String_Quoted*>(&rhs)) {
Expand Down
2 changes: 2 additions & 0 deletions src/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1514,6 +1514,7 @@ namespace Sass {
{ }
std::string type() { return "string"; }
static std::string type_name() { return "string"; }
virtual bool is_invisible() const;

virtual size_t hash()
{
Expand Down Expand Up @@ -2219,6 +2220,7 @@ namespace Sass {
}

Complex_Selector* to_complex(Memory_Manager& mem);
Compound_Selector* parentize(Selector_List* parents, Context& ctx);
Compound_Selector* unify_with(Compound_Selector* rhs, Context& ctx);
// virtual Selector_Placeholder* find_placeholder();
virtual bool has_parent_ref();
Expand Down
30 changes: 19 additions & 11 deletions src/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,22 +504,22 @@ namespace Sass {
}

// only the last item will be used to eval the binary expression
if (String_Schema* s_1 = dynamic_cast<String_Schema*>(b->left())) {
if (!s_1->is_right_interpolant()) {
ret_schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, s_1->pstate());
if (String_Schema* s_l = dynamic_cast<String_Schema*>(b->left())) {
if (!s_l->has_interpolant() && (!s_l->is_right_interpolant())) {
ret_schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, s_l->pstate());
Binary_Expression* bin_ex = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, b->pstate(),
b->op(), s_1->last(), b->right());
b->op(), s_l->last(), b->right());
bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed());
// bin_ex->is_interpolant(b->left()->is_interpolant());
for (size_t i = 0; i < s_1->length() - 1; ++i) {
*ret_schema << s_1->at(i)->perform(this);
for (size_t i = 0; i < s_l->length() - 1; ++i) {
*ret_schema << s_l->at(i)->perform(this);
}
*ret_schema << bin_ex->perform(this);
return ret_schema->perform(this);
}
}
if (String_Schema* s_r = dynamic_cast<String_Schema*>(b->right())) {
if (!s_r->is_left_interpolant() || op_type == Sass_OP::DIV) {
if (!s_r->has_interpolant() && (!s_r->is_left_interpolant() || op_type == Sass_OP::DIV)) {
ret_schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, s_r->pstate());
Binary_Expression* bin_ex = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, b->pstate(),
b->op(), b->left(), s_r->first());
Expand Down Expand Up @@ -691,7 +691,7 @@ namespace Sass {
}
}

if (force_delay) {
if (force_delay) {
std::string str("");
str += v_l->to_string(ctx.c_options);
if (b->op().ws_before) str += " ";
Expand Down Expand Up @@ -1125,11 +1125,12 @@ namespace Sass {
if (List* l = dynamic_cast<List*>(ex)) {
List* ll = SASS_MEMORY_NEW(ctx.mem, List, l->pstate(), 0, l->separator());
// this fixes an issue with bourbon sample, not really sure why
if (l->size() && dynamic_cast<Null*>((*l)[0])) { res += " "; }
// if (l->size() && dynamic_cast<Null*>((*l)[0])) { res += ""; }
for(auto item : *l) {
item->is_interpolant(l->is_interpolant());
std::string rl(""); interpolation(ctx, rl, item, into_quotes, l->is_interpolant());
if (rl != "") *ll << SASS_MEMORY_NEW(ctx.mem, String_Quoted, item->pstate(), rl);
bool is_null = dynamic_cast<Null*>(item) != 0; // rl != ""
if (!is_null) *ll << SASS_MEMORY_NEW(ctx.mem, String_Quoted, item->pstate(), rl);
}
res += (ll->to_string(ctx.c_options));
ll->is_interpolant(l->is_interpolant());
Expand Down Expand Up @@ -1170,15 +1171,22 @@ namespace Sass {
}
}
}
bool was_quoted = false;
bool was_interpolant = false;
std::string res("");
for (size_t i = 0; i < L; ++i) {
bool is_quoted = dynamic_cast<String_Quoted*>((*s)[i]) != NULL;
(*s)[i]->perform(this);
if (was_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; }
else if (i > 0 && is_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; }
Expression* ex = (*s)[i]->is_delayed() ? (*s)[i] : (*s)[i]->perform(this);
interpolation(ctx, res, ex, into_quotes, ex->is_interpolant());
was_quoted = dynamic_cast<String_Quoted*>((*s)[i]) != NULL;
was_interpolant = (*s)[i]->is_interpolant();

}
if (!s->is_interpolant()) {
if (res == "") return SASS_MEMORY_NEW(ctx.mem, Null, s->pstate());
if (s->length() > 1 && res == "") return SASS_MEMORY_NEW(ctx.mem, Null, s->pstate());
return SASS_MEMORY_NEW(ctx.mem, String_Constant, s->pstate(), res);
}
String_Quoted* str = SASS_MEMORY_NEW(ctx.mem, String_Quoted, s->pstate(), res);
Expand Down
5 changes: 4 additions & 1 deletion src/inspect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,10 @@ namespace Sass {
Expression* list_item = (*list)[i];
if (output_style() != TO_SASS) {
if (list_item->is_invisible()) {
continue;
// this fixes an issue with "" in a list
if (!dynamic_cast<String_Constant*>(list_item)) {
continue;
}
}
}
if (items_output) {
Expand Down
46 changes: 32 additions & 14 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1596,6 +1596,8 @@ namespace Sass {
}

const char* e = 0;
const char* ee = end;
end = stop;
size_t num_items = 0;
bool need_space = false;
while (position < stop) {
Expand All @@ -1605,7 +1607,7 @@ namespace Sass {
}
if (need_space) {
need_space = false;
(*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, " ");
// (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, " ");
}
if ((e = peek< re_functional >()) && e < stop) {
(*schema) << parse_function_call();
Expand All @@ -1632,19 +1634,22 @@ namespace Sass {
else if (lex< alternatives < exactly<'%'>, exactly < '-' >, exactly < '+' > > >()) {
(*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
}
else if (lex< sequence < identifier > >()) {
(*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
// lex a quoted string
else if (lex< quoted_string >()) {
// need_space = true;
// if (schema->length()) (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, " ");
// else need_space = true;
(*schema) << parse_string();
if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
need_space = true;
// need_space = true;
}
if (peek < exactly < '-' > >()) break;
}
// lex a quoted string
else if (lex< quoted_string >()) {
(*schema) << SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, lexed, '"');
else if (lex< sequence < identifier > >()) {
(*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
need_space = true;
// need_space = true;
}
if (peek < exactly < '-' > >()) return schema;
}
// lex (normalized) variable
else if (lex< variable >()) {
Expand Down Expand Up @@ -1675,10 +1680,15 @@ namespace Sass {
(*schema) << parse_factor();
}
else {
return schema;
break;
}
++num_items;
}
if (position != stop) {
(*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(position, stop));
position = stop;
}
end = ee;
return schema;
}

Expand Down Expand Up @@ -2392,19 +2402,27 @@ namespace Sass {
non_greedy <
alternatives <
// consume whitespace
block_comment, spaces,
block_comment, // spaces,
// main tokens
interpolant,
sequence <
interpolant,
optional <
quoted_string
>
>,
identifier,
variable,
// issue #442
sequence <
parenthese_scope,
interpolant
interpolant,
optional <
quoted_string
>
>
>,
sequence <
optional_spaces,
// optional_spaces,
alternatives <
exactly<'{'>,
exactly<'}'>,
Expand Down
8 changes: 7 additions & 1 deletion src/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ namespace Sass {
const char* it_before_token = sneak < mx >(start);

// match the given prelexer
return mx(it_before_token);
const char* match = mx(it_before_token);

// check if match is in valid range
return match <= end ? match : 0;

}

Expand All @@ -142,6 +145,9 @@ namespace Sass {
// now call matcher to get position after token
const char* it_after_token = mx(it_before_token);

// check if match is in valid range
if (it_after_token > end) return 0;

// maybe we want to update the parser state anyway?
if (force == false) {
// assertion that we got a valid match
Expand Down