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 | |
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 | |
21 | InvalidSass::InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg) |
22 | : Base(pstate, msg, traces) |
23 | { } |
24 | |
25 | |
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(opt: Sass_Inspect_Options()) + "\": " |
31 | "\"" + parent->to_string(opt: Sass_Inspect_Options()) + "\"" ; |
32 | } |
33 | |
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 | |
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(opt: Sass_Inspect_Options()); |
46 | msg += "\" is not a " + type + " for `" + fn + "'" ; |
47 | } |
48 | |
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 | |
55 | InvalidSyntax::InvalidSyntax(SourceSpan pstate, Backtraces traces, sass::string msg) |
56 | : Base(pstate, msg, traces) |
57 | { } |
58 | |
59 | NestingLimitError::NestingLimitError(SourceSpan pstate, Backtraces traces, sass::string msg) |
60 | : Base(pstate, msg, traces) |
61 | { } |
62 | |
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 | |
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 | |
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 | |
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 | |
87 | IncompatibleUnits::IncompatibleUnits(const Units& lhs, const Units& rhs) |
88 | { |
89 | msg = "Incompatible units: '" + rhs.unit() + "' and '" + lhs.unit() + "'." ; |
90 | } |
91 | |
92 | IncompatibleUnits::IncompatibleUnits(const UnitType lhs, const UnitType rhs) |
93 | { |
94 | msg = sass::string("Incompatible units: '" ) + unit_to_string(unit: rhs) + "' and '" + unit_to_string(unit: lhs) + "'." ; |
95 | } |
96 | |
97 | AlphaChannelsNotEqual::AlphaChannelsNotEqual(const Expression* lhs, const Expression* rhs, enum Sass_OP op) |
98 | : OperationError(), lhs(lhs), rhs(rhs), op(op) |
99 | { |
100 | msg = "Alpha channels must be equal: " + |
101 | lhs->to_string(opt: { NESTED, 5 }) + |
102 | " " + sass_op_to_name(op) + " " + |
103 | rhs->to_string(opt: { NESTED, 5 }) + "." ; |
104 | } |
105 | |
106 | ZeroDivisionError::ZeroDivisionError(const Expression& lhs, const Expression& rhs) |
107 | : OperationError(), lhs(lhs), rhs(rhs) |
108 | { |
109 | msg = "divided by 0" ; |
110 | } |
111 | |
112 | UndefinedOperation::UndefinedOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op) |
113 | : OperationError(), lhs(lhs), rhs(rhs), op(op) |
114 | { |
115 | msg = def_op_msg + ": \"" + |
116 | lhs->to_string(opt: { NESTED, 5 }) + |
117 | " " + sass_op_to_name(op) + " " + |
118 | rhs->to_string(opt: { TO_SASS, 5 }) + |
119 | "\"." ; |
120 | } |
121 | |
122 | InvalidNullOperation::InvalidNullOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op) |
123 | : UndefinedOperation(lhs, rhs, op) |
124 | { |
125 | msg = def_op_null_msg + ": \"" + lhs->inspect() + " " + sass_op_to_name(op) + " " + rhs->inspect() + "\"." ; |
126 | } |
127 | |
128 | SassValueError::SassValueError(Backtraces traces, SourceSpan pstate, OperationError& err) |
129 | : Base(pstate, err.what(), traces) |
130 | { |
131 | msg = err.what(); |
132 | prefix = err.errtype(); |
133 | } |
134 | |
135 | TopLevelParent::TopLevelParent(Backtraces traces, SourceSpan pstate) |
136 | : Base(pstate, "Top-level selectors may not contain the parent selector \"&\"." , traces) |
137 | { |
138 | |
139 | } |
140 | |
141 | UnsatisfiedExtend::UnsatisfiedExtend(Backtraces traces, Extension extension) |
142 | : Base(extension.target->pstate(), "The target selector was not found.\n" |
143 | "Use \"@extend " + extension.target->to_string() + " !optional\" to avoid this error." , traces) |
144 | { |
145 | |
146 | } |
147 | |
148 | ExtendAcrossMedia::ExtendAcrossMedia(Backtraces traces, Extension extension) |
149 | : Base(extension.target->pstate(), "You may not @extend selectors across media queries.\n" |
150 | "Use \"@extend " + extension.target->to_string() + " !optional\" to avoid this error." , traces) |
151 | { |
152 | |
153 | } |
154 | |
155 | |
156 | } |
157 | |
158 | |
159 | void warn(sass::string msg, SourceSpan pstate) |
160 | { |
161 | std::cerr << "Warning: " << msg << std::endl; |
162 | } |
163 | |
164 | void warning(sass::string msg, SourceSpan pstate) |
165 | { |
166 | sass::string cwd(Sass::File::get_cwd()); |
167 | sass::string abs_path(Sass::File::rel2abs(path: pstate.getPath(), base: cwd, cwd)); |
168 | sass::string rel_path(Sass::File::abs2rel(path: pstate.getPath(), base: cwd, cwd)); |
169 | sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, orig_path: pstate.getPath())); |
170 | |
171 | std::cerr << "WARNING on line " << pstate.getLine() << ", column " << pstate.getColumn() << " of " << output_path << ":" << std::endl; |
172 | std::cerr << msg << std::endl << std::endl; |
173 | } |
174 | |
175 | void warn(sass::string msg, SourceSpan pstate, Backtrace* bt) |
176 | { |
177 | warn(msg, pstate); |
178 | } |
179 | |
180 | void deprecated_function(sass::string msg, SourceSpan pstate) |
181 | { |
182 | sass::string cwd(Sass::File::get_cwd()); |
183 | sass::string abs_path(Sass::File::rel2abs(path: pstate.getPath(), base: cwd, cwd)); |
184 | sass::string rel_path(Sass::File::abs2rel(path: pstate.getPath(), base: cwd, cwd)); |
185 | sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, orig_path: pstate.getPath())); |
186 | |
187 | std::cerr << "DEPRECATION WARNING: " << msg << std::endl; |
188 | std::cerr << "will be an error in future versions of Sass." << std::endl; |
189 | std::cerr << " on line " << pstate.getLine() << " of " << output_path << std::endl; |
190 | } |
191 | |
192 | void deprecated(sass::string msg, sass::string msg2, bool with_column, SourceSpan pstate) |
193 | { |
194 | sass::string cwd(Sass::File::get_cwd()); |
195 | sass::string abs_path(Sass::File::rel2abs(path: pstate.getPath(), base: cwd, cwd)); |
196 | sass::string rel_path(Sass::File::abs2rel(path: pstate.getPath(), base: cwd, cwd)); |
197 | sass::string output_path(Sass::File::path_for_console(rel_path, abs_path: pstate.getPath(), orig_path: pstate.getPath())); |
198 | |
199 | std::cerr << "DEPRECATION WARNING on line " << pstate.getLine(); |
200 | // if (with_column) std::cerr << ", column " << pstate.column + pstate.offset.column + 1; |
201 | if (output_path.length()) std::cerr << " of " << output_path; |
202 | std::cerr << ":" << std::endl; |
203 | std::cerr << msg << std::endl; |
204 | if (msg2.length()) std::cerr << msg2 << std::endl; |
205 | std::cerr << std::endl; |
206 | } |
207 | |
208 | void deprecated_bind(sass::string msg, SourceSpan pstate) |
209 | { |
210 | sass::string cwd(Sass::File::get_cwd()); |
211 | sass::string abs_path(Sass::File::rel2abs(path: pstate.getPath(), base: cwd, cwd)); |
212 | sass::string rel_path(Sass::File::abs2rel(path: pstate.getPath(), base: cwd, cwd)); |
213 | sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, orig_path: pstate.getPath())); |
214 | |
215 | std::cerr << "WARNING: " << msg << std::endl; |
216 | std::cerr << " on line " << pstate.getLine() << " of " << output_path << std::endl; |
217 | std::cerr << "This will be an error in future versions of Sass." << std::endl; |
218 | } |
219 | |
220 | // should be replaced with error with backtraces |
221 | void coreError(sass::string msg, SourceSpan pstate) |
222 | { |
223 | Backtraces traces; |
224 | throw Exception::InvalidSyntax(pstate, traces, msg); |
225 | } |
226 | |
227 | void error(sass::string msg, SourceSpan pstate, Backtraces& traces) |
228 | { |
229 | traces.push_back(x: Backtrace(pstate)); |
230 | throw Exception::InvalidSyntax(pstate, traces, msg); |
231 | } |
232 | |
233 | } |
234 | |