sassc 1.11.4 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +2 -2
- data/CODE_OF_CONDUCT.md +10 -0
- data/README.md +4 -1
- data/ext/libsass/.editorconfig +1 -1
- data/ext/libsass/.github/CONTRIBUTING.md +7 -7
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
- data/ext/libsass/.gitignore +3 -0
- data/ext/libsass/.travis.yml +37 -18
- data/ext/libsass/GNUmakefile.am +23 -37
- data/ext/libsass/Makefile +10 -6
- data/ext/libsass/Makefile.conf +3 -0
- data/ext/libsass/Readme.md +68 -63
- data/ext/libsass/appveyor.yml +7 -3
- data/ext/libsass/configure.ac +10 -14
- data/ext/libsass/docs/api-context-internal.md +29 -21
- data/ext/libsass/docs/api-context.md +26 -6
- data/ext/libsass/docs/api-doc.md +49 -16
- data/ext/libsass/docs/api-function-example.md +1 -1
- data/ext/libsass/docs/api-function.md +31 -7
- data/ext/libsass/docs/api-importer.md +19 -19
- data/ext/libsass/docs/api-value.md +4 -2
- data/ext/libsass/docs/build-on-windows.md +4 -4
- data/ext/libsass/docs/build-with-mingw.md +3 -3
- data/ext/libsass/docs/build.md +9 -9
- data/ext/libsass/docs/custom-functions-internal.md +10 -8
- data/ext/libsass/docs/implementations.md +20 -8
- data/ext/libsass/docs/unicode.md +16 -10
- data/ext/libsass/include/sass/base.h +0 -3
- data/ext/libsass/include/sass/context.h +20 -2
- data/ext/libsass/include/sass/functions.h +31 -0
- data/ext/libsass/include/sass/values.h +3 -1
- data/ext/libsass/include/sass/version.h +1 -1
- data/ext/libsass/include/sass/version.h.in +1 -1
- data/ext/libsass/include/sass2scss.h +1 -1
- data/ext/libsass/res/resource.rc +6 -6
- data/ext/libsass/script/ci-build-libsass +10 -5
- data/ext/libsass/script/ci-build-plugin +62 -0
- data/ext/libsass/script/ci-install-compiler +1 -1
- data/ext/libsass/script/ci-install-deps +4 -7
- data/ext/libsass/script/ci-report-coverage +13 -3
- data/ext/libsass/script/tap-driver +1 -1
- data/ext/libsass/script/tap-runner +1 -1
- data/ext/libsass/src/GNUmakefile.am +1 -1
- data/ext/libsass/src/ast.cpp +537 -762
- data/ext/libsass/src/ast.hpp +377 -419
- data/ext/libsass/src/ast_def_macros.hpp +26 -1
- data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
- data/ext/libsass/src/b64/encode.h +3 -1
- data/ext/libsass/src/backtrace.cpp +46 -0
- data/ext/libsass/src/backtrace.hpp +7 -54
- data/ext/libsass/src/bind.cpp +72 -50
- data/ext/libsass/src/bind.hpp +0 -1
- data/ext/libsass/src/cencode.c +6 -0
- data/ext/libsass/src/check_nesting.cpp +157 -135
- data/ext/libsass/src/check_nesting.hpp +11 -10
- data/ext/libsass/src/color_maps.cpp +10 -6
- data/ext/libsass/src/color_maps.hpp +6 -8
- data/ext/libsass/src/constants.cpp +4 -3
- data/ext/libsass/src/constants.hpp +4 -3
- data/ext/libsass/src/context.cpp +110 -47
- data/ext/libsass/src/context.hpp +11 -1
- data/ext/libsass/src/cssize.cpp +105 -94
- data/ext/libsass/src/cssize.hpp +4 -5
- data/ext/libsass/src/debugger.hpp +247 -244
- data/ext/libsass/src/emitter.cpp +30 -6
- data/ext/libsass/src/emitter.hpp +7 -0
- data/ext/libsass/src/environment.cpp +67 -16
- data/ext/libsass/src/environment.hpp +28 -7
- data/ext/libsass/src/error_handling.cpp +92 -64
- data/ext/libsass/src/error_handling.hpp +64 -43
- data/ext/libsass/src/eval.cpp +494 -544
- data/ext/libsass/src/eval.hpp +17 -23
- data/ext/libsass/src/expand.cpp +182 -154
- data/ext/libsass/src/expand.hpp +4 -5
- data/ext/libsass/src/extend.cpp +299 -291
- data/ext/libsass/src/extend.hpp +46 -11
- data/ext/libsass/src/file.cpp +103 -36
- data/ext/libsass/src/file.hpp +21 -4
- data/ext/libsass/src/functions.cpp +561 -312
- data/ext/libsass/src/functions.hpp +8 -5
- data/ext/libsass/src/inspect.cpp +108 -53
- data/ext/libsass/src/inspect.hpp +5 -2
- data/ext/libsass/src/lexer.cpp +15 -7
- data/ext/libsass/src/lexer.hpp +13 -4
- data/ext/libsass/src/listize.cpp +3 -2
- data/ext/libsass/src/listize.hpp +0 -1
- data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
- data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
- data/ext/libsass/src/node.cpp +34 -38
- data/ext/libsass/src/node.hpp +6 -8
- data/ext/libsass/src/operation.hpp +2 -2
- data/ext/libsass/src/operators.cpp +240 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/output.cpp +22 -20
- data/ext/libsass/src/parser.cpp +719 -358
- data/ext/libsass/src/parser.hpp +57 -22
- data/ext/libsass/src/plugins.cpp +28 -10
- data/ext/libsass/src/position.cpp +21 -3
- data/ext/libsass/src/position.hpp +2 -1
- data/ext/libsass/src/prelexer.cpp +104 -19
- data/ext/libsass/src/prelexer.hpp +10 -3
- data/ext/libsass/src/remove_placeholders.cpp +9 -10
- data/ext/libsass/src/remove_placeholders.hpp +1 -5
- data/ext/libsass/src/sass.cpp +62 -4
- data/ext/libsass/src/sass.hpp +5 -2
- data/ext/libsass/src/sass_context.cpp +96 -58
- data/ext/libsass/src/sass_context.hpp +7 -5
- data/ext/libsass/src/sass_functions.cpp +63 -1
- data/ext/libsass/src/sass_functions.hpp +19 -1
- data/ext/libsass/src/sass_util.cpp +3 -3
- data/ext/libsass/src/sass_util.hpp +4 -4
- data/ext/libsass/src/sass_values.cpp +42 -39
- data/ext/libsass/src/sass_values.hpp +2 -1
- data/ext/libsass/src/source_map.cpp +16 -18
- data/ext/libsass/src/subset_map.cpp +6 -8
- data/ext/libsass/src/subset_map.hpp +6 -6
- data/ext/libsass/src/to_c.cpp +2 -2
- data/ext/libsass/src/to_value.cpp +8 -3
- data/ext/libsass/src/to_value.hpp +1 -0
- data/ext/libsass/src/units.cpp +349 -45
- data/ext/libsass/src/units.hpp +39 -22
- data/ext/libsass/src/utf8/checked.h +7 -0
- data/ext/libsass/src/utf8/unchecked.h +7 -0
- data/ext/libsass/src/utf8_string.cpp +1 -1
- data/ext/libsass/src/util.cpp +139 -45
- data/ext/libsass/src/util.hpp +4 -7
- data/ext/libsass/src/values.cpp +15 -23
- data/ext/libsass/win/libsass.sln +13 -2
- data/ext/libsass/win/libsass.sln.DotSettings +9 -0
- data/ext/libsass/win/libsass.targets +3 -0
- data/ext/libsass/win/libsass.vcxproj.filters +9 -0
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +1 -1
- data/test/native_test.rb +1 -1
- metadata +11 -4
data/ext/libsass/src/eval.hpp
CHANGED
@@ -18,16 +18,20 @@ namespace Sass {
|
|
18
18
|
Expression_Ptr fallback_impl(AST_Node_Ptr n);
|
19
19
|
|
20
20
|
public:
|
21
|
-
Expand&
|
21
|
+
Expand& exp;
|
22
22
|
Context& ctx;
|
23
|
+
Backtraces& traces;
|
23
24
|
Eval(Expand& exp);
|
24
25
|
~Eval();
|
25
26
|
|
26
27
|
bool force;
|
27
28
|
bool is_in_comment;
|
29
|
+
bool is_in_selector_schema;
|
30
|
+
|
31
|
+
Boolean_Obj bool_true;
|
32
|
+
Boolean_Obj bool_false;
|
28
33
|
|
29
34
|
Env* environment();
|
30
|
-
Backtrace* backtrace();
|
31
35
|
Selector_List_Obj selector();
|
32
36
|
|
33
37
|
// for evaluating function bodies
|
@@ -49,7 +53,6 @@ namespace Sass {
|
|
49
53
|
Expression_Ptr operator()(Function_Call_Ptr);
|
50
54
|
Expression_Ptr operator()(Function_Call_Schema_Ptr);
|
51
55
|
Expression_Ptr operator()(Variable_Ptr);
|
52
|
-
Expression_Ptr operator()(Textual_Ptr);
|
53
56
|
Expression_Ptr operator()(Number_Ptr);
|
54
57
|
Expression_Ptr operator()(Color_Ptr);
|
55
58
|
Expression_Ptr operator()(Boolean_Ptr);
|
@@ -57,7 +60,7 @@ namespace Sass {
|
|
57
60
|
Expression_Ptr operator()(String_Quoted_Ptr);
|
58
61
|
Expression_Ptr operator()(String_Constant_Ptr);
|
59
62
|
// Expression_Ptr operator()(Selector_List_Ptr);
|
60
|
-
|
63
|
+
Media_Query_Ptr operator()(Media_Query_Ptr);
|
61
64
|
Expression_Ptr operator()(Media_Query_Expression_Ptr);
|
62
65
|
Expression_Ptr operator()(At_Root_Query_Ptr);
|
63
66
|
Expression_Ptr operator()(Supports_Operator_Ptr);
|
@@ -72,14 +75,15 @@ namespace Sass {
|
|
72
75
|
// these will return selectors
|
73
76
|
Selector_List_Ptr operator()(Selector_List_Ptr);
|
74
77
|
Selector_List_Ptr operator()(Complex_Selector_Ptr);
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
78
|
+
Compound_Selector_Ptr operator()(Compound_Selector_Ptr);
|
79
|
+
Simple_Selector_Ptr operator()(Simple_Selector_Ptr s);
|
80
|
+
Wrapped_Selector_Ptr operator()(Wrapped_Selector_Ptr s);
|
81
|
+
// they don't have any specific implementation (yet)
|
82
|
+
// Element_Selector_Ptr operator()(Element_Selector_Ptr s) { return s; };
|
83
|
+
// Pseudo_Selector_Ptr operator()(Pseudo_Selector_Ptr s) { return s; };
|
84
|
+
// Class_Selector_Ptr operator()(Class_Selector_Ptr s) { return s; };
|
85
|
+
// Id_Selector_Ptr operator()(Id_Selector_Ptr s) { return s; };
|
86
|
+
// Placeholder_Selector_Ptr operator()(Placeholder_Selector_Ptr s) { return s; };
|
83
87
|
// actual evaluated selectors
|
84
88
|
Selector_List_Ptr operator()(Selector_Schema_Ptr);
|
85
89
|
Expression_Ptr operator()(Parent_Selector_Ptr);
|
@@ -87,22 +91,12 @@ namespace Sass {
|
|
87
91
|
template <typename U>
|
88
92
|
Expression_Ptr fallback(U x) { return fallback_impl(x); }
|
89
93
|
|
90
|
-
// -- only need to define two comparisons, and the rest can be implemented in terms of them
|
91
|
-
static bool eq(Expression_Obj, Expression_Obj);
|
92
|
-
static bool lt(Expression_Obj, Expression_Obj, std::string op);
|
93
|
-
// -- arithmetic on the combinations that matter
|
94
|
-
static Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
|
95
|
-
static Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
|
96
|
-
static Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
|
97
|
-
static Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
|
98
|
-
static Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, ParserState* pstate = 0, bool interpolant = false);
|
99
|
-
|
100
94
|
private:
|
101
95
|
void interpolation(Context& ctx, std::string& res, Expression_Obj ex, bool into_quotes, bool was_itpl = false);
|
102
96
|
|
103
97
|
};
|
104
98
|
|
105
|
-
Expression_Ptr cval_to_astnode(union Sass_Value* v,
|
99
|
+
Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtraces traces, ParserState pstate = ParserState("[AST]"));
|
106
100
|
|
107
101
|
}
|
108
102
|
|
data/ext/libsass/src/expand.cpp
CHANGED
@@ -9,14 +9,16 @@
|
|
9
9
|
#include "backtrace.hpp"
|
10
10
|
#include "context.hpp"
|
11
11
|
#include "parser.hpp"
|
12
|
+
#include "sass_functions.hpp"
|
12
13
|
|
13
14
|
namespace Sass {
|
14
15
|
|
15
16
|
// simple endless recursion protection
|
16
17
|
const size_t maxRecursion = 500;
|
17
18
|
|
18
|
-
Expand::Expand(Context& ctx, Env* env,
|
19
|
+
Expand::Expand(Context& ctx, Env* env, std::vector<Selector_List_Obj>* stack)
|
19
20
|
: ctx(ctx),
|
21
|
+
traces(ctx.traces),
|
20
22
|
eval(Eval(*this)),
|
21
23
|
recursions(0),
|
22
24
|
in_keyframes(false),
|
@@ -26,8 +28,7 @@ namespace Sass {
|
|
26
28
|
block_stack(std::vector<Block_Ptr>()),
|
27
29
|
call_stack(std::vector<AST_Node_Obj>()),
|
28
30
|
selector_stack(std::vector<Selector_List_Obj>()),
|
29
|
-
media_block_stack(std::vector<Media_Block_Ptr>())
|
30
|
-
backtrace_stack(std::vector<Backtrace*>())
|
31
|
+
media_block_stack(std::vector<Media_Block_Ptr>())
|
31
32
|
{
|
32
33
|
env_stack.push_back(0);
|
33
34
|
env_stack.push_back(env);
|
@@ -36,13 +37,6 @@ namespace Sass {
|
|
36
37
|
if (stack == NULL) { selector_stack.push_back(0); }
|
37
38
|
else { selector_stack.insert(selector_stack.end(), stack->begin(), stack->end()); }
|
38
39
|
media_block_stack.push_back(0);
|
39
|
-
backtrace_stack.push_back(0);
|
40
|
-
backtrace_stack.push_back(bt);
|
41
|
-
}
|
42
|
-
|
43
|
-
Context& Expand::context()
|
44
|
-
{
|
45
|
-
return ctx;
|
46
40
|
}
|
47
41
|
|
48
42
|
Env* Expand::environment()
|
@@ -59,13 +53,6 @@ namespace Sass {
|
|
59
53
|
return 0;
|
60
54
|
}
|
61
55
|
|
62
|
-
Backtrace* Expand::backtrace()
|
63
|
-
{
|
64
|
-
if (backtrace_stack.size() > 0)
|
65
|
-
return backtrace_stack.back();
|
66
|
-
return 0;
|
67
|
-
}
|
68
|
-
|
69
56
|
// blocks create new variable scopes
|
70
57
|
Block_Ptr Expand::operator()(Block_Ptr b)
|
71
58
|
{
|
@@ -78,7 +65,7 @@ namespace Sass {
|
|
78
65
|
b->length(),
|
79
66
|
b->is_root());
|
80
67
|
// setup block and env stack
|
81
|
-
this->block_stack.push_back(
|
68
|
+
this->block_stack.push_back(bb);
|
82
69
|
this->env_stack.push_back(&env);
|
83
70
|
// operate on block
|
84
71
|
// this may throw up!
|
@@ -95,12 +82,14 @@ namespace Sass {
|
|
95
82
|
LOCAL_FLAG(old_at_root_without_rule, at_root_without_rule);
|
96
83
|
|
97
84
|
if (in_keyframes) {
|
98
|
-
Block_Ptr bb = operator()(
|
85
|
+
Block_Ptr bb = operator()(r->block());
|
99
86
|
Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);
|
100
87
|
if (r->selector()) {
|
101
|
-
|
102
|
-
|
103
|
-
|
88
|
+
if (Selector_List_Ptr s = r->selector()) {
|
89
|
+
selector_stack.push_back(0);
|
90
|
+
k->name(s->eval(eval));
|
91
|
+
selector_stack.pop_back();
|
92
|
+
}
|
104
93
|
}
|
105
94
|
return k.detach();
|
106
95
|
}
|
@@ -108,50 +97,54 @@ namespace Sass {
|
|
108
97
|
// reset when leaving scope
|
109
98
|
LOCAL_FLAG(at_root_without_rule, false);
|
110
99
|
|
111
|
-
//
|
112
|
-
|
113
|
-
|
100
|
+
// `&` is allowed in `@at-root`!
|
101
|
+
bool has_parent_selector = false;
|
102
|
+
for (size_t i = 0, L = selector_stack.size(); i < L && !has_parent_selector; i++) {
|
103
|
+
Selector_List_Obj ll = selector_stack.at(i);
|
104
|
+
has_parent_selector = ll != 0 && ll->length() > 0;
|
105
|
+
}
|
106
|
+
|
107
|
+
Selector_List_Obj sel = r->selector();
|
108
|
+
if (sel) sel = sel->eval(eval);
|
109
|
+
|
110
|
+
// check for parent selectors in base level rules
|
111
|
+
if (r->is_root() || (block_stack.back() && block_stack.back()->is_root())) {
|
112
|
+
if (Selector_List_Ptr selector_list = Cast<Selector_List>(r->selector())) {
|
114
113
|
for (Complex_Selector_Obj complex_selector : selector_list->elements()) {
|
115
|
-
Complex_Selector_Ptr tail =
|
114
|
+
Complex_Selector_Ptr tail = complex_selector;
|
116
115
|
while (tail) {
|
117
116
|
if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
|
118
|
-
|
117
|
+
Parent_Selector_Ptr ptr = Cast<Parent_Selector>(header);
|
118
|
+
if (ptr == NULL || (!ptr->real() || has_parent_selector)) continue;
|
119
119
|
std::string sel_str(complex_selector->to_string(ctx.c_options));
|
120
|
-
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(),
|
120
|
+
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), traces);
|
121
121
|
}
|
122
|
-
tail =
|
122
|
+
tail = tail->tail();
|
123
123
|
}
|
124
124
|
}
|
125
125
|
}
|
126
126
|
}
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
if (sel->length() == 0 || sel->has_parent_ref()) {
|
134
|
-
bool has_parent_selector = false;
|
135
|
-
for (size_t i = 0, L = selector_stack.size(); i < L && !has_parent_selector; i++) {
|
136
|
-
Selector_List_Obj ll = selector_stack.at(i);
|
137
|
-
has_parent_selector = ll != 0 && ll->length() > 0;
|
138
|
-
}
|
139
|
-
if (sel->has_real_parent_ref() && !has_parent_selector) {
|
140
|
-
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), backtrace());
|
127
|
+
else {
|
128
|
+
if (sel->length() == 0 || sel->has_parent_ref()) {
|
129
|
+
if (sel->has_real_parent_ref() && !has_parent_selector) {
|
130
|
+
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), traces);
|
131
|
+
}
|
141
132
|
}
|
142
133
|
}
|
143
134
|
|
144
|
-
|
135
|
+
// do not connect parent again
|
136
|
+
sel->remove_parent_selectors();
|
137
|
+
selector_stack.push_back(sel);
|
145
138
|
Env env(environment());
|
146
139
|
if (block_stack.back()->is_root()) {
|
147
140
|
env_stack.push_back(&env);
|
148
141
|
}
|
149
142
|
sel->set_media_block(media_block_stack.back());
|
150
143
|
Block_Obj blk = 0;
|
151
|
-
if (r->block()) blk = operator()(
|
144
|
+
if (r->block()) blk = operator()(r->block());
|
152
145
|
Ruleset_Ptr rr = SASS_MEMORY_NEW(Ruleset,
|
153
146
|
r->pstate(),
|
154
|
-
|
147
|
+
sel,
|
155
148
|
blk);
|
156
149
|
selector_stack.pop_back();
|
157
150
|
if (block_stack.back()->is_root()) {
|
@@ -169,27 +162,33 @@ namespace Sass {
|
|
169
162
|
Expression_Obj condition = f->condition()->perform(&eval);
|
170
163
|
Supports_Block_Obj ff = SASS_MEMORY_NEW(Supports_Block,
|
171
164
|
f->pstate(),
|
172
|
-
|
173
|
-
operator()(
|
165
|
+
Cast<Supports_Condition>(condition),
|
166
|
+
operator()(f->block()));
|
174
167
|
return ff.detach();
|
175
168
|
}
|
176
169
|
|
177
170
|
Statement_Ptr Expand::operator()(Media_Block_Ptr m)
|
178
171
|
{
|
179
|
-
|
180
|
-
|
172
|
+
Media_Block_Obj cpy = SASS_MEMORY_COPY(m);
|
173
|
+
// Media_Blocks are prone to have circular references
|
174
|
+
// Copy could leak memory if it does not get picked up
|
175
|
+
// Looks like we are able to reset block reference for copy
|
176
|
+
// Good as it will ensure a low memory overhead for this fix
|
177
|
+
// So this is a cheap solution with a minimal price
|
178
|
+
ctx.ast_gc.push_back(cpy); cpy->block(0);
|
179
|
+
Expression_Obj mq = eval(m->media_queries());
|
181
180
|
std::string str_mq(mq->to_string(ctx.c_options));
|
182
181
|
char* str = sass_copy_c_string(str_mq.c_str());
|
183
182
|
ctx.strings.push_back(str);
|
184
|
-
Parser p(Parser::from_c_str(str, ctx, mq->pstate()));
|
185
|
-
mq =
|
186
|
-
|
187
|
-
|
183
|
+
Parser p(Parser::from_c_str(str, ctx, traces, mq->pstate()));
|
184
|
+
mq = p.parse_media_queries(); // re-assign now
|
185
|
+
cpy->media_queries(mq);
|
186
|
+
media_block_stack.push_back(cpy);
|
187
|
+
Block_Obj blk = operator()(m->block());
|
188
188
|
Media_Block_Ptr mm = SASS_MEMORY_NEW(Media_Block,
|
189
189
|
m->pstate(),
|
190
|
-
|
191
|
-
blk
|
192
|
-
0);
|
190
|
+
mq,
|
191
|
+
blk);
|
193
192
|
media_block_stack.pop_back();
|
194
193
|
mm->tabs(m->tabs());
|
195
194
|
return mm;
|
@@ -198,7 +197,7 @@ namespace Sass {
|
|
198
197
|
Statement_Ptr Expand::operator()(At_Root_Block_Ptr a)
|
199
198
|
{
|
200
199
|
Block_Obj ab = a->block();
|
201
|
-
Expression_Obj ae =
|
200
|
+
Expression_Obj ae = a->expression();
|
202
201
|
|
203
202
|
if (ae) ae = ae->perform(&eval);
|
204
203
|
else ae = SASS_MEMORY_NEW(At_Root_Query, a->pstate());
|
@@ -208,23 +207,23 @@ namespace Sass {
|
|
208
207
|
|
209
208
|
;
|
210
209
|
|
211
|
-
Block_Obj bb = ab ? operator()(
|
210
|
+
Block_Obj bb = ab ? operator()(ab) : NULL;
|
212
211
|
At_Root_Block_Obj aa = SASS_MEMORY_NEW(At_Root_Block,
|
213
212
|
a->pstate(),
|
214
213
|
bb,
|
215
|
-
|
214
|
+
Cast<At_Root_Query>(ae));
|
216
215
|
return aa.detach();
|
217
216
|
}
|
218
217
|
|
219
218
|
Statement_Ptr Expand::operator()(Directive_Ptr a)
|
220
219
|
{
|
221
220
|
LOCAL_FLAG(in_keyframes, a->is_keyframes());
|
222
|
-
Block_Ptr ab =
|
223
|
-
|
224
|
-
Expression_Ptr av =
|
221
|
+
Block_Ptr ab = a->block();
|
222
|
+
Selector_List_Ptr as = a->selector();
|
223
|
+
Expression_Ptr av = a->value();
|
225
224
|
selector_stack.push_back(0);
|
226
225
|
if (av) av = av->perform(&eval);
|
227
|
-
if (as) as =
|
226
|
+
if (as) as = eval(as);
|
228
227
|
selector_stack.pop_back();
|
229
228
|
Block_Ptr bb = ab ? operator()(ab) : NULL;
|
230
229
|
Directive_Ptr aa = SASS_MEMORY_NEW(Directive,
|
@@ -241,14 +240,15 @@ namespace Sass {
|
|
241
240
|
Block_Obj ab = d->block();
|
242
241
|
String_Obj old_p = d->property();
|
243
242
|
Expression_Obj prop = old_p->perform(&eval);
|
244
|
-
String_Obj new_p =
|
243
|
+
String_Obj new_p = Cast<String>(prop);
|
245
244
|
// we might get a color back
|
246
245
|
if (!new_p) {
|
247
246
|
std::string str(prop->to_string(ctx.c_options));
|
248
247
|
new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str);
|
249
248
|
}
|
250
|
-
Expression_Obj value = d->value()
|
251
|
-
|
249
|
+
Expression_Obj value = d->value();
|
250
|
+
if (value) value = value->perform(&eval);
|
251
|
+
Block_Obj bb = ab ? operator()(ab) : NULL;
|
252
252
|
if (!bb) {
|
253
253
|
if (!value || (value->is_invisible() && !d->is_important())) return 0;
|
254
254
|
}
|
@@ -257,6 +257,7 @@ namespace Sass {
|
|
257
257
|
new_p,
|
258
258
|
value,
|
259
259
|
d->is_important(),
|
260
|
+
d->is_custom_property(),
|
260
261
|
bb);
|
261
262
|
decl->tabs(d->tabs());
|
262
263
|
return decl;
|
@@ -265,11 +266,11 @@ namespace Sass {
|
|
265
266
|
Statement_Ptr Expand::operator()(Assignment_Ptr a)
|
266
267
|
{
|
267
268
|
Env* env = environment();
|
268
|
-
std::string var(a->variable());
|
269
|
+
const std::string& var(a->variable());
|
269
270
|
if (a->is_global()) {
|
270
271
|
if (a->is_default()) {
|
271
272
|
if (env->has_global(var)) {
|
272
|
-
Expression_Obj e =
|
273
|
+
Expression_Obj e = Cast<Expression>(env->get_global(var));
|
273
274
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
274
275
|
env->set_global(var, a->value()->perform(&eval));
|
275
276
|
}
|
@@ -288,7 +289,7 @@ namespace Sass {
|
|
288
289
|
while (cur && cur->is_lexical()) {
|
289
290
|
if (cur->has_local(var)) {
|
290
291
|
if (AST_Node_Obj node = cur->get_local(var)) {
|
291
|
-
Expression_Obj e =
|
292
|
+
Expression_Obj e = Cast<Expression>(node);
|
292
293
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
293
294
|
cur->set_local(var, a->value()->perform(&eval));
|
294
295
|
}
|
@@ -304,7 +305,7 @@ namespace Sass {
|
|
304
305
|
}
|
305
306
|
else if (env->has_global(var)) {
|
306
307
|
if (AST_Node_Obj node = env->get_global(var)) {
|
307
|
-
Expression_Obj e =
|
308
|
+
Expression_Obj e = Cast<Expression>(node);
|
308
309
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
309
310
|
env->set_global(var, a->value()->perform(&eval));
|
310
311
|
}
|
@@ -328,7 +329,7 @@ namespace Sass {
|
|
328
329
|
Import_Obj result = SASS_MEMORY_NEW(Import, imp->pstate());
|
329
330
|
if (imp->import_queries() && imp->import_queries()->size()) {
|
330
331
|
Expression_Obj ex = imp->import_queries()->perform(&eval);
|
331
|
-
result->import_queries(
|
332
|
+
result->import_queries(Cast<List>(ex));
|
332
333
|
}
|
333
334
|
for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
|
334
335
|
result->urls().push_back(imp->urls()[i]->perform(&eval));
|
@@ -340,10 +341,11 @@ namespace Sass {
|
|
340
341
|
|
341
342
|
Statement_Ptr Expand::operator()(Import_Stub_Ptr i)
|
342
343
|
{
|
344
|
+
traces.push_back(Backtrace(i->pstate()));
|
343
345
|
// get parent node from call stack
|
344
346
|
AST_Node_Obj parent = call_stack.back();
|
345
|
-
if (
|
346
|
-
error("Import directives may not be used within control directives or mixins.", i->pstate());
|
347
|
+
if (Cast<Block>(parent) == NULL) {
|
348
|
+
error("Import directives may not be used within control directives or mixins.", i->pstate(), traces);
|
347
349
|
}
|
348
350
|
// we don't seem to need that actually afterall
|
349
351
|
Sass_Import_Entry import = sass_make_import(
|
@@ -352,10 +354,18 @@ namespace Sass {
|
|
352
354
|
0, 0
|
353
355
|
);
|
354
356
|
ctx.import_stack.push_back(import);
|
357
|
+
|
358
|
+
Block_Obj trace_block = SASS_MEMORY_NEW(Block, i->pstate());
|
359
|
+
Trace_Obj trace = SASS_MEMORY_NEW(Trace, i->pstate(), i->imp_path(), trace_block, 'i');
|
360
|
+
block_stack.back()->append(trace);
|
361
|
+
block_stack.push_back(trace_block);
|
362
|
+
|
355
363
|
const std::string& abs_path(i->resource().abs_path);
|
356
|
-
append_block(
|
364
|
+
append_block(ctx.sheets.at(abs_path).root);
|
357
365
|
sass_delete_import(ctx.import_stack.back());
|
358
366
|
ctx.import_stack.pop_back();
|
367
|
+
block_stack.pop_back();
|
368
|
+
traces.pop_back();
|
359
369
|
return 0;
|
360
370
|
}
|
361
371
|
|
@@ -382,8 +392,13 @@ namespace Sass {
|
|
382
392
|
|
383
393
|
Statement_Ptr Expand::operator()(Comment_Ptr c)
|
384
394
|
{
|
395
|
+
if (ctx.output_style() == COMPRESSED) {
|
396
|
+
// comments should not be evaluated in compact
|
397
|
+
// https://github.com/sass/libsass/issues/2359
|
398
|
+
if (!c->is_important()) return NULL;
|
399
|
+
}
|
385
400
|
eval.is_in_comment = true;
|
386
|
-
Comment_Ptr rv = SASS_MEMORY_NEW(Comment, c->pstate(),
|
401
|
+
Comment_Ptr rv = SASS_MEMORY_NEW(Comment, c->pstate(), Cast<String>(c->text()->perform(&eval)), c->is_important());
|
387
402
|
eval.is_in_comment = false;
|
388
403
|
// TODO: eval the text, once we're parsing/storing it as a String_Schema
|
389
404
|
return rv;
|
@@ -396,10 +411,10 @@ namespace Sass {
|
|
396
411
|
call_stack.push_back(i);
|
397
412
|
Expression_Obj rv = i->predicate()->perform(&eval);
|
398
413
|
if (*rv) {
|
399
|
-
append_block(
|
414
|
+
append_block(i->block());
|
400
415
|
}
|
401
416
|
else {
|
402
|
-
Block_Ptr alt =
|
417
|
+
Block_Ptr alt = i->alternative();
|
403
418
|
if (alt) append_block(alt);
|
404
419
|
}
|
405
420
|
call_stack.pop_back();
|
@@ -414,20 +429,22 @@ namespace Sass {
|
|
414
429
|
std::string variable(f->variable());
|
415
430
|
Expression_Obj low = f->lower_bound()->perform(&eval);
|
416
431
|
if (low->concrete_type() != Expression::NUMBER) {
|
417
|
-
|
432
|
+
traces.push_back(Backtrace(low->pstate()));
|
433
|
+
throw Exception::TypeMismatch(traces, *low, "integer");
|
418
434
|
}
|
419
435
|
Expression_Obj high = f->upper_bound()->perform(&eval);
|
420
436
|
if (high->concrete_type() != Expression::NUMBER) {
|
421
|
-
|
437
|
+
traces.push_back(Backtrace(high->pstate()));
|
438
|
+
throw Exception::TypeMismatch(traces, *high, "integer");
|
422
439
|
}
|
423
|
-
Number_Obj sass_start =
|
424
|
-
Number_Obj sass_end =
|
440
|
+
Number_Obj sass_start = Cast<Number>(low);
|
441
|
+
Number_Obj sass_end = Cast<Number>(high);
|
425
442
|
// check if units are valid for sequence
|
426
443
|
if (sass_start->unit() != sass_end->unit()) {
|
427
444
|
std::stringstream msg; msg << "Incompatible units: '"
|
428
445
|
<< sass_start->unit() << "' and '"
|
429
446
|
<< sass_end->unit() << "'.";
|
430
|
-
error(msg.str(), low->pstate(),
|
447
|
+
error(msg.str(), low->pstate(), traces);
|
431
448
|
}
|
432
449
|
double start = sass_start->value();
|
433
450
|
double end = sass_end->value();
|
@@ -435,17 +452,14 @@ namespace Sass {
|
|
435
452
|
Env env(environment(), true);
|
436
453
|
env_stack.push_back(&env);
|
437
454
|
call_stack.push_back(f);
|
438
|
-
|
439
|
-
env.set_local(variable, &it);
|
440
|
-
Block_Ptr body = &f->block();
|
455
|
+
Block_Ptr body = f->block();
|
441
456
|
if (start < end) {
|
442
457
|
if (f->is_inclusive()) ++end;
|
443
458
|
for (double i = start;
|
444
459
|
i < end;
|
445
460
|
++i) {
|
446
|
-
it =
|
447
|
-
it
|
448
|
-
env.set_local(variable, &it);
|
461
|
+
Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());
|
462
|
+
env.set_local(variable, it);
|
449
463
|
append_block(body);
|
450
464
|
}
|
451
465
|
} else {
|
@@ -453,9 +467,8 @@ namespace Sass {
|
|
453
467
|
for (double i = start;
|
454
468
|
i > end;
|
455
469
|
--i) {
|
456
|
-
it =
|
457
|
-
it
|
458
|
-
env.set_local(variable, &it);
|
470
|
+
Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());
|
471
|
+
env.set_local(variable, it);
|
459
472
|
append_block(body);
|
460
473
|
}
|
461
474
|
}
|
@@ -473,25 +486,25 @@ namespace Sass {
|
|
473
486
|
List_Obj list = 0;
|
474
487
|
Map_Obj map;
|
475
488
|
if (expr->concrete_type() == Expression::MAP) {
|
476
|
-
map =
|
489
|
+
map = Cast<Map>(expr);
|
477
490
|
}
|
478
|
-
else if (Selector_List_Ptr ls =
|
491
|
+
else if (Selector_List_Ptr ls = Cast<Selector_List>(expr)) {
|
479
492
|
Listize listize;
|
480
493
|
Expression_Obj rv = ls->perform(&listize);
|
481
|
-
list =
|
494
|
+
list = Cast<List>(rv);
|
482
495
|
}
|
483
496
|
else if (expr->concrete_type() != Expression::LIST) {
|
484
497
|
list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA);
|
485
498
|
list->append(expr);
|
486
499
|
}
|
487
500
|
else {
|
488
|
-
list =
|
501
|
+
list = Cast<List>(expr);
|
489
502
|
}
|
490
503
|
// remember variables and then reset them
|
491
504
|
Env env(environment(), true);
|
492
505
|
env_stack.push_back(&env);
|
493
506
|
call_stack.push_back(e);
|
494
|
-
Block_Ptr body =
|
507
|
+
Block_Ptr body = e->block();
|
495
508
|
|
496
509
|
if (map) {
|
497
510
|
for (auto key : map->keys()) {
|
@@ -502,43 +515,43 @@ namespace Sass {
|
|
502
515
|
List_Obj variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
|
503
516
|
variable->append(k);
|
504
517
|
variable->append(v);
|
505
|
-
env.set_local(variables[0],
|
518
|
+
env.set_local(variables[0], variable);
|
506
519
|
} else {
|
507
|
-
env.set_local(variables[0],
|
508
|
-
env.set_local(variables[1],
|
520
|
+
env.set_local(variables[0], k);
|
521
|
+
env.set_local(variables[1], v);
|
509
522
|
}
|
510
523
|
append_block(body);
|
511
524
|
}
|
512
525
|
}
|
513
526
|
else {
|
514
527
|
// bool arglist = list->is_arglist();
|
515
|
-
if (list->length() == 1 &&
|
516
|
-
list =
|
528
|
+
if (list->length() == 1 && Cast<Selector_List>(list)) {
|
529
|
+
list = Cast<List>(list);
|
517
530
|
}
|
518
531
|
for (size_t i = 0, L = list->length(); i < L; ++i) {
|
519
|
-
Expression_Obj
|
532
|
+
Expression_Obj item = list->at(i);
|
520
533
|
// unwrap value if the expression is an argument
|
521
|
-
if (Argument_Obj arg =
|
534
|
+
if (Argument_Obj arg = Cast<Argument>(item)) item = arg->value();
|
522
535
|
// check if we got passed a list of args (investigate)
|
523
|
-
if (List_Obj scalars =
|
536
|
+
if (List_Obj scalars = Cast<List>(item)) {
|
524
537
|
if (variables.size() == 1) {
|
525
538
|
List_Obj var = scalars;
|
526
539
|
// if (arglist) var = (*scalars)[0];
|
527
|
-
env.set_local(variables[0],
|
540
|
+
env.set_local(variables[0], var);
|
528
541
|
} else {
|
529
542
|
for (size_t j = 0, K = variables.size(); j < K; ++j) {
|
530
543
|
Expression_Obj res = j >= scalars->length()
|
531
544
|
? SASS_MEMORY_NEW(Null, expr->pstate())
|
532
545
|
: (*scalars)[j]->perform(&eval);
|
533
|
-
env.set_local(variables[j],
|
546
|
+
env.set_local(variables[j], res);
|
534
547
|
}
|
535
548
|
}
|
536
549
|
} else {
|
537
550
|
if (variables.size() > 0) {
|
538
|
-
env.set_local(variables.at(0),
|
551
|
+
env.set_local(variables.at(0), item);
|
539
552
|
for (size_t j = 1, K = variables.size(); j < K; ++j) {
|
540
553
|
Expression_Obj res = SASS_MEMORY_NEW(Null, expr->pstate());
|
541
|
-
env.set_local(variables[j],
|
554
|
+
env.set_local(variables[j], res);
|
542
555
|
}
|
543
556
|
}
|
544
557
|
}
|
@@ -553,12 +566,12 @@ namespace Sass {
|
|
553
566
|
Statement_Ptr Expand::operator()(While_Ptr w)
|
554
567
|
{
|
555
568
|
Expression_Obj pred = w->predicate();
|
556
|
-
Block_Ptr body =
|
569
|
+
Block_Ptr body = w->block();
|
557
570
|
Env env(environment(), true);
|
558
571
|
env_stack.push_back(&env);
|
559
572
|
call_stack.push_back(w);
|
560
573
|
Expression_Obj cond = pred->perform(&eval);
|
561
|
-
while (
|
574
|
+
while (!cond->is_false()) {
|
562
575
|
append_block(body);
|
563
576
|
cond = pred->perform(&eval);
|
564
577
|
}
|
@@ -569,21 +582,21 @@ namespace Sass {
|
|
569
582
|
|
570
583
|
Statement_Ptr Expand::operator()(Return_Ptr r)
|
571
584
|
{
|
572
|
-
error("@return may only be used within a function", r->pstate(),
|
585
|
+
error("@return may only be used within a function", r->pstate(), traces);
|
573
586
|
return 0;
|
574
587
|
}
|
575
588
|
|
576
589
|
|
577
590
|
void Expand::expand_selector_list(Selector_Obj s, Selector_List_Obj extender) {
|
578
591
|
|
579
|
-
if (Selector_List_Obj sl =
|
592
|
+
if (Selector_List_Obj sl = Cast<Selector_List>(s)) {
|
580
593
|
for (Complex_Selector_Obj complex_selector : sl->elements()) {
|
581
594
|
Complex_Selector_Obj tail = complex_selector;
|
582
595
|
while (tail) {
|
583
596
|
if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
|
584
|
-
if (
|
597
|
+
if (Cast<Parent_Selector>(header) == NULL) continue; // skip all others
|
585
598
|
std::string sel_str(complex_selector->to_string(ctx.c_options));
|
586
|
-
error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(),
|
599
|
+
error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), traces);
|
587
600
|
}
|
588
601
|
tail = tail->tail();
|
589
602
|
}
|
@@ -591,20 +604,20 @@ namespace Sass {
|
|
591
604
|
}
|
592
605
|
|
593
606
|
|
594
|
-
Selector_List_Obj contextualized =
|
607
|
+
Selector_List_Obj contextualized = Cast<Selector_List>(s->perform(&eval));
|
595
608
|
if (contextualized == false) return;
|
596
609
|
for (auto complex_sel : contextualized->elements()) {
|
597
610
|
Complex_Selector_Obj c = complex_sel;
|
598
611
|
if (!c->head() || c->tail()) {
|
599
612
|
std::string sel_str(contextualized->to_string(ctx.c_options));
|
600
|
-
error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(),
|
613
|
+
error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), traces);
|
601
614
|
}
|
602
|
-
Compound_Selector_Obj
|
603
|
-
if (contextualized->is_optional())
|
615
|
+
Compound_Selector_Obj target = c->head();
|
616
|
+
if (contextualized->is_optional()) target->is_optional(true);
|
604
617
|
for (size_t i = 0, L = extender->length(); i < L; ++i) {
|
605
618
|
Complex_Selector_Obj sel = (*extender)[i];
|
606
619
|
if (!(sel->head() && sel->head()->length() > 0 &&
|
607
|
-
|
620
|
+
Cast<Parent_Selector>((*sel->head())[0])))
|
608
621
|
{
|
609
622
|
Compound_Selector_Obj hh = SASS_MEMORY_NEW(Compound_Selector, (*extender)[i]->pstate());
|
610
623
|
hh->media_block((*extender)[i]->media_block());
|
@@ -613,13 +626,13 @@ namespace Sass {
|
|
613
626
|
if (sel->has_line_feed()) ssel->has_line_feed(true);
|
614
627
|
Parent_Selector_Obj ps = SASS_MEMORY_NEW(Parent_Selector, (*extender)[i]->pstate());
|
615
628
|
ps->media_block((*extender)[i]->media_block());
|
616
|
-
hh->append(
|
629
|
+
hh->append(ps);
|
617
630
|
ssel->tail(sel);
|
618
631
|
ssel->head(hh);
|
619
632
|
sel = ssel;
|
620
633
|
}
|
621
634
|
// if (c->has_line_feed()) sel->has_line_feed(true);
|
622
|
-
ctx.subset_map.put(
|
635
|
+
ctx.subset_map.put(target, std::make_pair(sel, target));
|
623
636
|
}
|
624
637
|
}
|
625
638
|
|
@@ -627,31 +640,30 @@ namespace Sass {
|
|
627
640
|
|
628
641
|
Statement* Expand::operator()(Extension_Ptr e)
|
629
642
|
{
|
630
|
-
if (
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
if (
|
635
|
-
// convert selector schema to a selector list
|
636
|
-
else if (Selector_Schema_Obj schema = SASS_MEMORY_CAST(Selector_Schema, s)) {
|
643
|
+
if (Selector_List_Ptr extender = selector()) {
|
644
|
+
Selector_List_Ptr sl = e->selector();
|
645
|
+
// abort on invalid selector
|
646
|
+
if (sl == NULL) return NULL;
|
647
|
+
if (Selector_Schema_Ptr schema = sl->schema()) {
|
637
648
|
if (schema->has_real_parent_ref()) {
|
638
|
-
|
649
|
+
// put root block on stack again (ignore parents)
|
650
|
+
// selector schema must not connect in eval!
|
651
|
+
block_stack.push_back(block_stack.at(1));
|
652
|
+
sl = eval(sl->schema());
|
653
|
+
block_stack.pop_back();
|
639
654
|
} else {
|
640
655
|
selector_stack.push_back(0);
|
641
|
-
sl = eval(
|
642
|
-
sl->remove_parent_selectors();
|
656
|
+
sl = eval(sl->schema());
|
643
657
|
selector_stack.pop_back();
|
644
658
|
}
|
645
659
|
}
|
646
|
-
// abort on invalid selector
|
647
|
-
if (sl.isNull()) return NULL;
|
648
660
|
for (Complex_Selector_Obj cs : sl->elements()) {
|
649
661
|
if (!cs.isNull() && !cs->head().isNull()) {
|
650
662
|
cs->head()->media_block(media_block_stack.back());
|
651
663
|
}
|
652
664
|
}
|
653
665
|
selector_stack.push_back(0);
|
654
|
-
expand_selector_list(
|
666
|
+
expand_selector_list(sl, extender);
|
655
667
|
selector_stack.pop_back();
|
656
668
|
}
|
657
669
|
return 0;
|
@@ -662,7 +674,7 @@ namespace Sass {
|
|
662
674
|
Env* env = environment();
|
663
675
|
Definition_Obj dd = SASS_MEMORY_COPY(d);
|
664
676
|
env->local_frame()[d->name() +
|
665
|
-
(d->type() == Definition::MIXIN ? "[m]" : "[f]")] =
|
677
|
+
(d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
|
666
678
|
|
667
679
|
if (d->type() == Definition::FUNCTION && (
|
668
680
|
Prelexer::calc_fn_call(d->name().c_str()) ||
|
@@ -671,9 +683,9 @@ namespace Sass {
|
|
671
683
|
d->name() == "url"
|
672
684
|
)) {
|
673
685
|
deprecated(
|
674
|
-
"Naming a function \"" + d->name() + "\" is disallowed",
|
686
|
+
"Naming a function \"" + d->name() + "\" is disallowed and will be an error in future versions of Sass.",
|
675
687
|
"This name conflicts with an existing CSS function with special parse rules.",
|
676
|
-
|
688
|
+
false, d->pstate()
|
677
689
|
);
|
678
690
|
}
|
679
691
|
|
@@ -684,9 +696,8 @@ namespace Sass {
|
|
684
696
|
|
685
697
|
Statement_Ptr Expand::operator()(Mixin_Call_Ptr c)
|
686
698
|
{
|
687
|
-
|
688
699
|
if (recursions > maxRecursion) {
|
689
|
-
throw Exception::StackError(*c);
|
700
|
+
throw Exception::StackError(traces, *c);
|
690
701
|
}
|
691
702
|
|
692
703
|
recursions ++;
|
@@ -694,19 +705,28 @@ namespace Sass {
|
|
694
705
|
Env* env = environment();
|
695
706
|
std::string full_name(c->name() + "[m]");
|
696
707
|
if (!env->has(full_name)) {
|
697
|
-
error("no mixin named " + c->name(), c->pstate(),
|
708
|
+
error("no mixin named " + c->name(), c->pstate(), traces);
|
698
709
|
}
|
699
|
-
Definition_Obj def =
|
710
|
+
Definition_Obj def = Cast<Definition>((*env)[full_name]);
|
700
711
|
Block_Obj body = def->block();
|
701
712
|
Parameters_Obj params = def->parameters();
|
702
713
|
|
703
714
|
if (c->block() && c->name() != "@content" && !body->has_content()) {
|
704
|
-
error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(),
|
715
|
+
error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(), traces);
|
705
716
|
}
|
706
717
|
Expression_Obj rv = c->arguments()->perform(&eval);
|
707
|
-
Arguments_Obj args =
|
708
|
-
|
709
|
-
|
718
|
+
Arguments_Obj args = Cast<Arguments>(rv);
|
719
|
+
std::string msg(", in mixin `" + c->name() + "`");
|
720
|
+
traces.push_back(Backtrace(c->pstate(), msg));
|
721
|
+
ctx.callee_stack.push_back({
|
722
|
+
c->name().c_str(),
|
723
|
+
c->pstate().path,
|
724
|
+
c->pstate().line + 1,
|
725
|
+
c->pstate().column + 1,
|
726
|
+
SASS_CALLEE_MIXIN,
|
727
|
+
{ env }
|
728
|
+
});
|
729
|
+
|
710
730
|
Env new_env(def->environment());
|
711
731
|
env_stack.push_back(&new_env);
|
712
732
|
if (c->block()) {
|
@@ -718,7 +738,7 @@ namespace Sass {
|
|
718
738
|
c->block(),
|
719
739
|
Definition::MIXIN);
|
720
740
|
thunk->environment(env);
|
721
|
-
new_env.local_frame()["@content[m]"] =
|
741
|
+
new_env.local_frame()["@content[m]"] = thunk;
|
722
742
|
}
|
723
743
|
|
724
744
|
bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval);
|
@@ -726,16 +746,24 @@ namespace Sass {
|
|
726
746
|
Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate());
|
727
747
|
Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block);
|
728
748
|
|
729
|
-
|
730
|
-
block_stack.
|
749
|
+
env->set_global("is_in_mixin", bool_true);
|
750
|
+
if (Block_Ptr pr = block_stack.back()) {
|
751
|
+
trace_block->is_root(pr->is_root());
|
752
|
+
}
|
753
|
+
block_stack.push_back(trace_block);
|
731
754
|
for (auto bb : body->elements()) {
|
755
|
+
if (Ruleset_Ptr r = Cast<Ruleset>(bb)) {
|
756
|
+
r->is_root(trace_block->is_root());
|
757
|
+
}
|
732
758
|
Statement_Obj ith = bb->perform(this);
|
733
759
|
if (ith) trace->block()->append(ith);
|
734
760
|
}
|
735
761
|
block_stack.pop_back();
|
762
|
+
env->del_global("is_in_mixin");
|
736
763
|
|
764
|
+
ctx.callee_stack.pop_back();
|
737
765
|
env_stack.pop_back();
|
738
|
-
|
766
|
+
traces.pop_back();
|
739
767
|
|
740
768
|
recursions --;
|
741
769
|
return trace.detach();
|
@@ -756,7 +784,7 @@ namespace Sass {
|
|
756
784
|
"@content",
|
757
785
|
SASS_MEMORY_NEW(Arguments, c->pstate()));
|
758
786
|
|
759
|
-
Trace_Obj trace =
|
787
|
+
Trace_Obj trace = Cast<Trace>(call->perform(this));
|
760
788
|
|
761
789
|
if (block_stack.back()->is_root()) {
|
762
790
|
selector_stack.pop_back();
|
@@ -770,8 +798,8 @@ namespace Sass {
|
|
770
798
|
{
|
771
799
|
std::string err =std:: string("`Expand` doesn't handle ") + typeid(*n).name();
|
772
800
|
String_Quoted_Obj msg = SASS_MEMORY_NEW(String_Quoted, ParserState("[WARN]"), err);
|
773
|
-
error("unknown internal error; please contact the LibSass maintainers", n->pstate(),
|
774
|
-
return SASS_MEMORY_NEW(Warning, ParserState("[WARN]"),
|
801
|
+
error("unknown internal error; please contact the LibSass maintainers", n->pstate(), traces);
|
802
|
+
return SASS_MEMORY_NEW(Warning, ParserState("[WARN]"), msg);
|
775
803
|
}
|
776
804
|
|
777
805
|
// process and add to last block on stack
|
@@ -779,7 +807,7 @@ namespace Sass {
|
|
779
807
|
{
|
780
808
|
if (b->is_root()) call_stack.push_back(b);
|
781
809
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
782
|
-
Statement_Ptr stm =
|
810
|
+
Statement_Ptr stm = b->at(i);
|
783
811
|
Statement_Obj ith = stm->perform(this);
|
784
812
|
if (ith) block_stack.back()->append(ith);
|
785
813
|
}
|