Skip to content

Commit

Permalink
Implements call stack queries (functions and mixins)
Browse files Browse the repository at this point in the history
  • Loading branch information
mgreter committed Jan 5, 2017
1 parent 7abaa75 commit 04d96da
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/sass/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ ADDAPI struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compil
ADDAPI size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler);
ADDAPI Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler);
ADDAPI Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx);
ADDAPI size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler);
ADDAPI Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler);
ADDAPI Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx);

// Push function for paths (no manipulation support for now)
ADDAPI void ADDCALL sass_option_push_plugin_path (struct Sass_Options* options, const char* path);
Expand Down
15 changes: 15 additions & 0 deletions include/sass/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ extern "C" {


// Forward declaration
struct Sass_Callee;
struct Sass_Import;
struct Sass_Options;
struct Sass_Compiler;
struct Sass_Importer;
struct Sass_Function;

// Typedef helpers for callee lists
typedef struct Sass_Callee (*Sass_Callee_Entry);
// Typedef helpers for import lists
typedef struct Sass_Import (*Sass_Import_Entry);
typedef struct Sass_Import* (*Sass_Import_List);
Expand All @@ -34,6 +37,12 @@ typedef struct Sass_Function* (*Sass_Function_List);
typedef union Sass_Value* (*Sass_Function_Fn)
(const union Sass_Value*, Sass_Function_Entry cb, struct Sass_Compiler* compiler);

// Type of function calls
enum Sass_Callee_Type {
SASS_CALLEE_MIXIN,
SASS_CALLEE_FUNCTION,
SASS_CALLEE_C_FUNCTION,
};

// Creator for sass custom importer return argument list
ADDAPI Sass_Importer_List ADDCALL sass_make_importer_list (size_t length);
Expand Down Expand Up @@ -66,6 +75,12 @@ ADDAPI Sass_Import_Entry ADDCALL sass_import_set_error(Sass_Import_Entry import,
ADDAPI void ADDCALL sass_import_set_list_entry (Sass_Import_List list, size_t idx, Sass_Import_Entry entry);
ADDAPI Sass_Import_Entry ADDCALL sass_import_get_list_entry (Sass_Import_List list, size_t idx);

// Getters for callee entry
ADDAPI const char* ADDCALL sass_callee_get_name (Sass_Callee_Entry);
ADDAPI const char* ADDCALL sass_callee_get_path (Sass_Callee_Entry);
ADDAPI size_t ADDCALL sass_callee_get_line (Sass_Callee_Entry);
ADDAPI size_t ADDCALL sass_callee_get_column (Sass_Callee_Entry);
ADDAPI enum Sass_Callee_Type ADDCALL sass_callee_get_type (Sass_Callee_Entry);
// Getters for import entry
ADDAPI const char* ADDCALL sass_import_get_imp_path (Sass_Import_Entry);
ADDAPI const char* ADDCALL sass_import_get_abs_path (Sass_Import_Entry);
Expand Down
1 change: 1 addition & 0 deletions src/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ namespace Sass {
std::map<const std::string, StyleSheet> sheets;
Subset_Map subset_map;
std::vector<Sass_Import_Entry> import_stack;
std::vector<Sass_Callee> callee_stack;

struct Sass_Compiler* c_compiler;

Expand Down
51 changes: 51 additions & 0 deletions src/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "parser.hpp"
#include "expand.hpp"
#include "color_maps.hpp"
#include "sass_functions.hpp"

namespace Sass {

Expand Down Expand Up @@ -334,6 +335,16 @@ namespace Sass {
// try to use generic function
if (env->has("@warn[f]")) {

// add call stack entry
ctx.callee_stack.push_back({
"@warn",
w->pstate().path,
w->pstate().line + 1,
w->pstate().column + 1,
SASS_CALLEE_FUNCTION,
{ env }
});

Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@warn[f]"]);
// Block_Obj body = def->block();
// Native_Function func = def->native_function();
Expand All @@ -345,6 +356,7 @@ namespace Sass {
sass_list_set_value(c_args, 0, message->perform(&to_c));
union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler);
ctx.c_options.output_style = outstyle;
ctx.callee_stack.pop_back();
sass_delete_value(c_args);
sass_delete_value(c_val);
return 0;
Expand All @@ -370,6 +382,16 @@ namespace Sass {
// try to use generic function
if (env->has("@error[f]")) {

// add call stack entry
ctx.callee_stack.push_back({
"@error",
e->pstate().path,
e->pstate().line + 1,
e->pstate().column + 1,
SASS_CALLEE_FUNCTION,
{ env }
});

Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@error[f]"]);
// Block_Obj body = def->block();
// Native_Function func = def->native_function();
Expand All @@ -381,6 +403,7 @@ namespace Sass {
sass_list_set_value(c_args, 0, message->perform(&to_c));
union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler);
ctx.c_options.output_style = outstyle;
ctx.callee_stack.pop_back();
sass_delete_value(c_args);
sass_delete_value(c_val);
return 0;
Expand All @@ -403,6 +426,16 @@ namespace Sass {
// try to use generic function
if (env->has("@debug[f]")) {

// add call stack entry
ctx.callee_stack.push_back({
"@debug",
d->pstate().path,
d->pstate().line + 1,
d->pstate().column + 1,
SASS_CALLEE_FUNCTION,
{ env }
});

Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@debug[f]"]);
// Block_Obj body = def->block();
// Native_Function func = def->native_function();
Expand All @@ -414,6 +447,7 @@ namespace Sass {
sass_list_set_value(c_args, 0, message->perform(&to_c));
union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler);
ctx.c_options.output_style = outstyle;
ctx.callee_stack.pop_back();
sass_delete_value(c_args);
sass_delete_value(c_val);
return 0;
Expand Down Expand Up @@ -874,6 +908,14 @@ namespace Sass {
bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
exp.backtrace_stack.push_back(&here);
ctx.callee_stack.push_back({
c->name().c_str(),
c->pstate().path,
c->pstate().line + 1,
c->pstate().column + 1,
SASS_CALLEE_FUNCTION
});

// eval the body if user-defined or special, invoke underlying CPP function if native
if (body /* && !Prelexer::re_special_fun(name.c_str()) */) {
result = body->perform(this);
Expand All @@ -885,6 +927,7 @@ namespace Sass {
error(std::string("Function ") + c->name() + " did not return a value", c->pstate());
}
exp.backtrace_stack.pop_back();
ctx.callee_stack.pop_back();
}

// else if it's a user-defined c function
Expand All @@ -905,6 +948,13 @@ namespace Sass {

Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
exp.backtrace_stack.push_back(&here);
ctx.callee_stack.push_back({
c->name().c_str(),
c->pstate().path,
c->pstate().line + 1,
c->pstate().column + 1,
SASS_CALLEE_C_FUNCTION
});

To_C to_c;
union Sass_Value* c_args = sass_make_list(params->length(), SASS_COMMA, false);
Expand All @@ -924,6 +974,7 @@ namespace Sass {
result = cval_to_astnode(c_val, backtrace(), c->pstate());

exp.backtrace_stack.pop_back();
ctx.callee_stack.pop_back();
sass_delete_value(c_args);
if (c_val != c_args)
sass_delete_value(c_val);
Expand Down
10 changes: 10 additions & 0 deletions src/expand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "backtrace.hpp"
#include "context.hpp"
#include "parser.hpp"
#include "sass_functions.hpp"

namespace Sass {

Expand Down Expand Up @@ -706,6 +707,14 @@ namespace Sass {
Arguments_Obj args = SASS_MEMORY_CAST(Arguments, rv);
Backtrace new_bt(backtrace(), c->pstate(), ", in mixin `" + c->name() + "`");
backtrace_stack.push_back(&new_bt);
ctx.callee_stack.push_back({
c->name().c_str(),
c->pstate().path,
c->pstate().line + 1,
c->pstate().column + 1,
SASS_CALLEE_MIXIN
});

Env new_env(def->environment());
env_stack.push_back(&new_env);
if (c->block()) {
Expand Down Expand Up @@ -735,6 +744,7 @@ namespace Sass {

env_stack.pop_back();
backtrace_stack.pop_back();
ctx.callee_stack.pop_back();

recursions --;
return trace.detach();
Expand Down
4 changes: 4 additions & 0 deletions src/sass_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,10 @@ extern "C" {
size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.size(); }
Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.back(); }
Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx) { return compiler->cpp_ctx->import_stack[idx]; }
// Getters for Sass_Compiler options (query function stack)
size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->callee_stack.size(); }
Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler) { return &compiler->cpp_ctx->callee_stack.back(); }
Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx) { return &compiler->cpp_ctx->callee_stack[idx]; }

// Calculate the size of the stored null terminated array
size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx)
Expand Down
7 changes: 7 additions & 0 deletions src/sass_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ extern "C" {
free(import);
}

// Getter for callee entry
const char* ADDCALL sass_callee_get_name(Sass_Callee_Entry entry) { return entry->name; }
const char* ADDCALL sass_callee_get_path(Sass_Callee_Entry entry) { return entry->path; }
size_t ADDCALL sass_callee_get_line(Sass_Callee_Entry entry) { return entry->line; }
size_t ADDCALL sass_callee_get_column(Sass_Callee_Entry entry) { return entry->column; }
enum Sass_Callee_Type ADDCALL sass_callee_get_type(Sass_Callee_Entry entry) { return entry->type; }

// Getter for import entry
const char* ADDCALL sass_import_get_imp_path(Sass_Import_Entry entry) { return entry->imp_path; }
const char* ADDCALL sass_import_get_abs_path(Sass_Import_Entry entry) { return entry->abs_path; }
Expand Down
9 changes: 9 additions & 0 deletions src/sass_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ struct Sass_Import {
size_t column;
};

// External call entry
struct Sass_Callee {
const char* name;
const char* path;
size_t line;
size_t column;
enum Sass_Callee_Type type;
};

// Struct to hold importer callback
struct Sass_Importer {
Sass_Importer_Fn importer;
Expand Down

0 comments on commit 04d96da

Please sign in to comment.