Skip to content

Commit

Permalink
Improve sourcemap output for prepended texts
Browse files Browse the repository at this point in the history
Fixes #879
Should work for all prepended texts (like top-comments)
  • Loading branch information
mgreter committed Mar 9, 2015
1 parent 5606d26 commit 21ce837
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 28 deletions.
1 change: 1 addition & 0 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "ast_def_macros.hpp"
#include "ast_fwd_decl.hpp"
#include "to_string.hpp"
#include "source_map.hpp"

#include "sass.h"
#include "sass_values.h"
Expand Down
13 changes: 10 additions & 3 deletions emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,17 @@ namespace Sass {
}
}

// prepend some text or token to the buffer
void Emitter::prepend_output(const OutputBuffer& output)
{
wbuf.smap.prepend(output);
wbuf.buffer = output.buffer + wbuf.buffer;
}

// prepend some text or token to the buffer
void Emitter::prepend_string(const string& text)
{
// update source-map for new text
wbuf.smap.prepend(Offset(text));
wbuf.buffer = text + wbuf.buffer;
}

Expand All @@ -104,12 +111,12 @@ namespace Sass {
// add to buffer
wbuf.buffer += out;
// account for data in source-maps
wbuf.smap.update_column(out);
wbuf.smap.append(Offset(out));
} else {
// add to buffer
wbuf.buffer += text;
// account for data in source-maps
wbuf.smap.update_column(text);
wbuf.smap.append(Offset(text));
}
}

Expand Down
13 changes: 2 additions & 11 deletions emitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,6 @@ namespace Sass {
class Context;
using namespace std;

class OutputBuffer {
public:
OutputBuffer(void)
: buffer(""),
smap()
{ }
public:
string buffer;
SourceMap smap;
};

class Emitter {

public:
Expand All @@ -31,6 +20,7 @@ namespace Sass {
public:
const string buffer(void) { return wbuf.buffer; }
const SourceMap smap(void) { return wbuf.smap; }
const OutputBuffer output(void) { return wbuf; }
// proxy methods for source maps
void add_source_index(size_t idx);
void set_filename(const string& str);
Expand Down Expand Up @@ -64,6 +54,7 @@ namespace Sass {
void flush_schedules(void);
// prepend some text or token to the buffer
void prepend_string(const string& text);
void prepend_output(const OutputBuffer& out);
// append some text or token to the buffer
void append_string(const string& text);
// append some white-space only text
Expand Down
5 changes: 2 additions & 3 deletions output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ namespace Sass {

// flush scheduled outputs
inspect.finalize();
// create combined buffer string
wbuf.buffer = inspect.buffer()
+ this->buffer();
// prepend buffer on top
prepend_output(inspect.output());
// make sure we end with a linefeed
if (!ends_with(wbuf.buffer, ctx->linefeed)) {
// if the output is not completely empty
Expand Down
26 changes: 24 additions & 2 deletions position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ namespace Sass {

using namespace std;

Offset::Offset(const char* string)
: line(0), column(0)
{
*this = inc(string, string + strlen(string));
}

Offset::Offset(const string& text)
: line(0), column(0)
{
*this = inc(text.c_str(), text.c_str() + text.size());
}

Offset::Offset(const size_t line, const size_t column)
: line(line), column(column) { }

Expand Down Expand Up @@ -34,7 +46,12 @@ namespace Sass {
return line != pos.line || column != pos.column;
}

const Offset Offset::operator+ (const Offset &off) const
void Offset::operator+= (const Offset &off)
{
*this = Offset(line + off.line, off.line > 0 ? off.column : off.column + column);
}

Offset Offset::operator+ (const Offset &off) const
{
return Offset(line + off.line, off.line > 0 ? off.column : off.column + column);
}
Expand Down Expand Up @@ -67,7 +84,7 @@ namespace Sass {
Position Position::inc(const char* begin, const char* end) const
{
Offset offset(line, column);
offset.inc(begin, end);
offset = offset.inc(begin, end);
return Position(file, offset);
}

Expand All @@ -81,6 +98,11 @@ namespace Sass {
return file == pos.file || line != pos.line || column != pos.column;
}

void Position::operator+= (const Offset &off)
{
*this = Position(file, line + off.line, off.line > 0 ? off.column : off.column + column);
}

const Position Position::operator+ (const Offset &off) const
{
return Position(file, line + off.line, off.line > 0 ? off.column : off.column + column);
Expand Down
6 changes: 5 additions & 1 deletion position.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ namespace Sass {
class Offset {

public: // c-tor
Offset(const char* string);
Offset(const string& text);
Offset(const size_t line, const size_t column);

// return new position, incremented by the given string
Offset inc(const char* begin, const char* end) const;

public: // overload operators for position
void operator+= (const Offset &pos);
bool operator== (const Offset &pos) const;
bool operator!= (const Offset &pos) const;
const Offset operator+ (const Offset &off) const;
Offset operator+ (const Offset &off) const;

public: // overload output stream operator
// friend ostream& operator<<(ostream& strm, const Offset& off);
Expand All @@ -45,6 +48,7 @@ namespace Sass {
Position(const size_t file, const size_t line, const size_t column);

public: // overload operators for position
void operator+= (const Offset &off);
bool operator== (const Position &pos) const;
bool operator!= (const Position &pos) const;
const Position operator+ (const Offset &off) const;
Expand Down
50 changes: 43 additions & 7 deletions source_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,51 @@ namespace Sass {
return result;
}

void SourceMap::update_column(const string& str)
void SourceMap::prepend(const OutputBuffer& out)
{
const ptrdiff_t new_line_count = std::count(str.begin(), str.end(), '\n');
current_position.line += new_line_count;
if (new_line_count > 0) {
current_position.column = str.size() - str.find_last_of('\n') - 1;
} else {
current_position.column += str.size();
Offset size(out.smap.current_position);
for (Mapping mapping : out.smap.mappings) {
if (mapping.generated_position.line > size.line) {
throw(runtime_error("prepend sourcemap has illegal line"));
}
if (mapping.generated_position.line == size.line) {
if (mapping.generated_position.column > size.column) {
throw(runtime_error("prepend sourcemap has illegal column"));
}
}
}
// will adjust the offset
prepend(Offset(out.buffer));
// now add the new mappings
VECTOR_UNSHIFT(mappings, out.smap.mappings);
}

void SourceMap::append(const OutputBuffer& out)
{
append(Offset(out.buffer));
}

void SourceMap::prepend(const Offset& offset)
{
if (offset.line != 0 || offset.column != 0) {
for (Mapping& mapping : mappings) {
// move stuff on the first old line
if (mapping.generated_position.line == 0) {
mapping.generated_position.column += offset.column;
}
// make place for the new lines
mapping.generated_position.line += offset.line;
}
}
if (current_position.line == 0) {
current_position.column += offset.column;
}
current_position.line += offset.line;
}

void SourceMap::append(const Offset& offset)
{
current_position += offset;
}

void SourceMap::add_open_mapping(AST_Node* node)
Expand Down
21 changes: 20 additions & 1 deletion source_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@

#include "ast_fwd_decl.hpp"
#include "base64vlq.hpp"
#include "position.hpp"
#include "mapping.hpp"

#define VECTOR_PUSH(vec, ins) vec.insert(vec.end(), ins.begin(), ins.end())
#define VECTOR_UNSHIFT(vec, ins) vec.insert(vec.begin(), ins.begin(), ins.end())

namespace Sass {
using std::vector;

class Context;
class OutputBuffer;

class SourceMap {

Expand All @@ -22,7 +27,10 @@ namespace Sass {
void setFile(const string& str) {
file = str;
}
void update_column(const string& str);
void append(const Offset& offset);
void prepend(const Offset& offset);
void append(const OutputBuffer& out);
void prepend(const OutputBuffer& out);
void add_open_mapping(AST_Node* node);
void add_close_mapping(AST_Node* node);

Expand All @@ -41,6 +49,17 @@ namespace Sass {
Base64VLQ base64vlq;
};

class OutputBuffer {
public:
OutputBuffer(void)
: buffer(""),
smap()
{ }
public:
string buffer;
SourceMap smap;
};

}

#endif

0 comments on commit 21ce837

Please sign in to comment.