sassc 1.11.4 → 1.12.0
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 +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
|
}
|