Skip to content

Commit

Permalink
Parse imports right away after discovery
Browse files Browse the repository at this point in the history
Makes import resolve depth-first instead of breadth-first
Fixes sass#1262
  • Loading branch information
mgreter committed Sep 4, 2015
1 parent 9b07cbd commit ebe0914
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
36 changes: 22 additions & 14 deletions src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ namespace Sass {
if (char* contents = read_file(resolved)) {
add_source(path, resolved, contents);
style_sheets[path] = 0;
size_t i = queue.size() - 1;
process_queue_entry(queue[i], i);
return path;
}
return std::string("");
Expand Down Expand Up @@ -268,6 +270,8 @@ namespace Sass {
if (char* contents = read_file(resolved[0].abs_path)) {
add_source(base_file, resolved[0].abs_path, contents);
style_sheets[base_file] = 0;
size_t i = queue.size() - 1;
process_queue_entry(queue[i], i);
return base_file;
}
}
Expand Down Expand Up @@ -300,28 +304,30 @@ namespace Sass {
return sass_strdup(output.c_str());
}

Block* Context::parse_file()
void Context::process_queue_entry(Sass_Queued& entry, size_t i)
{
Block* root = 0;
for (size_t i = 0; i < queue.size(); ++i) {
if (style_sheets[queue[i].load_path]) return;
Sass_Import_Entry import = sass_make_import(
queue[i].load_path.c_str(),
queue[i].abs_path.c_str(),
entry.load_path.c_str(),
entry.abs_path.c_str(),
0, 0
);
import_stack.push_back(import);
// keep a copy of the path around (for parser states)
strings.push_back(sass_strdup(queue[i].abs_path.c_str()));
ParserState pstate(strings.back(), queue[i].source, i);
Parser p(Parser::from_c_str(queue[i].source, *this, pstate));
Block* ast = p.parse();
strings.push_back(sass_strdup(entry.abs_path.c_str()));
ParserState pstate(strings.back(), entry.source, i);
Parser p(Parser::from_c_str(entry.source, *this, pstate));
style_sheets[entry.load_path] = p.parse();
sass_delete_import(import_stack.back());
import_stack.pop_back();
if (i == 0) root = ast;
// ToDo: we store by load_path, which can lead
// to duplicates if importer reports the same path
// Maybe we should add an error for duplicates!?
style_sheets[queue[i].load_path] = ast;
}

Block* Context::parse_file()
{
Block* root = 0;
for (size_t i = 0; i < queue.size(); ++i) {
process_queue_entry(queue[i], i);
if (i == 0) root = style_sheets[queue[i].load_path];
}
if (root == 0) return 0;

Expand Down Expand Up @@ -368,6 +374,8 @@ namespace Sass {
return parse_file();
}
add_source(input_path, input_path, source_c_str);
size_t idx = queue.size() - 1;
process_queue_entry(queue[idx], idx);
return parse_file();
}

Expand Down
1 change: 1 addition & 0 deletions src/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ namespace Sass {
std::string add_file(const std::string& imp_path);
std::string add_file(const std::string& imp_path, const std::string& abs_path, ParserState pstate);

void process_queue_entry(Sass_Queued& entry, size_t idx);

// allow to optionally overwrite the input path
// default argument for input_path is std::string("stdin")
Expand Down
4 changes: 4 additions & 0 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,13 @@ namespace Sass {
if (abs_path) {
ctx.add_source(uniq_path, abs_path, source);
imp->files().push_back(uniq_path);
size_t i = ctx.queue.size() - 1;
ctx.process_queue_entry(ctx.queue[i], i);
} else {
ctx.add_source(uniq_path, uniq_path, source);
imp->files().push_back(uniq_path);
size_t i = ctx.queue.size() - 1;
ctx.process_queue_entry(ctx.queue[i], i);
}
} else if(abs_path) {
import_single_file(imp, abs_path);
Expand Down

0 comments on commit ebe0914

Please sign in to comment.