1 // sass.hpp must go before all system headers to get the
2 // __EXTENSIONS__ fix on Solaris.
3 #include "sass.hpp"
4 
5 #include "ast.hpp"
6 #include "prelexer.hpp"
7 #include "backtrace.hpp"
8 #include "error_handling.hpp"
9 
10 #include <iostream>
11 
12 namespace Sass {
13 
14   namespace Exception {
15 
Base(SourceSpan pstate,sass::string msg,Backtraces traces)16     Base::Base(SourceSpan pstate, sass::string msg, Backtraces traces)
17     : std::runtime_error(msg.c_str()), msg(msg),
18       prefix("Error"), pstate(pstate), traces(traces)
19     { }
20 
InvalidSass(SourceSpan pstate,Backtraces traces,sass::string msg)21     InvalidSass::InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg)
22     : Base(pstate, msg, traces)
23     { }
24 
25 
InvalidParent(Selector * parent,Backtraces traces,Selector * selector)26     InvalidParent::InvalidParent(Selector* parent, Backtraces traces, Selector* selector)
27     : Base(selector->pstate(), def_msg, traces), parent(parent), selector(selector)
28     {
29       msg = "Invalid parent selector for "
30         "\"" + selector->to_string(Sass_Inspect_Options()) + "\": "
31         "\"" + parent->to_string(Sass_Inspect_Options()) + "\"";
32     }
33 
InvalidVarKwdType(SourceSpan pstate,Backtraces traces,sass::string name,const Argument * arg)34     InvalidVarKwdType::InvalidVarKwdType(SourceSpan pstate, Backtraces traces, sass::string name, const Argument* arg)
35     : Base(pstate, def_msg, traces), name(name), arg(arg)
36     {
37       msg = "Variable keyword argument map must have string keys.\n" +
38         name + " is not a string in " + arg->to_string() + ".";
39     }
40 
InvalidArgumentType(SourceSpan pstate,Backtraces traces,sass::string fn,sass::string arg,sass::string type,const Value * value)41     InvalidArgumentType::InvalidArgumentType(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string type, const Value* value)
42     : Base(pstate, def_msg, traces), fn(fn), arg(arg), type(type), value(value)
43     {
44       msg = arg + ": \"";
45       if (value) msg += value->to_string(Sass_Inspect_Options());
46       msg += "\" is not a " + type + " for `" + fn + "'";
47     }
48 
MissingArgument(SourceSpan pstate,Backtraces traces,sass::string fn,sass::string arg,sass::string fntype)49     MissingArgument::MissingArgument(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string fntype)
50     : Base(pstate, def_msg, traces), fn(fn), arg(arg), fntype(fntype)
51     {
52       msg = fntype + " " + fn + " is missing argument " + arg + ".";
53     }
54 
InvalidSyntax(SourceSpan pstate,Backtraces traces,sass::string msg)55     InvalidSyntax::InvalidSyntax(SourceSpan pstate, Backtraces traces, sass::string msg)
56     : Base(pstate, msg, traces)
57     { }
58 
NestingLimitError(SourceSpan pstate,Backtraces traces,sass::string msg)59     NestingLimitError::NestingLimitError(SourceSpan pstate, Backtraces traces, sass::string msg)
60     : Base(pstate, msg, traces)
61     { }
62 
DuplicateKeyError(Backtraces traces,const Map & dup,const Expression & org)63     DuplicateKeyError::DuplicateKeyError(Backtraces traces, const Map& dup, const Expression& org)
64     : Base(org.pstate(), def_msg, traces), dup(dup), org(org)
65     {
66       msg = "Duplicate key " + dup.get_duplicate_key()->inspect() + " in map (" + org.inspect() + ").";
67     }
68 
TypeMismatch(Backtraces traces,const Expression & var,const sass::string type)69     TypeMismatch::TypeMismatch(Backtraces traces, const Expression& var, const sass::string type)
70     : Base(var.pstate(), def_msg, traces), var(var), type(type)
71     {
72       msg = var.to_string() + " is not an " + type + ".";
73     }
74 
InvalidValue(Backtraces traces,const Expression & val)75     InvalidValue::InvalidValue(Backtraces traces, const Expression& val)
76     : Base(val.pstate(), def_msg, traces), val(val)
77     {
78       msg = val.to_string() + " isn't a valid CSS value.";
79     }
80 
StackError(Backtraces traces,const AST_Node & node)81     StackError::StackError(Backtraces traces, const AST_Node& node)
82     : Base(node.pstate(), def_msg, traces), node(node)
83     {
84       msg = "stack level too deep";
85     }
86 
EndlessExtendError(Backtraces traces,const AST_Node & node)87     EndlessExtendError::EndlessExtendError(Backtraces traces, const AST_Node& node)
88       : Base(node.pstate(), def_msg, traces), node(node)
89     {
90       msg = "Extend is creating an absurdly big selector, aborting!";
91     }
92 
IncompatibleUnits(const Units & lhs,const Units & rhs)93     IncompatibleUnits::IncompatibleUnits(const Units& lhs, const Units& rhs)
94     {
95       msg = "Incompatible units: '" + rhs.unit() + "' and '" + lhs.unit() + "'.";
96     }
97 
IncompatibleUnits(const UnitType lhs,const UnitType rhs)98     IncompatibleUnits::IncompatibleUnits(const UnitType lhs, const UnitType rhs)
99     {
100       msg = sass::string("Incompatible units: '") + unit_to_string(rhs) + "' and '" + unit_to_string(lhs) + "'.";
101     }
102 
AlphaChannelsNotEqual(const Expression * lhs,const Expression * rhs,enum Sass_OP op)103     AlphaChannelsNotEqual::AlphaChannelsNotEqual(const Expression* lhs, const Expression* rhs, enum Sass_OP op)
104     : OperationError(), lhs(lhs), rhs(rhs), op(op)
105     {
106       msg = "Alpha channels must be equal: " +
107         lhs->to_string({ NESTED, 5 }) +
108         " " + sass_op_to_name(op) + " " +
109         rhs->to_string({ NESTED, 5 }) + ".";
110     }
111 
ZeroDivisionError(const Expression & lhs,const Expression & rhs)112     ZeroDivisionError::ZeroDivisionError(const Expression& lhs, const Expression& rhs)
113     : OperationError(), lhs(lhs), rhs(rhs)
114     {
115       msg = "divided by 0";
116     }
117 
UndefinedOperation(const Expression * lhs,const Expression * rhs,enum Sass_OP op)118     UndefinedOperation::UndefinedOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op)
119     : OperationError(), lhs(lhs), rhs(rhs), op(op)
120     {
121       msg = def_op_msg + ": \"" +
122         lhs->to_string({ NESTED, 5 }) +
123         " " + sass_op_to_name(op) + " " +
124         rhs->to_string({ TO_SASS, 5 }) +
125         "\".";
126     }
127 
InvalidNullOperation(const Expression * lhs,const Expression * rhs,enum Sass_OP op)128     InvalidNullOperation::InvalidNullOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op)
129     : UndefinedOperation(lhs, rhs, op)
130     {
131       msg = def_op_null_msg + ": \"" + lhs->inspect() + " " + sass_op_to_name(op) + " " + rhs->inspect() + "\".";
132     }
133 
SassValueError(Backtraces traces,SourceSpan pstate,OperationError & err)134     SassValueError::SassValueError(Backtraces traces, SourceSpan pstate, OperationError& err)
135     : Base(pstate, err.what(), traces)
136     {
137       msg = err.what();
138       prefix = err.errtype();
139     }
140 
TopLevelParent(Backtraces traces,SourceSpan pstate)141     TopLevelParent::TopLevelParent(Backtraces traces, SourceSpan pstate)
142       : Base(pstate, "Top-level selectors may not contain the parent selector \"&\".", traces)
143     {
144 
145     }
146 
UnsatisfiedExtend(Backtraces traces,Extension extension)147     UnsatisfiedExtend::UnsatisfiedExtend(Backtraces traces, Extension extension)
148       : Base(extension.target->pstate(), "The target selector was not found.\n"
149         "Use \"@extend " + extension.target->to_string() + " !optional\" to avoid this error.", traces)
150     {
151 
152     }
153 
ExtendAcrossMedia(Backtraces traces,Extension extension)154     ExtendAcrossMedia::ExtendAcrossMedia(Backtraces traces, Extension extension)
155       : Base(extension.target->pstate(), "You may not @extend selectors across media queries.\n"
156         "Use \"@extend " + extension.target->to_string() + " !optional\" to avoid this error.", traces)
157     {
158 
159     }
160 
161 
162   }
163 
164 
warn(sass::string msg,SourceSpan pstate)165   void warn(sass::string msg, SourceSpan pstate)
166   {
167     std::cerr << "Warning: " << msg << std::endl;
168   }
169 
warning(sass::string msg,SourceSpan pstate)170   void warning(sass::string msg, SourceSpan pstate)
171   {
172     sass::string cwd(Sass::File::get_cwd());
173     sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));
174     sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));
175     sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));
176 
177     std::cerr << "WARNING on line " << pstate.getLine() << ", column " << pstate.getColumn() << " of " << output_path << ":" << std::endl;
178     std::cerr << msg << std::endl << std::endl;
179   }
180 
warn(sass::string msg,SourceSpan pstate,Backtrace * bt)181   void warn(sass::string msg, SourceSpan pstate, Backtrace* bt)
182   {
183     warn(msg, pstate);
184   }
185 
deprecated_function(sass::string msg,SourceSpan pstate)186   void deprecated_function(sass::string msg, SourceSpan pstate)
187   {
188     sass::string cwd(Sass::File::get_cwd());
189     sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));
190     sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));
191     sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));
192 
193     std::cerr << "DEPRECATION WARNING: " << msg << std::endl;
194     std::cerr << "will be an error in future versions of Sass." << std::endl;
195     std::cerr << "        on line " << pstate.getLine() << " of " << output_path << std::endl;
196   }
197 
deprecated(sass::string msg,sass::string msg2,bool with_column,SourceSpan pstate)198   void deprecated(sass::string msg, sass::string msg2, bool with_column, SourceSpan pstate)
199   {
200     sass::string cwd(Sass::File::get_cwd());
201     sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));
202     sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));
203     sass::string output_path(Sass::File::path_for_console(rel_path, pstate.getPath(), pstate.getPath()));
204 
205     std::cerr << "DEPRECATION WARNING on line " << pstate.getLine();
206     // if (with_column) std::cerr << ", column " << pstate.column + pstate.offset.column + 1;
207     if (output_path.length()) std::cerr << " of " << output_path;
208     std::cerr << ":" << std::endl;
209     std::cerr << msg << std::endl;
210     if (msg2.length()) std::cerr << msg2 << std::endl;
211     std::cerr << std::endl;
212   }
213 
deprecated_bind(sass::string msg,SourceSpan pstate)214   void deprecated_bind(sass::string msg, SourceSpan pstate)
215   {
216     sass::string cwd(Sass::File::get_cwd());
217     sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));
218     sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));
219     sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));
220 
221     std::cerr << "WARNING: " << msg << std::endl;
222     std::cerr << "        on line " << pstate.getLine() << " of " << output_path << std::endl;
223     std::cerr << "This will be an error in future versions of Sass." << std::endl;
224   }
225 
226   // should be replaced with error with backtraces
coreError(sass::string msg,SourceSpan pstate)227   void coreError(sass::string msg, SourceSpan pstate)
228   {
229     Backtraces traces;
230     throw Exception::InvalidSyntax(pstate, traces, msg);
231   }
232 
error(sass::string msg,SourceSpan pstate,Backtraces & traces)233   void error(sass::string msg, SourceSpan pstate, Backtraces& traces)
234   {
235     traces.push_back(Backtrace(pstate));
236     throw Exception::InvalidSyntax(pstate, traces, msg);
237   }
238 
239 }
240