sassc 1.8.1 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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();
|