Skip to content

Commit

Permalink
Merge pull request sass#715 from mgreter/feature/overload-error-fn
Browse files Browse the repository at this point in the history
Implement @error function
  • Loading branch information
mgreter committed Dec 13, 2014
2 parents efe46c6 + d31c960 commit 48e97c2
Show file tree
Hide file tree
Showing 26 changed files with 151 additions and 19 deletions.
12 changes: 12 additions & 0 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,18 @@ namespace Sass {
ATTACH_OPERATIONS();
};

///////////////////////////////
// The Sass `@error` directive.
///////////////////////////////
class Error : public Statement {
ADD_PROPERTY(Expression*, message);
public:
Error(string path, Position position, Expression* msg)
: Statement(path, position), message_(msg)
{ }
ATTACH_OPERATIONS();
};

///////////////////////////////////////////
// CSS comments. These may be interpolated.
///////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions ast_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace Sass {
Import<Function_Call*>* new_CSS_Import(string p, size_t l, Function_Call* loc);
Import<String*>* new_SASS_Import(string p, size_t l, String* loc);
Warning* new_Warning(string p, size_t l, Expression* msg);
Error* new_Error(string p, size_t l, Expression* msg);
Comment* new_Comment(string p, size_t l, String* txt);
If* new_If(string p, size_t l, Expression* pred, Block* con, Block* alt = 0);
For* new_For(string p, size_t l, string var, Expression* lo, Expression* hi, Block* b, bool inc);
Expand Down
1 change: 1 addition & 0 deletions ast_fwd_decl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace Sass {
class Import;
class Import_Stub;
class Warning;
class Error;
class Comment;
class If;
class For;
Expand Down
1 change: 1 addition & 0 deletions constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace Sass {
extern const char in_kwd[] = "in";
extern const char while_kwd[] = "@while";
extern const char warn_kwd[] = "@warn";
extern const char error_kwd[] = "@error";
extern const char default_kwd[] = "default";
extern const char global_kwd[] = "global";
extern const char null_kwd[] = "null";
Expand Down
1 change: 1 addition & 0 deletions constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace Sass {
extern const char in_kwd[];
extern const char while_kwd[];
extern const char warn_kwd[];
extern const char error_kwd[];
extern const char default_kwd[];
extern const char global_kwd[];
extern const char null_kwd[];
Expand Down
6 changes: 3 additions & 3 deletions error_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

namespace Sass {

Error::Error(Type type, string path, Position position, string message)
Sass_Error::Sass_Error(Type type, string path, Position position, string message)
: type(type), path(path), position(position), message(message)
{ }

void error(string msg, string path, Position position)
{ throw Error(Error::syntax, path, position, msg); }
{ throw Sass_Error(Sass_Error::syntax, path, position, msg); }

void error(string msg, string path, Position position, Backtrace* bt)
{
Expand All @@ -22,7 +22,7 @@ namespace Sass {
Backtrace top(bt, path, position, "");
msg += top.to_string();

throw Error(Error::syntax, path, position, msg);
throw Sass_Error(Sass_Error::syntax, path, position, msg);
}

}
4 changes: 2 additions & 2 deletions error_handling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ namespace Sass {

struct Backtrace;

struct Error {
struct Sass_Error {
enum Type { read, write, syntax, evaluation };

Type type;
string path;
Position position;
string message;

Error(Type type, string path, Position position, string message);
Sass_Error(Type type, string path, Position position, string message);

};

Expand Down
39 changes: 38 additions & 1 deletion eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,38 @@ namespace Sass {
return 0;
}

Expression* Eval::operator()(Error* e)
{
Expression* message = e->message()->perform(this);
To_String to_string;

// try to use generic function
if (env->has("@error[f]")) {

Definition* def = static_cast<Definition*>((*env)["@error[f]"]);
// Block* body = def->block();
// Native_Function func = def->native_function();
Sass_C_Function c_func = def->c_function();

To_C to_c;
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA);
sass_list_set_value(c_args, 0, message->perform(&to_c));
Sass_Value* c_val = c_func(c_args, def->cookie());
sass_delete_value(c_args);
sass_delete_value(c_val);
return 0;

}

string prefix("Error: ");
string result(unquote(message->perform(&to_string)));
cerr << prefix << result;
Backtrace top(backtrace, e->path(), e->position(), "");
cerr << top.to_string(true);
cerr << endl << endl;
return 0;
}

Expression* Eval::operator()(List* l)
{
if (l->is_expanded()) return l;
Expand Down Expand Up @@ -450,6 +482,8 @@ namespace Sass {
Sass_Value* c_val = c_func(c_args, def->cookie());
if (sass_value_get_tag(c_val) == SASS_ERROR) {
error("error in C function " + c->name() + ": " + sass_error_get_message(c_val), c->path(), c->position(), backtrace);
} else if (sass_value_get_tag(c_val) == SASS_WARNING) {
error("warning in C function " + c->name() + ": " + sass_warning_get_message(c_val), c->path(), c->position(), backtrace);
}
result = cval_to_astnode(c_val, ctx, backtrace, c->path(), c->position());

Expand Down Expand Up @@ -1037,7 +1071,10 @@ namespace Sass {
e = new (ctx.mem) Null(path, position);
} break;
case SASS_ERROR: {
error("error in C function: " + string(sass_error_get_message(v)), path, position, backtrace);
error("Error in C function: " + string(sass_error_get_message(v)), path, position, backtrace);
} break;
case SASS_WARNING: {
error("Warning in C function: " + string(sass_warning_get_message(v)), path, position, backtrace);
} break;
}
return e;
Expand Down
1 change: 1 addition & 0 deletions eval.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ namespace Sass {
Expression* operator()(While*);
Expression* operator()(Return*);
Expression* operator()(Warning*);
Expression* operator()(Error*);

Expression* operator()(List*);
Expression* operator()(Map*);
Expand Down
7 changes: 7 additions & 0 deletions expand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ namespace Sass {
return 0;
}

Statement* Expand::operator()(Error* e)
{
// eval handles this too, because errors may occur in functions
e->perform(eval->with(env, backtrace));
return 0;
}

Statement* Expand::operator()(Comment* c)
{
// TODO: eval the text, once we're parsing/storing it as a String_Schema
Expand Down
1 change: 1 addition & 0 deletions expand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace Sass {
Statement* operator()(Import*);
Statement* operator()(Import_Stub*);
Statement* operator()(Warning*);
Statement* operator()(Error*);
Statement* operator()(Comment*);
Statement* operator()(If*);
Statement* operator()(For*);
Expand Down
7 changes: 5 additions & 2 deletions functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ namespace Sass {
Definition* make_c_function(Signature sig, Sass_C_Function f, void* cookie, Context& ctx)
{
Parser sig_parser = Parser::from_c_str(sig, ctx, "[c function]");
// allow to overload generic callback and @warn with custom functions
sig_parser.lex< alternatives < identifier, exactly <'*'>, exactly<Constants::warn_kwd> > >();
// allow to overload generic callback plus @warn and @error with custom functions
sig_parser.lex < alternatives < identifier, exactly <'*'>,
exactly < Constants::warn_kwd >,
exactly < Constants::error_kwd >
> >();
string name(Util::normalize_underscores(sig_parser.lexed));
Parameters* params = sig_parser.parse_parameters();
return new (ctx.mem) Definition("[c function]",
Expand Down
8 changes: 8 additions & 0 deletions inspect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ namespace Sass {
append_to_buffer(";");
}

void Inspect::operator()(Error* error)
{
if (ctx) ctx->source_map.add_mapping(error);
append_to_buffer("@error ");
error->message()->perform(this);
append_to_buffer(";");
}

void Inspect::operator()(Comment* comment)
{
comment->text()->perform(this);
Expand Down
1 change: 1 addition & 0 deletions inspect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace Sass {
virtual void operator()(Import*);
virtual void operator()(Import_Stub*);
virtual void operator()(Warning*);
virtual void operator()(Error*);
virtual void operator()(Comment*);
virtual void operator()(If*);
virtual void operator()(For*);
Expand Down
2 changes: 2 additions & 0 deletions operation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace Sass {
virtual T operator()(Import* x) = 0;
virtual T operator()(Import_Stub* x) = 0;
virtual T operator()(Warning* x) = 0;
virtual T operator()(Error* x) = 0;
virtual T operator()(Comment* x) = 0;
virtual T operator()(If* x) = 0;
virtual T operator()(For* x) = 0;
Expand Down Expand Up @@ -93,6 +94,7 @@ namespace Sass {
virtual T operator()(Import* x) { return static_cast<D*>(this)->fallback(x); }
virtual T operator()(Import_Stub* x) { return static_cast<D*>(this)->fallback(x); }
virtual T operator()(Warning* x) { return static_cast<D*>(this)->fallback(x); }
virtual T operator()(Error* x) { return static_cast<D*>(this)->fallback(x); }
virtual T operator()(Comment* x) { return static_cast<D*>(this)->fallback(x); }
virtual T operator()(If* x) { return static_cast<D*>(this)->fallback(x); }
virtual T operator()(For* x) { return static_cast<D*>(this)->fallback(x); }
Expand Down
1 change: 1 addition & 0 deletions output_compressed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace Sass {
virtual void operator()(Import*);
// virtual void operator()(Import_Stub*);
// virtual void operator()(Warning*);
// virtual void operator()(Error*);
virtual void operator()(Comment*);
// virtual void operator()(If*);
// virtual void operator()(For*);
Expand Down
1 change: 1 addition & 0 deletions output_nested.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ namespace Sass {
virtual void operator()(Import*);
// virtual void operator()(Import_Stub*);
// virtual void operator()(Warning*);
// virtual void operator()(Error*);
// virtual void operator()(Comment*);
// virtual void operator()(If*);
// virtual void operator()(For*);
Expand Down
18 changes: 16 additions & 2 deletions parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ namespace Sass {
(*root) << parse_warning();
if (!lex< exactly<';'> >()) error("top-level @warn directive must be terminated by ';'");
}
else if (peek< err >()) {
(*root) << parse_error();
if (!lex< exactly<';'> >()) error("top-level @error directive must be terminated by ';'");
}
// ignore the @charset directive for now
else if (lex< exactly< charset_kwd > >()) {
lex< string_constant >();
Expand Down Expand Up @@ -714,6 +718,10 @@ namespace Sass {
(*block) << parse_warning();
semicolon = true;
}
else if (peek< err >()) {
(*block) << parse_error();
semicolon = true;
}
else if (stack.back() == function_def) {
error("only variable declarations and control directives are allowed inside functions");
}
Expand Down Expand Up @@ -1099,7 +1107,7 @@ namespace Sass {
*args << arg;
return result;
}
catch (Error&) {
catch (Sass_Error&) {
// back up so we can try again
position = here;
source_position = here_p;
Expand Down Expand Up @@ -1729,6 +1737,12 @@ namespace Sass {
return new (ctx.mem) Warning(path, source_position, parse_list());
}

Error* Parser::parse_error()
{
lex< err >();
return new (ctx.mem) Error(path, source_position, parse_list());
}

Selector_Lookahead Parser::lookahead_for_selector(const char* start)
{
const char* p = start ? start : position;
Expand Down Expand Up @@ -1946,7 +1960,7 @@ namespace Sass {

void Parser::error(string msg, Position pos)
{
throw Error(Error::syntax, path, pos.line ? pos : source_position, msg);
throw Sass_Error(Sass_Error::syntax, path, pos.line ? pos : source_position, msg);
}

}
1 change: 1 addition & 0 deletions parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ namespace Sass {
Feature_Query_Condition* parse_supports_declaration();
At_Rule* parse_at_rule();
Warning* parse_warning();
Error* parse_error();

Selector_Lookahead lookahead_for_selector(const char* start = 0);
Selector_Lookahead lookahead_for_extension_target(const char* start = 0);
Expand Down
4 changes: 4 additions & 0 deletions prelexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ namespace Sass {
return exactly<warn_kwd>(src);
}

const char* err(const char* src) {
return exactly<error_kwd>(src);
}

const char* directive(const char* src) {
return sequence< exactly<'@'>, identifier >(src);
}
Expand Down
1 change: 1 addition & 0 deletions prelexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ namespace Sass {
const char* while_directive(const char* src);

const char* warn(const char* src);
const char* err(const char* src);

const char* directive(const char* src);
const char* at_keyword(const char* src);
Expand Down
7 changes: 5 additions & 2 deletions sass2scss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,11 @@ namespace Sass
}

// terminate warn and debug statements immediately
else if (sass.substr(pos_left, 5) == "@warn" || sass.substr(pos_left, 6) == "@debug")
{ sass = indent + sass.substr(pos_left); }
else if (
sass.substr(pos_left, 5) == "@warn" ||
sass.substr(pos_left, 6) == "@debug" ||
sass.substr(pos_left, 6) == "@error"
) { sass = indent + sass.substr(pos_left); }
// replace some specific sass shorthand directives (if not fallowed by a white space character)
else if (sass.substr(pos_left, 1) == "=" && sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left) != pos_left + 1)
{ sass = indent + "@mixin " + sass.substr(pos_left + 1); }
Expand Down
2 changes: 1 addition & 1 deletion sass_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ extern "C" {
try {
throw;
}
catch (Error& e) {
catch (Sass_Error& e) {
stringstream msg_stream;
JsonNode* json_err = json_mkobject();
json_append_member(json_err, "status", json_mknumber(1));
Expand Down
4 changes: 2 additions & 2 deletions sass_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ extern "C" {

copy_strings(cpp_ctx.get_included_files(1), &c_ctx->included_files, 1);
}
catch (Error& e) {
catch (Sass_Error& e) {
stringstream msg_stream;
msg_stream << e.path << ":" << e.position.line << ": " << e.message << endl;
c_ctx->error_message = strdup(msg_stream.str().c_str());
Expand Down Expand Up @@ -225,7 +225,7 @@ extern "C" {

copy_strings(cpp_ctx.get_included_files(), &c_ctx->included_files);
}
catch (Error& e) {
catch (Sass_Error& e) {
stringstream msg_stream;
msg_stream << e.path << ":" << e.position.line << ": " << e.message << endl;
c_ctx->error_message = strdup(msg_stream.str().c_str());
Expand Down
Loading

0 comments on commit 48e97c2

Please sign in to comment.