sassc 1.8.1 → 1.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/ext/libsass/Makefile +10 -6
- data/ext/libsass/Readme.md +4 -4
- data/ext/libsass/appveyor.yml +16 -1
- data/ext/libsass/docs/README.md +1 -1
- data/ext/libsass/docs/api-context-example.md +1 -1
- data/ext/libsass/docs/api-context.md +1 -1
- data/ext/libsass/docs/api-doc.md +1 -1
- data/ext/libsass/docs/api-function-example.md +12 -3
- data/ext/libsass/docs/api-function-internal.md +4 -4
- data/ext/libsass/docs/api-function.md +15 -13
- data/ext/libsass/docs/api-importer-internal.md +9 -4
- data/ext/libsass/docs/api-value.md +1 -1
- data/ext/libsass/docs/build-shared-library.md +3 -3
- data/ext/libsass/docs/custom-functions-internal.md +1 -1
- data/ext/libsass/docs/{plugins.go → plugins.md} +0 -0
- data/ext/libsass/script/ci-build-libsass +25 -36
- data/ext/libsass/script/ci-install-deps +3 -8
- data/ext/libsass/script/ci-report-coverage +17 -13
- data/ext/libsass/src/ast.cpp +102 -7
- data/ext/libsass/src/ast.hpp +53 -27
- data/ext/libsass/src/ast_def_macros.hpp +8 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +3 -2
- data/ext/libsass/src/backtrace.hpp +1 -1
- data/ext/libsass/src/bind.cpp +28 -17
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/context.cpp +441 -184
- data/ext/libsass/src/context.hpp +79 -82
- data/ext/libsass/src/debugger.hpp +3 -1
- data/ext/libsass/src/emitter.cpp +18 -17
- data/ext/libsass/src/emitter.hpp +5 -2
- data/ext/libsass/src/error_handling.cpp +78 -7
- data/ext/libsass/src/error_handling.hpp +50 -9
- data/ext/libsass/src/eval.cpp +100 -36
- data/ext/libsass/src/eval.hpp +5 -5
- data/ext/libsass/src/expand.cpp +32 -3
- data/ext/libsass/src/extend.cpp +1 -1
- data/ext/libsass/src/file.cpp +39 -27
- data/ext/libsass/src/file.hpp +67 -13
- data/ext/libsass/src/functions.cpp +39 -32
- data/ext/libsass/src/inspect.cpp +21 -21
- data/ext/libsass/src/json.cpp +1 -1
- data/ext/libsass/src/lexer.hpp +33 -4
- data/ext/libsass/src/output.cpp +11 -11
- data/ext/libsass/src/parser.cpp +28 -130
- data/ext/libsass/src/parser.hpp +0 -4
- data/ext/libsass/src/prelexer.cpp +8 -5
- data/ext/libsass/src/prelexer.hpp +1 -3
- data/ext/libsass/src/sass_context.cpp +52 -241
- data/ext/libsass/src/sass_context.hpp +156 -0
- data/ext/libsass/src/sass_functions.cpp +1 -26
- data/ext/libsass/src/sass_functions.hpp +32 -0
- data/ext/libsass/src/sass_interface.cpp +14 -48
- data/ext/libsass/src/sass_values.cpp +3 -77
- data/ext/libsass/src/sass_values.hpp +81 -0
- data/ext/libsass/src/source_map.cpp +7 -7
- data/ext/libsass/src/source_map.hpp +1 -4
- data/ext/libsass/src/to_string.cpp +4 -3
- data/ext/libsass/src/to_string.hpp +2 -1
- data/ext/libsass/src/util.cpp +34 -16
- data/ext/libsass/src/util.hpp +10 -8
- data/lib/sassc/version.rb +1 -1
- data/lib/tasks/libsass.rb +1 -1
- data/test/custom_importer_test.rb +6 -4
- data/test/engine_test.rb +5 -3
- data/test/functions_test.rb +1 -0
- data/test/native_test.rb +1 -1
- metadata +6 -4
- data/ext/libsass/script/coveralls-debug +0 -32
@@ -2,28 +2,69 @@
|
|
2
2
|
#define SASS_ERROR_HANDLING_H
|
3
3
|
|
4
4
|
#include <string>
|
5
|
-
|
5
|
+
#include <sstream>
|
6
|
+
#include <stdexcept>
|
6
7
|
#include "position.hpp"
|
7
8
|
|
8
9
|
namespace Sass {
|
9
10
|
|
10
11
|
struct Backtrace;
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
namespace Exception {
|
14
|
+
|
15
|
+
const std::string def_msg = "Invalid sass";
|
16
|
+
|
17
|
+
class Base : public std::runtime_error {
|
18
|
+
protected:
|
19
|
+
std::string msg;
|
20
|
+
public:
|
21
|
+
ParserState pstate;
|
22
|
+
public:
|
23
|
+
Base(ParserState pstate, std::string msg = def_msg);
|
24
|
+
virtual const char* what() const throw();
|
25
|
+
virtual ~Base() throw() {};
|
26
|
+
};
|
27
|
+
|
28
|
+
class InvalidSass : public Base {
|
29
|
+
public:
|
30
|
+
InvalidSass(ParserState pstate, std::string msg);
|
31
|
+
virtual ~InvalidSass() throw() {};
|
32
|
+
};
|
33
|
+
|
34
|
+
class InvalidParent : public Base {
|
35
|
+
protected:
|
36
|
+
Selector* parent;
|
37
|
+
Selector* selector;
|
38
|
+
public:
|
39
|
+
InvalidParent(Selector* parent, Selector* selector);
|
40
|
+
virtual ~InvalidParent() throw() {};
|
41
|
+
};
|
14
42
|
|
15
|
-
|
16
|
-
|
17
|
-
|
43
|
+
class InvalidArgumentType : public Base {
|
44
|
+
protected:
|
45
|
+
std::string fn;
|
46
|
+
std::string arg;
|
47
|
+
std::string type;
|
48
|
+
const Value* value;
|
49
|
+
public:
|
50
|
+
InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value* value = 0);
|
51
|
+
virtual ~InvalidArgumentType() throw() {};
|
52
|
+
};
|
18
53
|
|
19
|
-
|
54
|
+
class InvalidSyntax : public Base {
|
55
|
+
public:
|
56
|
+
InvalidSyntax(ParserState pstate, std::string msg);
|
57
|
+
virtual ~InvalidSyntax() throw() {};
|
58
|
+
};
|
20
59
|
|
21
|
-
}
|
60
|
+
}
|
22
61
|
|
23
62
|
void warn(std::string msg, ParserState pstate);
|
24
63
|
void warn(std::string msg, ParserState pstate, Backtrace* bt);
|
25
64
|
|
26
|
-
void
|
65
|
+
void deprecated_function(std::string msg, ParserState pstate);
|
66
|
+
void deprecated(std::string msg, std::string msg2, ParserState pstate);
|
67
|
+
void deprecated_bind(std::string msg, ParserState pstate);
|
27
68
|
// void deprecated(std::string msg, ParserState pstate, Backtrace* bt);
|
28
69
|
|
29
70
|
void error(std::string msg, ParserState pstate);
|
data/ext/libsass/src/eval.cpp
CHANGED
@@ -378,7 +378,7 @@ namespace Sass {
|
|
378
378
|
Expression* Eval::operator()(Debug* d)
|
379
379
|
{
|
380
380
|
Expression* message = d->value()->perform(this);
|
381
|
-
To_String to_string(&ctx);
|
381
|
+
To_String to_string(&ctx, false, true);
|
382
382
|
Env* env = exp.environment();
|
383
383
|
|
384
384
|
// try to use generic function
|
@@ -400,10 +400,13 @@ namespace Sass {
|
|
400
400
|
|
401
401
|
}
|
402
402
|
|
403
|
-
std::string cwd(ctx.
|
403
|
+
std::string cwd(ctx.cwd());
|
404
404
|
std::string result(unquote(message->perform(&to_string)));
|
405
|
-
std::string
|
406
|
-
std::
|
405
|
+
std::string abs_path(Sass::File::rel2abs(d->pstate().path, cwd, cwd));
|
406
|
+
std::string rel_path(Sass::File::abs2rel(d->pstate().path, cwd, cwd));
|
407
|
+
std::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().path));
|
408
|
+
|
409
|
+
std::cerr << output_path << ":" << d->pstate().line+1 << " DEBUG: " << result;
|
407
410
|
std::cerr << std::endl;
|
408
411
|
return 0;
|
409
412
|
}
|
@@ -446,7 +449,7 @@ namespace Sass {
|
|
446
449
|
// check the evaluated keys aren't duplicates.
|
447
450
|
if (mm->has_duplicate_key()) {
|
448
451
|
To_String to_string(&ctx);
|
449
|
-
error("Duplicate key \"" + mm->get_duplicate_key()->perform(&to_string) + "\" in map " +
|
452
|
+
error("Duplicate key \"" + mm->get_duplicate_key()->perform(&to_string) + "\" in map " + m->perform(&to_string) + ".", mm->pstate());
|
450
453
|
}
|
451
454
|
|
452
455
|
mm->is_expanded(true);
|
@@ -462,7 +465,11 @@ namespace Sass {
|
|
462
465
|
// if one of the operands is a '/' then make sure it's evaluated
|
463
466
|
Expression* lhs = b->left()->perform(this);
|
464
467
|
lhs->is_delayed(false);
|
465
|
-
while (typeid(*lhs) == typeid(Binary_Expression))
|
468
|
+
while (typeid(*lhs) == typeid(Binary_Expression)) {
|
469
|
+
Binary_Expression* lhs_ex = static_cast<Binary_Expression*>(lhs);
|
470
|
+
if (lhs_ex->type() == Sass_OP::DIV && lhs_ex->is_delayed()) break;
|
471
|
+
lhs = Eval::operator()(lhs_ex);
|
472
|
+
}
|
466
473
|
|
467
474
|
switch (op_type) {
|
468
475
|
case Sass_OP::AND:
|
@@ -520,36 +527,86 @@ namespace Sass {
|
|
520
527
|
default: break;
|
521
528
|
}
|
522
529
|
|
530
|
+
|
523
531
|
Expression::Concrete_Type l_type = lhs->concrete_type();
|
524
532
|
Expression::Concrete_Type r_type = rhs->concrete_type();
|
525
533
|
|
526
|
-
|
527
|
-
|
534
|
+
// Is one of the operands an interpolant?
|
535
|
+
String_Schema* s1 = dynamic_cast<String_Schema*>(b->left());
|
536
|
+
String_Schema* s2 = dynamic_cast<String_Schema*>(b->right());
|
537
|
+
|
538
|
+
if ((s1 && s1->has_interpolants()) || (s2 && s2->has_interpolants())) {
|
539
|
+
std::string sep;
|
540
|
+
switch (op_type) {
|
541
|
+
case Sass_OP::SUB: sep = "-"; break;
|
542
|
+
case Sass_OP::DIV: sep = "/"; break;
|
543
|
+
case Sass_OP::ADD: sep = "+"; break;
|
544
|
+
case Sass_OP::MUL: sep = "*"; break;
|
545
|
+
default: break;
|
546
|
+
}
|
547
|
+
|
548
|
+
// If possible upgrade LHS to a number
|
549
|
+
if (op_type == Sass_OP::DIV || op_type == Sass_OP::MUL || op_type == Sass_OP::ADD || op_type == Sass_OP::SUB) {
|
550
|
+
if (String_Constant* str = dynamic_cast<String_Constant*>(lhs)) {
|
551
|
+
std::string value(str->value());
|
552
|
+
const char* start = value.c_str();
|
553
|
+
if (Prelexer::sequence < Prelexer::number >(start) != 0) {
|
554
|
+
lhs = SASS_MEMORY_NEW(ctx.mem, Textual, lhs->pstate(), Textual::DIMENSION, str->value());
|
555
|
+
lhs->is_delayed(false); lhs = lhs->perform(this);
|
556
|
+
}
|
557
|
+
}
|
558
|
+
if (String_Constant* str = dynamic_cast<String_Constant*>(rhs)) {
|
559
|
+
std::string value(str->value());
|
560
|
+
const char* start = value.c_str();
|
561
|
+
if (Prelexer::sequence < Prelexer::number >(start) != 0) {
|
562
|
+
rhs = SASS_MEMORY_NEW(ctx.mem, Textual, rhs->pstate(), Textual::DIMENSION, str->value());
|
563
|
+
rhs->is_delayed(false); rhs = rhs->perform(this);
|
564
|
+
}
|
565
|
+
}
|
566
|
+
}
|
567
|
+
|
568
|
+
To_Value to_value(ctx, ctx.mem);
|
569
|
+
Value* v_l = dynamic_cast<Value*>(lhs->perform(&to_value));
|
570
|
+
Value* v_r = dynamic_cast<Value*>(rhs->perform(&to_value));
|
571
|
+
Expression::Concrete_Type l_type = lhs->concrete_type();
|
572
|
+
Expression::Concrete_Type r_type = rhs->concrete_type();
|
573
|
+
|
574
|
+
if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
|
575
|
+
return SASS_MEMORY_NEW(ctx.mem, String_Constant, lhs->pstate(),
|
576
|
+
v_l->to_string() + " " + sep + " " + v_r->to_string());
|
577
|
+
}
|
578
|
+
}
|
579
|
+
|
580
|
+
// ToDo: throw error in op functions
|
581
|
+
// ToDo: then catch and re-throw them
|
582
|
+
ParserState pstate(b->pstate());
|
583
|
+
int precision = (int)ctx.c_options->precision;
|
584
|
+
bool compressed = ctx.output_style() == SASS_STYLE_COMPRESSED;
|
528
585
|
if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
|
529
586
|
const Number* l_n = dynamic_cast<const Number*>(lhs);
|
530
587
|
const Number* r_n = dynamic_cast<const Number*>(rhs);
|
531
|
-
return op_numbers(ctx.mem, op_type, *l_n, *r_n, compressed, precision);
|
588
|
+
return op_numbers(ctx.mem, op_type, *l_n, *r_n, compressed, precision, &pstate);
|
532
589
|
}
|
533
590
|
if (l_type == Expression::NUMBER && r_type == Expression::COLOR) {
|
534
591
|
const Number* l_n = dynamic_cast<const Number*>(lhs);
|
535
592
|
const Color* r_c = dynamic_cast<const Color*>(rhs);
|
536
|
-
return op_number_color(ctx.mem, op_type, *l_n, *r_c, compressed, precision);
|
593
|
+
return op_number_color(ctx.mem, op_type, *l_n, *r_c, compressed, precision, &pstate);
|
537
594
|
}
|
538
595
|
if (l_type == Expression::COLOR && r_type == Expression::NUMBER) {
|
539
596
|
const Color* l_c = dynamic_cast<const Color*>(lhs);
|
540
597
|
const Number* r_n = dynamic_cast<const Number*>(rhs);
|
541
|
-
return op_color_number(ctx.mem, op_type, *l_c, *r_n, compressed, precision);
|
598
|
+
return op_color_number(ctx.mem, op_type, *l_c, *r_n, compressed, precision, &pstate);
|
542
599
|
}
|
543
600
|
if (l_type == Expression::COLOR && r_type == Expression::COLOR) {
|
544
601
|
const Color* l_c = dynamic_cast<const Color*>(lhs);
|
545
602
|
const Color* r_c = dynamic_cast<const Color*>(rhs);
|
546
|
-
return op_colors(ctx.mem, op_type, *l_c, *r_c, compressed, precision);
|
603
|
+
return op_colors(ctx.mem, op_type, *l_c, *r_c, compressed, precision, &pstate);
|
547
604
|
}
|
548
605
|
|
549
606
|
To_Value to_value(ctx, ctx.mem);
|
550
607
|
Value* v_l = dynamic_cast<Value*>(lhs->perform(&to_value));
|
551
608
|
Value* v_r = dynamic_cast<Value*>(rhs->perform(&to_value));
|
552
|
-
Value* ex = op_strings(ctx.mem, op_type, *v_l, *v_r, compressed, precision);
|
609
|
+
Value* ex = op_strings(ctx.mem, op_type, *v_l, *v_r, compressed, precision, &pstate);
|
553
610
|
if (String_Constant* str = dynamic_cast<String_Constant*>(ex))
|
554
611
|
{
|
555
612
|
if (str->concrete_type() != Expression::STRING) return ex;
|
@@ -651,14 +708,14 @@ namespace Sass {
|
|
651
708
|
exp.env_stack.push_back(&fn_env);
|
652
709
|
|
653
710
|
if (func || body) {
|
654
|
-
bind("
|
711
|
+
bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
|
655
712
|
Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
|
656
713
|
exp.backtrace_stack.push_back(&here);
|
657
714
|
// if it's user-defined, eval the body
|
658
715
|
if (body) result = body->perform(this);
|
659
716
|
// if it's native, invoke the underlying CPP function
|
660
717
|
else result = func(fn_env, *env, ctx, def->signature(), c->pstate(), backtrace());
|
661
|
-
if (!result) error(std::string("
|
718
|
+
if (!result) error(std::string("Function ") + c->name() + " did not return a value", c->pstate());
|
662
719
|
exp.backtrace_stack.pop_back();
|
663
720
|
}
|
664
721
|
|
@@ -675,7 +732,8 @@ namespace Sass {
|
|
675
732
|
}
|
676
733
|
|
677
734
|
// populates env with default values for params
|
678
|
-
|
735
|
+
std::string ff(c->name());
|
736
|
+
bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
|
679
737
|
|
680
738
|
Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
|
681
739
|
exp.backtrace_stack.push_back(&here);
|
@@ -897,7 +955,7 @@ namespace Sass {
|
|
897
955
|
} else if (List* list = dynamic_cast<List*>(s)) {
|
898
956
|
std::string acc = ""; // ToDo: different output styles
|
899
957
|
std::string sep = list->separator() == SASS_COMMA ? "," : " ";
|
900
|
-
if (ctx.output_style !=
|
958
|
+
if (ctx.output_style() != SASS_STYLE_COMPRESSED && sep == ",") sep += " ";
|
901
959
|
bool initial = false;
|
902
960
|
for(auto item : list->elements()) {
|
903
961
|
if (item->concrete_type() != Expression::NULL_VAL) {
|
@@ -914,10 +972,16 @@ namespace Sass {
|
|
914
972
|
return evacuate_quotes(interpolation(value));
|
915
973
|
} else if (dynamic_cast<Binary_Expression*>(s)) {
|
916
974
|
Expression* ex = s->perform(this);
|
975
|
+
// avoid recursive calls if same object gets returned
|
976
|
+
// since we will call interpolate again for the result
|
977
|
+
if (ex == s) {
|
978
|
+
To_String to_string(&ctx);
|
979
|
+
return evacuate_quotes(s->perform(&to_string));
|
980
|
+
}
|
917
981
|
return evacuate_quotes(interpolation(ex));
|
918
982
|
} else if (dynamic_cast<Function_Call*>(s)) {
|
919
983
|
Expression* ex = s->perform(this);
|
920
|
-
return evacuate_quotes(interpolation(ex));
|
984
|
+
return evacuate_quotes(unquote(interpolation(ex)));
|
921
985
|
} else if (dynamic_cast<Unary_Expression*>(s)) {
|
922
986
|
Expression* ex = s->perform(this);
|
923
987
|
return evacuate_quotes(interpolation(ex));
|
@@ -1160,15 +1224,15 @@ namespace Sass {
|
|
1160
1224
|
return *l < *r;
|
1161
1225
|
}
|
1162
1226
|
|
1163
|
-
Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, bool compressed, int precision)
|
1227
|
+
Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, bool compressed, int precision, ParserState* pstate)
|
1164
1228
|
{
|
1165
1229
|
double lv = l.value();
|
1166
1230
|
double rv = r.value();
|
1167
1231
|
if (op == Sass_OP::DIV && !rv) {
|
1168
|
-
return SASS_MEMORY_NEW(mem, String_Quoted, l.pstate(), "Infinity");
|
1232
|
+
return SASS_MEMORY_NEW(mem, String_Quoted, pstate ? *pstate : l.pstate(), "Infinity");
|
1169
1233
|
}
|
1170
1234
|
if (op == Sass_OP::MOD && !rv) {
|
1171
|
-
error("division by zero", r.pstate());
|
1235
|
+
error("division by zero", pstate ? *pstate : r.pstate());
|
1172
1236
|
}
|
1173
1237
|
|
1174
1238
|
Number tmp(r);
|
@@ -1178,10 +1242,10 @@ namespace Sass {
|
|
1178
1242
|
std::string r_unit(tmp.unit());
|
1179
1243
|
if (l_unit != r_unit && !l_unit.empty() && !r_unit.empty() &&
|
1180
1244
|
(op == Sass_OP::ADD || op == Sass_OP::SUB)) {
|
1181
|
-
error("Incompatible units: '"+r_unit+"' and '"+l_unit+"'.",
|
1245
|
+
error("Incompatible units: '"+r_unit+"' and '"+l_unit+"'.", pstate ? *pstate : r.pstate());
|
1182
1246
|
}
|
1183
1247
|
Number* v = SASS_MEMORY_NEW(mem, Number, l);
|
1184
|
-
v->pstate(l.pstate());
|
1248
|
+
v->pstate(pstate ? *pstate : l.pstate());
|
1185
1249
|
if (l_unit.empty() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) {
|
1186
1250
|
v->numerator_units() = r.numerator_units();
|
1187
1251
|
v->denominator_units() = r.denominator_units();
|
@@ -1211,7 +1275,7 @@ namespace Sass {
|
|
1211
1275
|
return v;
|
1212
1276
|
}
|
1213
1277
|
|
1214
|
-
Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, bool compressed, int precision)
|
1278
|
+
Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, bool compressed, int precision, ParserState* pstate)
|
1215
1279
|
{
|
1216
1280
|
Color r(rh);
|
1217
1281
|
r.disp("");
|
@@ -1220,7 +1284,7 @@ namespace Sass {
|
|
1220
1284
|
case Sass_OP::ADD:
|
1221
1285
|
case Sass_OP::MUL: {
|
1222
1286
|
return SASS_MEMORY_NEW(mem, Color,
|
1223
|
-
l.pstate(),
|
1287
|
+
pstate ? *pstate : l.pstate(),
|
1224
1288
|
ops[op](lv, r.r()),
|
1225
1289
|
ops[op](lv, r.g()),
|
1226
1290
|
ops[op](lv, r.b()),
|
@@ -1231,13 +1295,13 @@ namespace Sass {
|
|
1231
1295
|
std::string sep(op == Sass_OP::SUB ? "-" : "/");
|
1232
1296
|
std::string color(r.to_string(compressed||!r.sixtuplet(), precision));
|
1233
1297
|
return SASS_MEMORY_NEW(mem, String_Quoted,
|
1234
|
-
l.pstate(),
|
1298
|
+
pstate ? *pstate : l.pstate(),
|
1235
1299
|
l.to_string(compressed, precision)
|
1236
1300
|
+ sep
|
1237
1301
|
+ color);
|
1238
1302
|
} break;
|
1239
1303
|
case Sass_OP::MOD: {
|
1240
|
-
error("cannot divide a number by a color", r.pstate());
|
1304
|
+
error("cannot divide a number by a color", pstate ? *pstate : r.pstate());
|
1241
1305
|
} break;
|
1242
1306
|
default: break; // caller should ensure that we don't get here
|
1243
1307
|
}
|
@@ -1245,35 +1309,35 @@ namespace Sass {
|
|
1245
1309
|
return SASS_MEMORY_NEW(mem, Color, rh);
|
1246
1310
|
}
|
1247
1311
|
|
1248
|
-
Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, bool compressed, int precision)
|
1312
|
+
Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, bool compressed, int precision, ParserState* pstate)
|
1249
1313
|
{
|
1250
1314
|
double rv = r.value();
|
1251
|
-
if (op == Sass_OP::DIV && !rv) error("division by zero", r.pstate());
|
1315
|
+
if (op == Sass_OP::DIV && !rv) error("division by zero", pstate ? *pstate : r.pstate());
|
1252
1316
|
return SASS_MEMORY_NEW(mem, Color,
|
1253
|
-
l.pstate(),
|
1317
|
+
pstate ? *pstate : l.pstate(),
|
1254
1318
|
ops[op](l.r(), rv),
|
1255
1319
|
ops[op](l.g(), rv),
|
1256
1320
|
ops[op](l.b(), rv),
|
1257
1321
|
l.a());
|
1258
1322
|
}
|
1259
1323
|
|
1260
|
-
Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, bool compressed, int precision)
|
1324
|
+
Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, bool compressed, int precision, ParserState* pstate)
|
1261
1325
|
{
|
1262
1326
|
if (l.a() != r.a()) {
|
1263
|
-
error("alpha channels must be equal when combining colors", r.pstate());
|
1327
|
+
error("alpha channels must be equal when combining colors", pstate ? *pstate : r.pstate());
|
1264
1328
|
}
|
1265
1329
|
if (op == Sass_OP::DIV && (!r.r() || !r.g() ||!r.b())) {
|
1266
|
-
error("division by zero", r.pstate());
|
1330
|
+
error("division by zero", pstate ? *pstate : r.pstate());
|
1267
1331
|
}
|
1268
1332
|
return SASS_MEMORY_NEW(mem, Color,
|
1269
|
-
l.pstate(),
|
1333
|
+
pstate ? *pstate : l.pstate(),
|
1270
1334
|
ops[op](l.r(), r.r()),
|
1271
1335
|
ops[op](l.g(), r.g()),
|
1272
1336
|
ops[op](l.b(), r.b()),
|
1273
1337
|
l.a());
|
1274
1338
|
}
|
1275
1339
|
|
1276
|
-
Value* Eval::op_strings(Memory_Manager& mem, enum Sass_OP op, Value& lhs, Value& rhs, bool compressed, int precision)
|
1340
|
+
Value* Eval::op_strings(Memory_Manager& mem, enum Sass_OP op, Value& lhs, Value& rhs, bool compressed, int precision, ParserState* pstate)
|
1277
1341
|
{
|
1278
1342
|
Expression::Concrete_Type ltype = lhs.concrete_type();
|
1279
1343
|
Expression::Concrete_Type rtype = rhs.concrete_type();
|
@@ -1320,7 +1384,7 @@ namespace Sass {
|
|
1320
1384
|
switch (op) {
|
1321
1385
|
case Sass_OP::SUB: sep = "-"; break;
|
1322
1386
|
case Sass_OP::DIV: sep = "/"; break;
|
1323
|
-
default:
|
1387
|
+
default: break;
|
1324
1388
|
}
|
1325
1389
|
if (ltype == Expression::NULL_VAL) error("Invalid null operation: \"null plus "+quote(unquote(rstr), '"')+"\".", lhs.pstate());
|
1326
1390
|
if (rtype == Expression::NULL_VAL) error("Invalid null operation: \""+quote(unquote(lstr), '"')+" plus null\".", rhs.pstate());
|
data/ext/libsass/src/eval.hpp
CHANGED
@@ -89,11 +89,11 @@ namespace Sass {
|
|
89
89
|
static bool eq(Expression*, Expression*);
|
90
90
|
static bool lt(Expression*, Expression*);
|
91
91
|
// -- arithmetic on the combinations that matter
|
92
|
-
static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, bool compressed = false, int precision = 5);
|
93
|
-
static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, bool compressed = false, int precision = 5);
|
94
|
-
static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, bool compressed = false, int precision = 5);
|
95
|
-
static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, bool compressed = false, int precision = 5);
|
96
|
-
static Value* op_strings(Memory_Manager&, enum Sass_OP, Value&, Value&, bool compressed = false, int precision = 5);
|
92
|
+
static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
|
93
|
+
static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
|
94
|
+
static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
|
95
|
+
static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
|
96
|
+
static Value* op_strings(Memory_Manager&, enum Sass_OP, Value&, Value&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
|
97
97
|
|
98
98
|
private:
|
99
99
|
std::string interpolation(Expression* s, bool into_quotes = false);
|
data/ext/libsass/src/expand.cpp
CHANGED
@@ -28,6 +28,7 @@ namespace Sass {
|
|
28
28
|
env_stack.push_back(0);
|
29
29
|
env_stack.push_back(env);
|
30
30
|
block_stack.push_back(0);
|
31
|
+
// import_stack.push_back(0);
|
31
32
|
property_stack.push_back(0);
|
32
33
|
selector_stack.push_back(0);
|
33
34
|
backtrace_stack.push_back(0);
|
@@ -303,19 +304,31 @@ namespace Sass {
|
|
303
304
|
Statement* Expand::operator()(Import* imp)
|
304
305
|
{
|
305
306
|
Import* result = SASS_MEMORY_NEW(ctx.mem, Import, imp->pstate());
|
306
|
-
if (imp->media_queries()) {
|
307
|
+
if (imp->media_queries() && imp->media_queries()->size()) {
|
307
308
|
Expression* ex = imp->media_queries()->perform(&eval);
|
308
309
|
result->media_queries(dynamic_cast<List*>(ex));
|
309
310
|
}
|
310
311
|
for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
|
311
312
|
result->urls().push_back(imp->urls()[i]->perform(&eval));
|
312
313
|
}
|
314
|
+
// all resources have been dropped for Input_Stubs
|
315
|
+
// for ( size_t i = 0, S = imp->incs().size(); i < S; ++i) {}
|
313
316
|
return result;
|
314
317
|
}
|
315
318
|
|
316
319
|
Statement* Expand::operator()(Import_Stub* i)
|
317
320
|
{
|
318
|
-
|
321
|
+
// we don't seem to need that actually afterall
|
322
|
+
Sass_Import_Entry import = sass_make_import(
|
323
|
+
i->imp_path().c_str(),
|
324
|
+
i->abs_path().c_str(),
|
325
|
+
0, 0
|
326
|
+
);
|
327
|
+
ctx.import_stack.push_back(import);
|
328
|
+
const std::string& abs_path(i->resource().abs_path);
|
329
|
+
append_block(ctx.sheets.at(abs_path).root);
|
330
|
+
sass_delete_import(ctx.import_stack.back());
|
331
|
+
ctx.import_stack.pop_back();
|
319
332
|
return 0;
|
320
333
|
}
|
321
334
|
|
@@ -577,6 +590,21 @@ namespace Sass {
|
|
577
590
|
Definition* dd = SASS_MEMORY_NEW(ctx.mem, Definition, *d);
|
578
591
|
env->local_frame()[d->name() +
|
579
592
|
(d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
|
593
|
+
|
594
|
+
if (d->type() == Definition::FUNCTION && (
|
595
|
+
d->name() == "calc" ||
|
596
|
+
d->name() == "element" ||
|
597
|
+
d->name() == "expression" ||
|
598
|
+
d->name() == "url"
|
599
|
+
)) {
|
600
|
+
deprecated(
|
601
|
+
"Naming a function \"" + d->name() + "\" is disallowed",
|
602
|
+
"This name conflicts with an existing CSS function with special parse rules.",
|
603
|
+
d->pstate()
|
604
|
+
);
|
605
|
+
}
|
606
|
+
|
607
|
+
|
580
608
|
// set the static link so we can have lexical scoping
|
581
609
|
dd->environment(env);
|
582
610
|
return 0;
|
@@ -613,7 +641,8 @@ namespace Sass {
|
|
613
641
|
thunk->environment(env);
|
614
642
|
new_env.local_frame()["@content[m]"] = thunk;
|
615
643
|
}
|
616
|
-
|
644
|
+
|
645
|
+
bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval);
|
617
646
|
append_block(body);
|
618
647
|
backtrace_stack.pop_back();
|
619
648
|
env_stack.pop_back();
|