sassc 2.2.1 → 2.4.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 +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/Rakefile +1 -3
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +4 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +158 -168
- data/ext/libsass/src/ast.hpp +389 -230
- data/ext/libsass/src/ast_def_macros.hpp +18 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +594 -1026
- data/ext/libsass/src/ast_selectors.hpp +339 -385
- data/ext/libsass/src/ast_supports.cpp +36 -52
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +271 -84
- data/ext/libsass/src/ast_values.hpp +116 -107
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +18 -18
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +40 -41
- data/ext/libsass/src/check_nesting.hpp +6 -2
- data/ext/libsass/src/color_maps.cpp +14 -13
- data/ext/libsass/src/color_maps.hpp +1 -9
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +92 -119
- data/ext/libsass/src/context.hpp +41 -53
- data/ext/libsass/src/cssize.cpp +66 -149
- data/ext/libsass/src/cssize.hpp +17 -23
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +451 -295
- data/ext/libsass/src/emitter.cpp +15 -16
- data/ext/libsass/src/emitter.hpp +10 -12
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +29 -24
- data/ext/libsass/src/error_handling.cpp +62 -41
- data/ext/libsass/src/error_handling.hpp +61 -51
- data/ext/libsass/src/eval.cpp +167 -281
- data/ext/libsass/src/eval.hpp +27 -29
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +275 -222
- data/ext/libsass/src/expand.hpp +36 -16
- data/ext/libsass/src/extender.cpp +1188 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +81 -72
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +20 -18
- data/ext/libsass/src/fn_lists.cpp +30 -29
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +34 -46
- data/ext/libsass/src/fn_numbers.cpp +20 -13
- data/ext/libsass/src/fn_selectors.cpp +98 -128
- data/ext/libsass/src/fn_strings.cpp +47 -33
- data/ext/libsass/src/fn_utils.cpp +31 -29
- data/ext/libsass/src/fn_utils.hpp +17 -11
- data/ext/libsass/src/inspect.cpp +186 -148
- data/ext/libsass/src/inspect.hpp +31 -29
- data/ext/libsass/src/lexer.cpp +20 -82
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +23 -37
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +71 -61
- data/ext/libsass/src/operators.cpp +19 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +45 -64
- data/ext/libsass/src/output.hpp +6 -6
- data/ext/libsass/src/parser.cpp +512 -700
- data/ext/libsass/src/parser.hpp +89 -97
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.cpp +16 -15
- data/ext/libsass/src/sass.hpp +10 -5
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +91 -122
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +8 -11
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +24 -22
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +48 -50
- data/ext/libsass/src/util.hpp +20 -21
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +62 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +4 -6
- data/lib/sassc/script.rb +4 -4
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +18 -1
- data/test/native_test.rb +4 -4
- metadata +29 -15
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/lib/sassc/native/lib_c.rb +0 -21
data/ext/libsass/src/expand.cpp
CHANGED
@@ -13,13 +13,14 @@
|
|
13
13
|
#include "context.hpp"
|
14
14
|
#include "parser.hpp"
|
15
15
|
#include "sass_functions.hpp"
|
16
|
+
#include "error_handling.hpp"
|
16
17
|
|
17
18
|
namespace Sass {
|
18
19
|
|
19
20
|
// simple endless recursion protection
|
20
21
|
const size_t maxRecursion = 500;
|
21
22
|
|
22
|
-
Expand::Expand(Context& ctx, Env* env, SelectorStack* stack)
|
23
|
+
Expand::Expand(Context& ctx, Env* env, SelectorStack* stack, SelectorStack* originals)
|
23
24
|
: ctx(ctx),
|
24
25
|
traces(ctx.traces),
|
25
26
|
eval(Eval(*this)),
|
@@ -27,19 +28,32 @@ namespace Sass {
|
|
27
28
|
in_keyframes(false),
|
28
29
|
at_root_without_rule(false),
|
29
30
|
old_at_root_without_rule(false),
|
30
|
-
env_stack(
|
31
|
-
block_stack(
|
32
|
-
call_stack(
|
33
|
-
selector_stack(
|
34
|
-
|
31
|
+
env_stack(),
|
32
|
+
block_stack(),
|
33
|
+
call_stack(),
|
34
|
+
selector_stack(),
|
35
|
+
originalStack(),
|
36
|
+
mediaStack()
|
35
37
|
{
|
36
38
|
env_stack.push_back(nullptr);
|
37
39
|
env_stack.push_back(env);
|
38
40
|
block_stack.push_back(nullptr);
|
39
41
|
call_stack.push_back({});
|
40
|
-
if (stack == NULL) {
|
41
|
-
else {
|
42
|
-
|
42
|
+
if (stack == NULL) { pushToSelectorStack({}); }
|
43
|
+
else {
|
44
|
+
for (auto item : *stack) {
|
45
|
+
if (item.isNull()) pushToSelectorStack({});
|
46
|
+
else pushToSelectorStack(item);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
if (originals == NULL) { pushToOriginalStack({}); }
|
50
|
+
else {
|
51
|
+
for (auto item : *stack) {
|
52
|
+
if (item.isNull()) pushToOriginalStack({});
|
53
|
+
else pushToOriginalStack(item);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
mediaStack.push_back({});
|
43
57
|
}
|
44
58
|
|
45
59
|
Env* Expand::environment()
|
@@ -49,11 +63,80 @@ namespace Sass {
|
|
49
63
|
return 0;
|
50
64
|
}
|
51
65
|
|
52
|
-
|
66
|
+
void Expand::pushNullSelector()
|
67
|
+
{
|
68
|
+
pushToSelectorStack({});
|
69
|
+
pushToOriginalStack({});
|
70
|
+
}
|
71
|
+
|
72
|
+
void Expand::popNullSelector()
|
53
73
|
{
|
54
|
-
|
55
|
-
|
56
|
-
|
74
|
+
popFromOriginalStack();
|
75
|
+
popFromSelectorStack();
|
76
|
+
}
|
77
|
+
|
78
|
+
SelectorStack Expand::getOriginalStack()
|
79
|
+
{
|
80
|
+
return originalStack;
|
81
|
+
}
|
82
|
+
|
83
|
+
SelectorStack Expand::getSelectorStack()
|
84
|
+
{
|
85
|
+
return selector_stack;
|
86
|
+
}
|
87
|
+
|
88
|
+
SelectorListObj& Expand::selector()
|
89
|
+
{
|
90
|
+
if (selector_stack.size() > 0) {
|
91
|
+
auto& sel = selector_stack.back();
|
92
|
+
if (sel.isNull()) return sel;
|
93
|
+
return sel;
|
94
|
+
}
|
95
|
+
// Avoid the need to return copies
|
96
|
+
// We always want an empty first item
|
97
|
+
selector_stack.push_back({});
|
98
|
+
return selector_stack.back();;
|
99
|
+
}
|
100
|
+
|
101
|
+
SelectorListObj& Expand::original()
|
102
|
+
{
|
103
|
+
if (originalStack.size() > 0) {
|
104
|
+
auto& sel = originalStack.back();
|
105
|
+
if (sel.isNull()) return sel;
|
106
|
+
return sel;
|
107
|
+
}
|
108
|
+
// Avoid the need to return copies
|
109
|
+
// We always want an empty first item
|
110
|
+
originalStack.push_back({});
|
111
|
+
return originalStack.back();
|
112
|
+
}
|
113
|
+
|
114
|
+
SelectorListObj Expand::popFromSelectorStack()
|
115
|
+
{
|
116
|
+
SelectorListObj last = selector_stack.back();
|
117
|
+
if (selector_stack.size() > 0)
|
118
|
+
selector_stack.pop_back();
|
119
|
+
if (last.isNull()) return {};
|
120
|
+
return last;
|
121
|
+
}
|
122
|
+
|
123
|
+
void Expand::pushToSelectorStack(SelectorListObj selector)
|
124
|
+
{
|
125
|
+
selector_stack.push_back(selector);
|
126
|
+
}
|
127
|
+
|
128
|
+
SelectorListObj Expand::popFromOriginalStack()
|
129
|
+
{
|
130
|
+
SelectorListObj last = originalStack.back();
|
131
|
+
if (originalStack.size() > 0)
|
132
|
+
originalStack.pop_back();
|
133
|
+
if (last.isNull()) return {};
|
134
|
+
return last;
|
135
|
+
}
|
136
|
+
|
137
|
+
void Expand::pushToOriginalStack(SelectorListObj selector)
|
138
|
+
{
|
139
|
+
originalStack.push_back(selector);
|
57
140
|
}
|
58
141
|
|
59
142
|
// blocks create new variable scopes
|
@@ -80,76 +163,62 @@ namespace Sass {
|
|
80
163
|
return bb.detach();
|
81
164
|
}
|
82
165
|
|
83
|
-
Statement* Expand::operator()(
|
166
|
+
Statement* Expand::operator()(StyleRule* r)
|
84
167
|
{
|
85
168
|
LOCAL_FLAG(old_at_root_without_rule, at_root_without_rule);
|
86
169
|
|
87
170
|
if (in_keyframes) {
|
88
171
|
Block* bb = operator()(r->block());
|
89
172
|
Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);
|
90
|
-
if (r->
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
173
|
+
if (r->schema()) {
|
174
|
+
pushNullSelector();
|
175
|
+
k->name(eval(r->schema()));
|
176
|
+
popNullSelector();
|
177
|
+
}
|
178
|
+
else if (r->selector()) {
|
179
|
+
if (SelectorListObj s = r->selector()) {
|
180
|
+
pushNullSelector();
|
181
|
+
k->name(eval(s));
|
182
|
+
popNullSelector();
|
95
183
|
}
|
96
184
|
}
|
185
|
+
|
97
186
|
return k.detach();
|
98
187
|
}
|
99
188
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
Selector_List_Obj ll = selector_stack.at(i);
|
107
|
-
has_parent_selector = ll != nullptr && ll->length() > 0;
|
108
|
-
}
|
109
|
-
|
110
|
-
Selector_List_Obj sel = r->selector();
|
111
|
-
if (sel) sel = sel->eval(eval);
|
112
|
-
|
113
|
-
// check for parent selectors in base level rules
|
114
|
-
if (r->is_root() || (block_stack.back() && block_stack.back()->is_root())) {
|
115
|
-
if (Selector_List* selector_list = Cast<Selector_List>(r->selector())) {
|
116
|
-
for (Complex_Selector_Obj complex_selector : selector_list->elements()) {
|
117
|
-
Complex_Selector* tail = complex_selector;
|
118
|
-
while (tail) {
|
119
|
-
if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
|
120
|
-
Parent_Selector* ptr = Cast<Parent_Selector>(header);
|
121
|
-
if (ptr == NULL || (!ptr->real() || has_parent_selector)) continue;
|
122
|
-
std::string sel_str(complex_selector->to_string(ctx.c_options));
|
123
|
-
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), traces);
|
124
|
-
}
|
125
|
-
tail = tail->tail();
|
126
|
-
}
|
127
|
-
}
|
128
|
-
}
|
129
|
-
}
|
130
|
-
else {
|
131
|
-
if (sel->length() == 0 || sel->has_parent_ref()) {
|
132
|
-
if (sel->has_real_parent_ref() && !has_parent_selector) {
|
133
|
-
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), traces);
|
134
|
-
}
|
189
|
+
if (r->schema()) {
|
190
|
+
SelectorListObj sel = eval(r->schema());
|
191
|
+
r->selector(sel);
|
192
|
+
for (auto complex : sel->elements()) {
|
193
|
+
// ToDo: maybe we can get rid of chroots?
|
194
|
+
complex->chroots(complex->has_real_parent_ref());
|
135
195
|
}
|
196
|
+
|
136
197
|
}
|
137
198
|
|
199
|
+
// reset when leaving scope
|
200
|
+
LOCAL_FLAG(at_root_without_rule, false);
|
201
|
+
|
202
|
+
SelectorListObj evaled = eval(r->selector());
|
138
203
|
// do not connect parent again
|
139
|
-
sel->remove_parent_selectors();
|
140
|
-
selector_stack.push_back(sel);
|
141
204
|
Env env(environment());
|
142
205
|
if (block_stack.back()->is_root()) {
|
143
206
|
env_stack.push_back(&env);
|
144
207
|
}
|
145
|
-
sel->set_media_block(media_stack.back());
|
146
208
|
Block_Obj blk;
|
209
|
+
pushToSelectorStack(evaled);
|
210
|
+
// The copy is needed for parent reference evaluation
|
211
|
+
// dart-sass stores it as `originalSelector` member
|
212
|
+
pushToOriginalStack(SASS_MEMORY_COPY(evaled));
|
213
|
+
ctx.extender.addSelector(evaled, mediaStack.back());
|
147
214
|
if (r->block()) blk = operator()(r->block());
|
148
|
-
|
215
|
+
popFromOriginalStack();
|
216
|
+
popFromSelectorStack();
|
217
|
+
StyleRule* rr = SASS_MEMORY_NEW(StyleRule,
|
149
218
|
r->pstate(),
|
150
|
-
|
219
|
+
evaled,
|
151
220
|
blk);
|
152
|
-
|
221
|
+
|
153
222
|
if (block_stack.back()->is_root()) {
|
154
223
|
env_stack.pop_back();
|
155
224
|
}
|
@@ -160,47 +229,60 @@ namespace Sass {
|
|
160
229
|
return rr;
|
161
230
|
}
|
162
231
|
|
163
|
-
Statement* Expand::operator()(
|
232
|
+
Statement* Expand::operator()(SupportsRule* f)
|
164
233
|
{
|
165
|
-
|
166
|
-
|
234
|
+
ExpressionObj condition = f->condition()->perform(&eval);
|
235
|
+
SupportsRuleObj ff = SASS_MEMORY_NEW(SupportsRule,
|
167
236
|
f->pstate(),
|
168
|
-
Cast<
|
237
|
+
Cast<SupportsCondition>(condition),
|
169
238
|
operator()(f->block()));
|
170
239
|
return ff.detach();
|
171
240
|
}
|
172
241
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
242
|
+
sass::vector<CssMediaQuery_Obj> Expand::mergeMediaQueries(
|
243
|
+
const sass::vector<CssMediaQuery_Obj>& lhs,
|
244
|
+
const sass::vector<CssMediaQuery_Obj>& rhs)
|
245
|
+
{
|
246
|
+
sass::vector<CssMediaQuery_Obj> queries;
|
247
|
+
for (CssMediaQuery_Obj query1 : lhs) {
|
248
|
+
for (CssMediaQuery_Obj query2 : rhs) {
|
249
|
+
CssMediaQuery_Obj result = query1->merge(query2);
|
250
|
+
if (result && !result->empty()) {
|
251
|
+
queries.push_back(result);
|
252
|
+
}
|
253
|
+
}
|
254
|
+
}
|
255
|
+
return queries;
|
256
|
+
}
|
257
|
+
|
258
|
+
Statement* Expand::operator()(MediaRule* m)
|
259
|
+
{
|
260
|
+
ExpressionObj mq = eval(m->schema());
|
261
|
+
sass::string str_mq(mq->to_css(ctx.c_options));
|
262
|
+
ItplFile* source = SASS_MEMORY_NEW(ItplFile,
|
263
|
+
str_mq.c_str(), m->pstate());
|
264
|
+
Parser parser(source, ctx, traces);
|
265
|
+
// Create a new CSS only representation of the media rule
|
266
|
+
CssMediaRuleObj css = SASS_MEMORY_NEW(CssMediaRule, m->pstate(), m->block());
|
267
|
+
sass::vector<CssMediaQuery_Obj> parsed = parser.parseCssMediaQueries();
|
268
|
+
if (mediaStack.size() && mediaStack.back()) {
|
269
|
+
auto& parent = mediaStack.back()->elements();
|
270
|
+
css->concat(mergeMediaQueries(parent, parsed));
|
271
|
+
}
|
272
|
+
else {
|
273
|
+
css->concat(parsed);
|
274
|
+
}
|
275
|
+
mediaStack.push_back(css);
|
276
|
+
css->block(operator()(m->block()));
|
277
|
+
mediaStack.pop_back();
|
278
|
+
return css.detach();
|
279
|
+
|
280
|
+
}
|
281
|
+
|
282
|
+
Statement* Expand::operator()(AtRootRule* a)
|
201
283
|
{
|
202
284
|
Block_Obj ab = a->block();
|
203
|
-
|
285
|
+
ExpressionObj ae = a->expression();
|
204
286
|
|
205
287
|
if (ae) ae = ae->perform(&eval);
|
206
288
|
else ae = SASS_MEMORY_NEW(At_Root_Query, a->pstate());
|
@@ -211,25 +293,25 @@ namespace Sass {
|
|
211
293
|
;
|
212
294
|
|
213
295
|
Block_Obj bb = ab ? operator()(ab) : NULL;
|
214
|
-
|
296
|
+
AtRootRuleObj aa = SASS_MEMORY_NEW(AtRootRule,
|
215
297
|
a->pstate(),
|
216
298
|
bb,
|
217
299
|
Cast<At_Root_Query>(ae));
|
218
300
|
return aa.detach();
|
219
301
|
}
|
220
302
|
|
221
|
-
Statement* Expand::operator()(
|
303
|
+
Statement* Expand::operator()(AtRule* a)
|
222
304
|
{
|
223
305
|
LOCAL_FLAG(in_keyframes, a->is_keyframes());
|
224
306
|
Block* ab = a->block();
|
225
|
-
|
307
|
+
SelectorList* as = a->selector();
|
226
308
|
Expression* av = a->value();
|
227
|
-
|
309
|
+
pushNullSelector();
|
228
310
|
if (av) av = av->perform(&eval);
|
229
311
|
if (as) as = eval(as);
|
230
|
-
|
312
|
+
popNullSelector();
|
231
313
|
Block* bb = ab ? operator()(ab) : NULL;
|
232
|
-
|
314
|
+
AtRule* aa = SASS_MEMORY_NEW(AtRule,
|
233
315
|
a->pstate(),
|
234
316
|
a->keyword(),
|
235
317
|
as,
|
@@ -242,14 +324,14 @@ namespace Sass {
|
|
242
324
|
{
|
243
325
|
Block_Obj ab = d->block();
|
244
326
|
String_Obj old_p = d->property();
|
245
|
-
|
327
|
+
ExpressionObj prop = old_p->perform(&eval);
|
246
328
|
String_Obj new_p = Cast<String>(prop);
|
247
329
|
// we might get a color back
|
248
330
|
if (!new_p) {
|
249
|
-
|
331
|
+
sass::string str(prop->to_string(ctx.c_options));
|
250
332
|
new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str);
|
251
333
|
}
|
252
|
-
|
334
|
+
ExpressionObj value = d->value();
|
253
335
|
if (value) value = value->perform(&eval);
|
254
336
|
Block_Obj bb = ab ? operator()(ab) : NULL;
|
255
337
|
if (!bb) {
|
@@ -275,11 +357,17 @@ namespace Sass {
|
|
275
357
|
Statement* Expand::operator()(Assignment* a)
|
276
358
|
{
|
277
359
|
Env* env = environment();
|
278
|
-
const
|
360
|
+
const sass::string& var(a->variable());
|
279
361
|
if (a->is_global()) {
|
362
|
+
if (!env->has_global(var)) {
|
363
|
+
deprecated(
|
364
|
+
"!global assignments won't be able to declare new variables in future versions.",
|
365
|
+
"Consider adding `" + var + ": null` at the top level.",
|
366
|
+
true, a->pstate());
|
367
|
+
}
|
280
368
|
if (a->is_default()) {
|
281
369
|
if (env->has_global(var)) {
|
282
|
-
|
370
|
+
ExpressionObj e = Cast<Expression>(env->get_global(var));
|
283
371
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
284
372
|
env->set_global(var, a->value()->perform(&eval));
|
285
373
|
}
|
@@ -298,7 +386,7 @@ namespace Sass {
|
|
298
386
|
while (cur && cur->is_lexical()) {
|
299
387
|
if (cur->has_local(var)) {
|
300
388
|
if (AST_Node_Obj node = cur->get_local(var)) {
|
301
|
-
|
389
|
+
ExpressionObj e = Cast<Expression>(node);
|
302
390
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
303
391
|
cur->set_local(var, a->value()->perform(&eval));
|
304
392
|
}
|
@@ -314,7 +402,7 @@ namespace Sass {
|
|
314
402
|
}
|
315
403
|
else if (env->has_global(var)) {
|
316
404
|
if (AST_Node_Obj node = env->get_global(var)) {
|
317
|
-
|
405
|
+
ExpressionObj e = Cast<Expression>(node);
|
318
406
|
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
319
407
|
env->set_global(var, a->value()->perform(&eval));
|
320
408
|
}
|
@@ -337,7 +425,7 @@ namespace Sass {
|
|
337
425
|
{
|
338
426
|
Import_Obj result = SASS_MEMORY_NEW(Import, imp->pstate());
|
339
427
|
if (imp->import_queries() && imp->import_queries()->size()) {
|
340
|
-
|
428
|
+
ExpressionObj ex = imp->import_queries()->perform(&eval);
|
341
429
|
result->import_queries(Cast<List>(ex));
|
342
430
|
}
|
343
431
|
for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
|
@@ -369,7 +457,7 @@ namespace Sass {
|
|
369
457
|
block_stack.back()->append(trace);
|
370
458
|
block_stack.push_back(trace_block);
|
371
459
|
|
372
|
-
const
|
460
|
+
const sass::string& abs_path(i->resource().abs_path);
|
373
461
|
append_block(ctx.sheets.at(abs_path).root);
|
374
462
|
sass_delete_import(ctx.import_stack.back());
|
375
463
|
ctx.import_stack.pop_back();
|
@@ -378,21 +466,21 @@ namespace Sass {
|
|
378
466
|
return 0;
|
379
467
|
}
|
380
468
|
|
381
|
-
Statement* Expand::operator()(
|
469
|
+
Statement* Expand::operator()(WarningRule* w)
|
382
470
|
{
|
383
471
|
// eval handles this too, because warnings may occur in functions
|
384
472
|
w->perform(&eval);
|
385
473
|
return 0;
|
386
474
|
}
|
387
475
|
|
388
|
-
Statement* Expand::operator()(
|
476
|
+
Statement* Expand::operator()(ErrorRule* e)
|
389
477
|
{
|
390
478
|
// eval handles this too, because errors may occur in functions
|
391
479
|
e->perform(&eval);
|
392
480
|
return 0;
|
393
481
|
}
|
394
482
|
|
395
|
-
Statement* Expand::operator()(
|
483
|
+
Statement* Expand::operator()(DebugRule* d)
|
396
484
|
{
|
397
485
|
// eval handles this too, because warnings may occur in functions
|
398
486
|
d->perform(&eval);
|
@@ -418,7 +506,7 @@ namespace Sass {
|
|
418
506
|
Env env(environment(), true);
|
419
507
|
env_stack.push_back(&env);
|
420
508
|
call_stack.push_back(i);
|
421
|
-
|
509
|
+
ExpressionObj rv = i->predicate()->perform(&eval);
|
422
510
|
if (*rv) {
|
423
511
|
append_block(i->block());
|
424
512
|
}
|
@@ -433,15 +521,15 @@ namespace Sass {
|
|
433
521
|
|
434
522
|
// For does not create a new env scope
|
435
523
|
// But iteration vars are reset afterwards
|
436
|
-
Statement* Expand::operator()(
|
524
|
+
Statement* Expand::operator()(ForRule* f)
|
437
525
|
{
|
438
|
-
|
439
|
-
|
526
|
+
sass::string variable(f->variable());
|
527
|
+
ExpressionObj low = f->lower_bound()->perform(&eval);
|
440
528
|
if (low->concrete_type() != Expression::NUMBER) {
|
441
529
|
traces.push_back(Backtrace(low->pstate()));
|
442
530
|
throw Exception::TypeMismatch(traces, *low, "integer");
|
443
531
|
}
|
444
|
-
|
532
|
+
ExpressionObj high = f->upper_bound()->perform(&eval);
|
445
533
|
if (high->concrete_type() != Expression::NUMBER) {
|
446
534
|
traces.push_back(Backtrace(high->pstate()));
|
447
535
|
throw Exception::TypeMismatch(traces, *high, "integer");
|
@@ -450,7 +538,7 @@ namespace Sass {
|
|
450
538
|
Number_Obj sass_end = Cast<Number>(high);
|
451
539
|
// check if units are valid for sequence
|
452
540
|
if (sass_start->unit() != sass_end->unit()) {
|
453
|
-
|
541
|
+
sass::ostream msg; msg << "Incompatible units: '"
|
454
542
|
<< sass_start->unit() << "' and '"
|
455
543
|
<< sass_end->unit() << "'.";
|
456
544
|
error(msg.str(), low->pstate(), traces);
|
@@ -488,18 +576,17 @@ namespace Sass {
|
|
488
576
|
|
489
577
|
// Eval does not create a new env scope
|
490
578
|
// But iteration vars are reset afterwards
|
491
|
-
Statement* Expand::operator()(
|
579
|
+
Statement* Expand::operator()(EachRule* e)
|
492
580
|
{
|
493
|
-
|
494
|
-
|
581
|
+
sass::vector<sass::string> variables(e->variables());
|
582
|
+
ExpressionObj expr = e->list()->perform(&eval);
|
495
583
|
List_Obj list;
|
496
584
|
Map_Obj map;
|
497
585
|
if (expr->concrete_type() == Expression::MAP) {
|
498
586
|
map = Cast<Map>(expr);
|
499
587
|
}
|
500
|
-
else if (
|
501
|
-
Listize
|
502
|
-
Expression_Obj rv = ls->perform(&listize);
|
588
|
+
else if (SelectorList * ls = Cast<SelectorList>(expr)) {
|
589
|
+
ExpressionObj rv = Listize::perform(ls);
|
503
590
|
list = Cast<List>(rv);
|
504
591
|
}
|
505
592
|
else if (expr->concrete_type() != Expression::LIST) {
|
@@ -517,8 +604,8 @@ namespace Sass {
|
|
517
604
|
|
518
605
|
if (map) {
|
519
606
|
for (auto key : map->keys()) {
|
520
|
-
|
521
|
-
|
607
|
+
ExpressionObj k = key->perform(&eval);
|
608
|
+
ExpressionObj v = map->at(key)->perform(&eval);
|
522
609
|
|
523
610
|
if (variables.size() == 1) {
|
524
611
|
List_Obj variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
|
@@ -534,11 +621,11 @@ namespace Sass {
|
|
534
621
|
}
|
535
622
|
else {
|
536
623
|
// bool arglist = list->is_arglist();
|
537
|
-
if (list->length() == 1 && Cast<
|
624
|
+
if (list->length() == 1 && Cast<SelectorList>(list)) {
|
538
625
|
list = Cast<List>(list);
|
539
626
|
}
|
540
627
|
for (size_t i = 0, L = list->length(); i < L; ++i) {
|
541
|
-
|
628
|
+
ExpressionObj item = list->at(i);
|
542
629
|
// unwrap value if the expression is an argument
|
543
630
|
if (Argument_Obj arg = Cast<Argument>(item)) item = arg->value();
|
544
631
|
// check if we got passed a list of args (investigate)
|
@@ -549,17 +636,16 @@ namespace Sass {
|
|
549
636
|
env.set_local(variables[0], var);
|
550
637
|
} else {
|
551
638
|
for (size_t j = 0, K = variables.size(); j < K; ++j) {
|
552
|
-
|
639
|
+
env.set_local(variables[j], j >= scalars->length()
|
553
640
|
? SASS_MEMORY_NEW(Null, expr->pstate())
|
554
|
-
: (*scalars)[j]->perform(&eval);
|
555
|
-
env.set_local(variables[j], res);
|
641
|
+
: (*scalars)[j]->perform(&eval));
|
556
642
|
}
|
557
643
|
}
|
558
644
|
} else {
|
559
645
|
if (variables.size() > 0) {
|
560
646
|
env.set_local(variables.at(0), item);
|
561
647
|
for (size_t j = 1, K = variables.size(); j < K; ++j) {
|
562
|
-
|
648
|
+
ExpressionObj res = SASS_MEMORY_NEW(Null, expr->pstate());
|
563
649
|
env.set_local(variables[j], res);
|
564
650
|
}
|
565
651
|
}
|
@@ -572,14 +658,14 @@ namespace Sass {
|
|
572
658
|
return 0;
|
573
659
|
}
|
574
660
|
|
575
|
-
Statement* Expand::operator()(
|
661
|
+
Statement* Expand::operator()(WhileRule* w)
|
576
662
|
{
|
577
|
-
|
663
|
+
ExpressionObj pred = w->predicate();
|
578
664
|
Block* body = w->block();
|
579
665
|
Env env(environment(), true);
|
580
666
|
env_stack.push_back(&env);
|
581
667
|
call_stack.push_back(w);
|
582
|
-
|
668
|
+
ExpressionObj cond = pred->perform(&eval);
|
583
669
|
while (!cond->is_false()) {
|
584
670
|
append_block(body);
|
585
671
|
cond = pred->perform(&eval);
|
@@ -595,87 +681,63 @@ namespace Sass {
|
|
595
681
|
return 0;
|
596
682
|
}
|
597
683
|
|
684
|
+
Statement* Expand::operator()(ExtendRule* e)
|
685
|
+
{
|
598
686
|
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
Complex_Selector_Obj tail = complex_selector;
|
604
|
-
while (tail) {
|
605
|
-
if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
|
606
|
-
if (Cast<Parent_Selector>(header) == NULL) continue; // skip all others
|
607
|
-
std::string sel_str(complex_selector->to_string(ctx.c_options));
|
608
|
-
error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), traces);
|
609
|
-
}
|
610
|
-
tail = tail->tail();
|
611
|
-
}
|
612
|
-
}
|
687
|
+
// evaluate schema first
|
688
|
+
if (e->schema()) {
|
689
|
+
e->selector(eval(e->schema()));
|
690
|
+
e->isOptional(e->selector()->is_optional());
|
613
691
|
}
|
692
|
+
// evaluate the selector
|
693
|
+
e->selector(eval(e->selector()));
|
614
694
|
|
695
|
+
if (e->selector()) {
|
615
696
|
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
if (!c->head() || c->tail()) {
|
621
|
-
std::string sel_str(contextualized->to_string(ctx.c_options));
|
622
|
-
error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), traces);
|
623
|
-
}
|
624
|
-
Compound_Selector_Obj target = c->head();
|
625
|
-
if (contextualized->is_optional()) target->is_optional(true);
|
626
|
-
for (size_t i = 0, L = extender->length(); i < L; ++i) {
|
627
|
-
Complex_Selector_Obj sel = (*extender)[i];
|
628
|
-
if (!(sel->head() && sel->head()->length() > 0 &&
|
629
|
-
Cast<Parent_Selector>((*sel->head())[0])))
|
630
|
-
{
|
631
|
-
Compound_Selector_Obj hh = SASS_MEMORY_NEW(Compound_Selector, (*extender)[i]->pstate());
|
632
|
-
hh->media_block((*extender)[i]->media_block());
|
633
|
-
Complex_Selector_Obj ssel = SASS_MEMORY_NEW(Complex_Selector, (*extender)[i]->pstate());
|
634
|
-
ssel->media_block((*extender)[i]->media_block());
|
635
|
-
if (sel->has_line_feed()) ssel->has_line_feed(true);
|
636
|
-
Parent_Selector_Obj ps = SASS_MEMORY_NEW(Parent_Selector, (*extender)[i]->pstate());
|
637
|
-
ps->media_block((*extender)[i]->media_block());
|
638
|
-
hh->append(ps);
|
639
|
-
ssel->tail(sel);
|
640
|
-
ssel->head(hh);
|
641
|
-
sel = ssel;
|
697
|
+
for (auto complex : e->selector()->elements()) {
|
698
|
+
|
699
|
+
if (complex->length() != 1) {
|
700
|
+
error("complex selectors may not be extended.", complex->pstate(), traces);
|
642
701
|
}
|
643
|
-
// if (c->has_line_feed()) sel->has_line_feed(true);
|
644
|
-
ctx.subset_map.put(target, std::make_pair(sel, target));
|
645
|
-
}
|
646
|
-
}
|
647
702
|
|
648
|
-
|
703
|
+
if (const CompoundSelector* compound = complex->first()->getCompound()) {
|
704
|
+
|
705
|
+
if (compound->length() != 1) {
|
706
|
+
|
707
|
+
sass::ostream sels; bool addComma = false;
|
708
|
+
sels << "Compound selectors may no longer be extended.\n";
|
709
|
+
sels << "Consider `@extend ";
|
710
|
+
for (auto sel : compound->elements()) {
|
711
|
+
if (addComma) sels << ", ";
|
712
|
+
sels << sel->to_sass();
|
713
|
+
addComma = true;
|
714
|
+
}
|
715
|
+
sels << "` instead.\n";
|
716
|
+
sels << "See http://bit.ly/ExtendCompound for details.";
|
717
|
+
|
718
|
+
warning(sels.str(), compound->pstate());
|
719
|
+
|
720
|
+
// Make this an error once deprecation is over
|
721
|
+
for (SimpleSelectorObj simple : compound->elements()) {
|
722
|
+
// Pass every selector we ever see to extender (to make them findable for extend)
|
723
|
+
ctx.extender.addExtension(selector(), simple, mediaStack.back(), e->isOptional());
|
724
|
+
}
|
725
|
+
|
726
|
+
}
|
727
|
+
else {
|
728
|
+
// Pass every selector we ever see to extender (to make them findable for extend)
|
729
|
+
ctx.extender.addExtension(selector(), compound->first(), mediaStack.back(), e->isOptional());
|
730
|
+
}
|
649
731
|
|
650
|
-
Statement* Expand::operator()(Extension* e)
|
651
|
-
{
|
652
|
-
if (Selector_List_Obj extender = selector()) {
|
653
|
-
Selector_List* sl = e->selector();
|
654
|
-
// abort on invalid selector
|
655
|
-
if (sl == NULL) return NULL;
|
656
|
-
if (Selector_Schema* schema = sl->schema()) {
|
657
|
-
if (schema->has_real_parent_ref()) {
|
658
|
-
// put root block on stack again (ignore parents)
|
659
|
-
// selector schema must not connect in eval!
|
660
|
-
block_stack.push_back(block_stack.at(1));
|
661
|
-
sl = eval(sl->schema());
|
662
|
-
block_stack.pop_back();
|
663
|
-
} else {
|
664
|
-
selector_stack.push_back({});
|
665
|
-
sl = eval(sl->schema());
|
666
|
-
selector_stack.pop_back();
|
667
732
|
}
|
668
|
-
|
669
|
-
|
670
|
-
if (!cs.isNull() && !cs->head().isNull()) {
|
671
|
-
cs->head()->media_block(media_stack.back());
|
733
|
+
else {
|
734
|
+
error("complex selectors may not be extended.", complex->pstate(), traces);
|
672
735
|
}
|
673
736
|
}
|
674
|
-
selector_stack.push_back({});
|
675
|
-
expand_selector_list(sl, extender);
|
676
|
-
selector_stack.pop_back();
|
677
737
|
}
|
678
|
-
|
738
|
+
|
739
|
+
return nullptr;
|
740
|
+
|
679
741
|
}
|
680
742
|
|
681
743
|
Statement* Expand::operator()(Definition* d)
|
@@ -705,6 +767,7 @@ namespace Sass {
|
|
705
767
|
|
706
768
|
Statement* Expand::operator()(Mixin_Call* c)
|
707
769
|
{
|
770
|
+
|
708
771
|
if (recursions > maxRecursion) {
|
709
772
|
throw Exception::StackError(traces, *c);
|
710
773
|
}
|
@@ -712,7 +775,7 @@ namespace Sass {
|
|
712
775
|
recursions ++;
|
713
776
|
|
714
777
|
Env* env = environment();
|
715
|
-
|
778
|
+
sass::string full_name(c->name() + "[m]");
|
716
779
|
if (!env->has(full_name)) {
|
717
780
|
error("no mixin named " + c->name(), c->pstate(), traces);
|
718
781
|
}
|
@@ -723,15 +786,15 @@ namespace Sass {
|
|
723
786
|
if (c->block() && c->name() != "@content" && !body->has_content()) {
|
724
787
|
error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(), traces);
|
725
788
|
}
|
726
|
-
|
789
|
+
ExpressionObj rv = c->arguments()->perform(&eval);
|
727
790
|
Arguments_Obj args = Cast<Arguments>(rv);
|
728
|
-
|
791
|
+
sass::string msg(", in mixin `" + c->name() + "`");
|
729
792
|
traces.push_back(Backtrace(c->pstate(), msg));
|
730
793
|
ctx.callee_stack.push_back({
|
731
794
|
c->name().c_str(),
|
732
|
-
c->pstate().
|
733
|
-
c->pstate().
|
734
|
-
c->pstate().
|
795
|
+
c->pstate().getPath(),
|
796
|
+
c->pstate().getLine(),
|
797
|
+
c->pstate().getColumn(),
|
735
798
|
SASS_CALLEE_MIXIN,
|
736
799
|
{ env }
|
737
800
|
});
|
@@ -752,7 +815,7 @@ namespace Sass {
|
|
752
815
|
new_env.local_frame()["@content[m]"] = thunk;
|
753
816
|
}
|
754
817
|
|
755
|
-
bind(
|
818
|
+
bind(sass::string("Mixin"), c->name(), params, args, &new_env, &eval, traces);
|
756
819
|
|
757
820
|
Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate());
|
758
821
|
Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block);
|
@@ -763,7 +826,7 @@ namespace Sass {
|
|
763
826
|
}
|
764
827
|
block_stack.push_back(trace_block);
|
765
828
|
for (auto bb : body->elements()) {
|
766
|
-
if (
|
829
|
+
if (StyleRule* r = Cast<StyleRule>(bb)) {
|
767
830
|
r->is_root(trace_block->is_root());
|
768
831
|
}
|
769
832
|
Statement_Obj ith = bb->perform(this);
|
@@ -785,11 +848,6 @@ namespace Sass {
|
|
785
848
|
Env* env = environment();
|
786
849
|
// convert @content directives into mixin calls to the underlying thunk
|
787
850
|
if (!env->has("@content[m]")) return 0;
|
788
|
-
|
789
|
-
if (block_stack.back()->is_root()) {
|
790
|
-
selector_stack.push_back({});
|
791
|
-
}
|
792
|
-
|
793
851
|
Arguments_Obj args = c->arguments();
|
794
852
|
if (!args) args = SASS_MEMORY_NEW(Arguments, c->pstate());
|
795
853
|
|
@@ -799,11 +857,6 @@ namespace Sass {
|
|
799
857
|
args);
|
800
858
|
|
801
859
|
Trace_Obj trace = Cast<Trace>(call->perform(this));
|
802
|
-
|
803
|
-
if (block_stack.back()->is_root()) {
|
804
|
-
selector_stack.pop_back();
|
805
|
-
}
|
806
|
-
|
807
860
|
return trace.detach();
|
808
861
|
}
|
809
862
|
|