Skip to content

Commit

Permalink
Fix ParserState for SourceMaps
Browse files Browse the repository at this point in the history
- Fixes parent selector mappings
- Fixes media block/query mappings
- Fixes variable assignment mappings
- Fixes range over binary expressions
- Don't include semicolon for statics
  • Loading branch information
mgreter committed Oct 22, 2016
1 parent 01f4ffa commit de83d30
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 25 deletions.
42 changes: 42 additions & 0 deletions src/ast.cpp
Expand Up @@ -122,6 +122,11 @@ namespace Sass {
pstate_.offset += pstate - pstate_ + pstate.offset;
}

void AST_Node::set_pstate_offset(const Offset& offset)
{
pstate_.offset = offset;
}

inline bool is_ns_eq(const std::string& l, const std::string& r)
{
if (l.empty() && r.empty()) return true;
Expand Down Expand Up @@ -1056,22 +1061,30 @@ namespace Sass {
if (Class_Selector* sq = dynamic_cast<Class_Selector*>(rh->last())) {
Class_Selector* sqs = SASS_MEMORY_NEW(ctx.mem, Class_Selector, *sq);
sqs->name(sqs->name() + (*h)[0]->name());
sqs->pstate((*h)[0]->pstate());
(*rh)[rh->length()-1] = sqs;
rh->pstate(h->pstate());
for (i = 1; i < L; ++i) *rh << (*h)[i];
} else if (Id_Selector* sq = dynamic_cast<Id_Selector*>(rh->last())) {
Id_Selector* sqs = SASS_MEMORY_NEW(ctx.mem, Id_Selector, *sq);
sqs->name(sqs->name() + (*h)[0]->name());
sqs->pstate((*h)[0]->pstate());
(*rh)[rh->length()-1] = sqs;
rh->pstate(h->pstate());
for (i = 1; i < L; ++i) *rh << (*h)[i];
} else if (Element_Selector* ts = dynamic_cast<Element_Selector*>(rh->last())) {
Element_Selector* tss = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *ts);
tss->name(tss->name() + (*h)[0]->name());
tss->pstate((*h)[0]->pstate());
(*rh)[rh->length()-1] = tss;
rh->pstate(h->pstate());
for (i = 1; i < L; ++i) *rh << (*h)[i];
} else if (Placeholder_Selector* ps = dynamic_cast<Placeholder_Selector*>(rh->last())) {
Placeholder_Selector* pss = SASS_MEMORY_NEW(ctx.mem, Placeholder_Selector, *ps);
pss->name(pss->name() + (*h)[0]->name());
pss->pstate((*h)[0]->pstate());
(*rh)[rh->length()-1] = pss;
rh->pstate(h->pstate());
for (i = 1; i < L; ++i) *rh << (*h)[i];
} else {
*last()->head_ += h;
Expand Down Expand Up @@ -1150,8 +1163,19 @@ namespace Sass {
Sequence_Selector* ss = this->clone(ctx);
ss->tail(t ? t->clone(ctx) : 0);
SimpleSequence_Selector* h = head_->clone(ctx);
// remove parent selector from sequence
if (h->length()) h->erase(h->begin());
ss->head(h->length() ? h : 0);
// adjust for parent selector (1 char)
if (h->length()) {
ParserState state((*h)[0]->pstate());
state.offset.column += 1;
state.column -= 1;
(*h)[0]->pstate(state);
}
// keep old parser state
s->pstate(pstate());
// append new tail
s->append(ctx, ss);
*retval << s;
}
Expand All @@ -1171,10 +1195,21 @@ namespace Sass {
}
ss->tail(tail ? tail->clone(ctx) : 0);
SimpleSequence_Selector* h = head_->clone(ctx);
// remove parent selector from sequence
if (h->length()) h->erase(h->begin());
ss->head(h->length() ? h : 0);
// \/ IMO ruby sass bug \/
ss->has_line_feed(false);
// adjust for parent selector (1 char)
if (h->length()) {
ParserState state((*h)[0]->pstate());
state.offset.column += 1;
state.column -= 1;
(*h)[0]->pstate(state);
}
// keep old parser state
s->pstate(pstate());
// append new tail
s->append(ctx, ss);
*retval << s;
}
Expand Down Expand Up @@ -1557,6 +1592,13 @@ namespace Sass {
return result;
}

SimpleSequence_Selector& SimpleSequence_Selector::operator<<(Simple_Selector* element)
{
Vectorized<Simple_Selector*>::operator<<(element);
pstate_.offset += element->pstate().offset;
return *this;
}

SimpleSequence_Selector* SimpleSequence_Selector::minus(SimpleSequence_Selector* rhs, Context& ctx)
{
SimpleSequence_Selector* result = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, pstate());
Expand Down
5 changes: 4 additions & 1 deletion src/ast.hpp
Expand Up @@ -101,6 +101,7 @@ namespace Sass {
// virtual Block* block() { return 0; }
public:
void update_pstate(const ParserState& pstate);
void set_pstate_offset(const Offset& offset);
public:
Offset off() { return pstate(); }
Position pos() { return pstate(); }
Expand Down Expand Up @@ -235,7 +236,7 @@ namespace Sass {
T& operator[](size_t i) { return elements_[i]; }
virtual const T& at(size_t i) const { return elements_.at(i); }
const T& operator[](size_t i) const { return elements_[i]; }
Vectorized& operator<<(T element)
virtual Vectorized& operator<<(T element)
{
if (!element) return *this;
reset_hash();
Expand Down Expand Up @@ -2292,6 +2293,8 @@ namespace Sass {
return false;
};

SimpleSequence_Selector& operator<<(Simple_Selector* element);

bool is_universal() const
{
return length() == 1 && (*this)[0]->is_universal();
Expand Down
14 changes: 7 additions & 7 deletions src/eval.cpp
Expand Up @@ -502,7 +502,7 @@ namespace Sass {
// only the last item will be used to eval the binary expression
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());
ret_schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, b->pstate());
Binary_Expression* bin_ex = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, b->pstate(),
b->op(), s_l->last(), b->right());
bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // unverified
Expand All @@ -515,7 +515,7 @@ namespace Sass {
}
if (String_Schema* s_r = dynamic_cast<String_Schema*>(b->right())) {
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());
ret_schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, b->pstate());
Binary_Expression* bin_ex = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, b->pstate(),
b->op(), b->left(), s_r->first());
bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // verified
Expand Down Expand Up @@ -599,15 +599,15 @@ namespace Sass {
std::string value(str->value());
const char* start = value.c_str();
if (Prelexer::sequence < Prelexer::dimension, Prelexer::end_of_file >(start) != 0) {
lhs = SASS_MEMORY_NEW(ctx.mem, Textual, lhs->pstate(), Textual::DIMENSION, str->value());
lhs = SASS_MEMORY_NEW(ctx.mem, Textual, b->pstate(), Textual::DIMENSION, str->value());
lhs = lhs->perform(this);
}
}
if (String_Constant* str = dynamic_cast<String_Constant*>(rhs)) {
std::string value(str->value());
const char* start = value.c_str();
if (Prelexer::sequence < Prelexer::number >(start) != 0) {
rhs = SASS_MEMORY_NEW(ctx.mem, Textual, rhs->pstate(), Textual::DIMENSION, str->value());
rhs = SASS_MEMORY_NEW(ctx.mem, Textual, b->pstate(), Textual::DIMENSION, str->value());
rhs = rhs->perform(this);
}
}
Expand Down Expand Up @@ -636,7 +636,7 @@ namespace Sass {
str += b->separator();
if (b->op().ws_after) str += " ";
str += v_r->to_string(ctx.c_options);
String_Constant* val = SASS_MEMORY_NEW(ctx.mem, String_Constant, lhs->pstate(), str);
String_Constant* val = SASS_MEMORY_NEW(ctx.mem, String_Constant, b->pstate(), str);
val->is_interpolant(b->left()->has_interpolant());
return val;
}
Expand Down Expand Up @@ -1545,7 +1545,7 @@ namespace Sass {
(sep != "/" || !rqstr || !rqstr->quote_mark()) */
) {
// create a new string that might be quoted on output (but do not unquote what we pass)
return SASS_MEMORY_NEW(mem, String_Quoted, lhs.pstate(), lstr + rstr, 0, false, true);
return SASS_MEMORY_NEW(mem, String_Quoted, pstate ? *pstate : lhs.pstate(), lstr + rstr, 0, false, true);
}

if (sep != "" && !delayed) {
Expand All @@ -1558,7 +1558,7 @@ namespace Sass {
if (rqstr && rqstr->quote_mark()) rstr = quote(rstr);
}

return SASS_MEMORY_NEW(mem, String_Constant, lhs.pstate(), lstr + sep + rstr);
return SASS_MEMORY_NEW(mem, String_Constant, pstate ? *pstate : lhs.pstate(), lstr + sep + rstr);
}

Expression* cval_to_astnode(Memory_Manager& mem, union Sass_Value* v, Context& ctx, Backtrace* backtrace, ParserState pstate)
Expand Down
4 changes: 2 additions & 2 deletions src/json.cpp
Expand Up @@ -402,7 +402,7 @@ char *json_encode_string(const char *str)
try {
emit_string(&sb, str);
}
catch (std::exception &e) {
catch (std::exception) {
sb_free(&sb);
throw;
}
Expand All @@ -421,7 +421,7 @@ char *json_stringify(const JsonNode *node, const char *space)
else
emit_value(&sb, node);
}
catch (std::exception &e) {
catch (std::exception) {
sb_free(&sb);
throw;
}
Expand Down

0 comments on commit de83d30

Please sign in to comment.