sassc 1.1.2 → 1.2.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/ext/libsass/ast.cpp +124 -43
- data/ext/libsass/ast.hpp +15 -7
- data/ext/libsass/bind.cpp +57 -10
- data/ext/libsass/context.cpp +9 -7
- data/ext/libsass/contextualize.cpp +7 -0
- data/ext/libsass/contextualize_eval.cpp +1 -1
- data/ext/libsass/debugger.hpp +27 -70
- data/ext/libsass/emitter.cpp +5 -2
- data/ext/libsass/emitter.hpp +7 -1
- data/ext/libsass/eval.cpp +27 -13
- data/ext/libsass/expand.cpp +2 -2
- data/ext/libsass/functions.cpp +34 -9
- data/ext/libsass/functions.hpp +2 -0
- data/ext/libsass/inspect.cpp +111 -39
- data/ext/libsass/lexer.cpp +8 -8
- data/ext/libsass/lexer.hpp +8 -8
- data/ext/libsass/output.cpp +13 -5
- data/ext/libsass/parser.cpp +185 -46
- data/ext/libsass/parser.hpp +4 -0
- data/ext/libsass/prelexer.cpp +58 -7
- data/ext/libsass/prelexer.hpp +20 -2
- data/ext/libsass/sass_values.cpp +1 -1
- data/ext/libsass/sass_values.h +1 -1
- data/ext/libsass/to_string.cpp +3 -3
- data/ext/libsass/to_string.hpp +2 -1
- data/ext/libsass/units.cpp +134 -34
- data/ext/libsass/units.hpp +78 -4
- data/ext/libsass/util.cpp +8 -10
- data/ext/libsass/util.hpp +1 -1
- data/lib/sassc/engine.rb +7 -3
- data/lib/sassc/version.rb +1 -1
- data/test/native_test.rb +1 -1
- data/test/output_style_test.rb +7 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc1ddb620763b2dad7308dd18a9c91c82192162d
|
4
|
+
data.tar.gz: c533165c997f081c2736e299e5de9da5bfe59d3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: addcd9ccee78f7b39e7c8931fbae374c19dee6601c14553255f3cc665c51985614c0b6a8abc223d3391b61f82170b296e64205693016fc71dd73c951f94b1a6b
|
7
|
+
data.tar.gz: 29f40e46fd1713286196044415f168b1e3b7c07169f54f9c564ef528d5d70357325bcdf27164018b94a88a974116e7dfe0be514b5099826b43070e83eb1a57e4
|
data/ext/libsass/ast.cpp
CHANGED
@@ -26,29 +26,29 @@ namespace Sass {
|
|
26
26
|
}
|
27
27
|
|
28
28
|
bool Complex_Selector::operator==(const Complex_Selector& rhs) const {
|
29
|
-
|
29
|
+
// TODO: We have to access the tail directly using tail_ since ADD_PROPERTY doesn't provide a const version.
|
30
30
|
|
31
|
-
|
31
|
+
const Complex_Selector* pOne = this;
|
32
32
|
const Complex_Selector* pTwo = &rhs;
|
33
33
|
|
34
34
|
// Consume any empty references at the beginning of the Complex_Selector
|
35
35
|
if (pOne->combinator() == Complex_Selector::ANCESTOR_OF && pOne->head()->is_empty_reference()) {
|
36
|
-
|
36
|
+
pOne = pOne->tail_;
|
37
37
|
}
|
38
38
|
if (pTwo->combinator() == Complex_Selector::ANCESTOR_OF && pTwo->head()->is_empty_reference()) {
|
39
|
-
|
39
|
+
pTwo = pTwo->tail_;
|
40
40
|
}
|
41
41
|
|
42
42
|
while (pOne && pTwo) {
|
43
|
-
|
44
|
-
|
43
|
+
if (pOne->combinator() != pTwo->combinator()) {
|
44
|
+
return false;
|
45
45
|
}
|
46
46
|
|
47
47
|
if (*(pOne->head()) != *(pTwo->head())) {
|
48
|
-
|
48
|
+
return false;
|
49
49
|
}
|
50
50
|
|
51
|
-
|
51
|
+
pOne = pOne->tail_;
|
52
52
|
pTwo = pTwo->tail_;
|
53
53
|
}
|
54
54
|
|
@@ -68,10 +68,10 @@ namespace Sass {
|
|
68
68
|
|
69
69
|
bool Simple_Selector::operator==(const Simple_Selector& rhs) const
|
70
70
|
{
|
71
|
-
|
71
|
+
// Compare the string representations for equality.
|
72
72
|
|
73
|
-
|
74
|
-
|
73
|
+
// Cast away const here. To_String should take a const object, but it doesn't.
|
74
|
+
Simple_Selector* pLHS = const_cast<Simple_Selector*>(this);
|
75
75
|
Simple_Selector* pRHS = const_cast<Simple_Selector*>(&rhs);
|
76
76
|
|
77
77
|
To_String to_string;
|
@@ -79,10 +79,10 @@ namespace Sass {
|
|
79
79
|
}
|
80
80
|
|
81
81
|
bool Simple_Selector::operator<(const Simple_Selector& rhs) const {
|
82
|
-
|
82
|
+
// Use the string representation for ordering.
|
83
83
|
|
84
|
-
|
85
|
-
|
84
|
+
// Cast away const here. To_String should take a const object, but it doesn't.
|
85
|
+
Simple_Selector* pLHS = const_cast<Simple_Selector*>(this);
|
86
86
|
Simple_Selector* pRHS = const_cast<Simple_Selector*>(&rhs);
|
87
87
|
|
88
88
|
To_String to_string;
|
@@ -217,32 +217,46 @@ namespace Sass {
|
|
217
217
|
set<string> lpsuedoset, rpsuedoset;
|
218
218
|
for (size_t i = 0, L = length(); i < L; ++i)
|
219
219
|
{
|
220
|
-
|
221
|
-
|
220
|
+
if ((*this)[i]->is_pseudo_element()) {
|
221
|
+
string pseudo((*this)[i]->perform(&to_string));
|
222
222
|
pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
|
223
|
-
|
223
|
+
lpsuedoset.insert(pseudo);
|
224
224
|
}
|
225
225
|
}
|
226
226
|
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
227
227
|
{
|
228
|
-
|
229
|
-
|
228
|
+
if ((*rhs)[i]->is_pseudo_element()) {
|
229
|
+
string pseudo((*rhs)[i]->perform(&to_string));
|
230
230
|
pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
|
231
|
-
|
231
|
+
rpsuedoset.insert(pseudo);
|
232
232
|
}
|
233
233
|
}
|
234
|
-
|
234
|
+
if (lpsuedoset != rpsuedoset) {
|
235
235
|
return false;
|
236
236
|
}
|
237
237
|
|
238
|
-
|
238
|
+
// Check the Simple_Selectors
|
239
239
|
|
240
240
|
set<string> lset, rset;
|
241
241
|
|
242
242
|
if (!lbase) // no lbase; just see if the left-hand qualifiers are a subset of the right-hand selector
|
243
243
|
{
|
244
244
|
for (size_t i = 0, L = length(); i < L; ++i)
|
245
|
-
{
|
245
|
+
{
|
246
|
+
Selector* lhs = (*this)[i];
|
247
|
+
// very special case for wrapped matches selector
|
248
|
+
if (Wrapped_Selector* wrapped = dynamic_cast<Wrapped_Selector*>(lhs)) {
|
249
|
+
if (wrapped->name() == ":matches(" || wrapped->name() == ":-moz-any(") {
|
250
|
+
if (Selector_List* list = dynamic_cast<Selector_List*>(wrapped->selector())) {
|
251
|
+
if (Compound_Selector* comp = dynamic_cast<Compound_Selector*>(rhs)) {
|
252
|
+
if (list->is_superselector_of(comp)) return true;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
}
|
256
|
+
}
|
257
|
+
// match from here on as strings
|
258
|
+
lset.insert(lhs->perform(&to_string));
|
259
|
+
}
|
246
260
|
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
247
261
|
{ rset.insert((*rhs)[i]->perform(&to_string)); }
|
248
262
|
return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
|
@@ -274,33 +288,33 @@ namespace Sass {
|
|
274
288
|
set<string> lpsuedoset, rpsuedoset;
|
275
289
|
for (size_t i = 0, L = length(); i < L; ++i)
|
276
290
|
{
|
277
|
-
|
278
|
-
|
291
|
+
if ((*this)[i]->is_pseudo_element()) {
|
292
|
+
string pseudo((*this)[i]->perform(&to_string));
|
279
293
|
pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
|
280
|
-
|
294
|
+
lpsuedoset.insert(pseudo);
|
281
295
|
}
|
282
296
|
}
|
283
297
|
for (size_t i = 0, L = rhs.length(); i < L; ++i)
|
284
298
|
{
|
285
|
-
|
286
|
-
|
299
|
+
if (rhs[i]->is_pseudo_element()) {
|
300
|
+
string pseudo(rhs[i]->perform(&to_string));
|
287
301
|
pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
|
288
|
-
|
302
|
+
rpsuedoset.insert(pseudo);
|
289
303
|
}
|
290
304
|
}
|
291
|
-
|
305
|
+
if (lpsuedoset != rpsuedoset) {
|
292
306
|
return false;
|
293
307
|
}
|
294
308
|
|
295
|
-
|
309
|
+
// Check the base
|
296
310
|
|
297
311
|
const Simple_Selector* const lbase = base();
|
298
312
|
const Simple_Selector* const rbase = rhs.base();
|
299
313
|
|
300
314
|
if ((lbase && !rbase) ||
|
301
|
-
|
315
|
+
(!lbase && rbase) ||
|
302
316
|
((lbase && rbase) && (*lbase != *rbase))) {
|
303
|
-
|
317
|
+
return false;
|
304
318
|
}
|
305
319
|
|
306
320
|
|
@@ -326,8 +340,6 @@ namespace Sass {
|
|
326
340
|
|
327
341
|
bool Complex_Selector::is_superselector_of(Compound_Selector* rhs)
|
328
342
|
{
|
329
|
-
if (length() != 1)
|
330
|
-
{ return false; }
|
331
343
|
return base()->is_superselector_of(rhs);
|
332
344
|
}
|
333
345
|
|
@@ -352,6 +364,16 @@ namespace Sass {
|
|
352
364
|
if (l_len == 1)
|
353
365
|
{ return lhs->head()->is_superselector_of(rhs->base()); }
|
354
366
|
|
367
|
+
// we have to look one tail deeper, since we cary the
|
368
|
+
// combinator around for it (which is important here)
|
369
|
+
if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) {
|
370
|
+
Complex_Selector* lhs_tail = lhs->tail();
|
371
|
+
Complex_Selector* rhs_tail = rhs->tail();
|
372
|
+
if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
|
373
|
+
if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false;
|
374
|
+
}
|
375
|
+
|
376
|
+
|
355
377
|
bool found = false;
|
356
378
|
Complex_Selector* marker = rhs;
|
357
379
|
for (size_t i = 0, L = rhs->length(); i < L; ++i) {
|
@@ -458,7 +480,7 @@ namespace Sass {
|
|
458
480
|
Complex_Selector* cpy = new (ctx.mem) Complex_Selector(*this);
|
459
481
|
|
460
482
|
if (head()) {
|
461
|
-
|
483
|
+
cpy->head(head()->clone(ctx));
|
462
484
|
}
|
463
485
|
|
464
486
|
if (tail()) {
|
@@ -493,6 +515,50 @@ namespace Sass {
|
|
493
515
|
#endif
|
494
516
|
}
|
495
517
|
|
518
|
+
// it's a superselector if every selector of the right side
|
519
|
+
// list is a superselector of the given left side selector
|
520
|
+
bool Complex_Selector::is_superselector_of(Selector_List *sub)
|
521
|
+
{
|
522
|
+
// Check every rhs selector against left hand list
|
523
|
+
for(size_t i = 0, L = sub->length(); i < L; ++i) {
|
524
|
+
if (!is_superselector_of((*sub)[i])) return false;
|
525
|
+
}
|
526
|
+
return true;
|
527
|
+
}
|
528
|
+
|
529
|
+
// it's a superselector if every selector of the right side
|
530
|
+
// list is a superselector of the given left side selector
|
531
|
+
bool Selector_List::is_superselector_of(Selector_List *sub)
|
532
|
+
{
|
533
|
+
// Check every rhs selector against left hand list
|
534
|
+
for(size_t i = 0, L = sub->length(); i < L; ++i) {
|
535
|
+
if (!is_superselector_of((*sub)[i])) return false;
|
536
|
+
}
|
537
|
+
return true;
|
538
|
+
}
|
539
|
+
|
540
|
+
// it's a superselector if every selector on the right side
|
541
|
+
// is a superselector of any one of the left side selectors
|
542
|
+
bool Selector_List::is_superselector_of(Compound_Selector *sub)
|
543
|
+
{
|
544
|
+
// Check every lhs selector against right hand
|
545
|
+
for(size_t i = 0, L = length(); i < L; ++i) {
|
546
|
+
if ((*this)[i]->is_superselector_of(sub)) return true;
|
547
|
+
}
|
548
|
+
return false;
|
549
|
+
}
|
550
|
+
|
551
|
+
// it's a superselector if every selector on the right side
|
552
|
+
// is a superselector of any one of the left side selectors
|
553
|
+
bool Selector_List::is_superselector_of(Complex_Selector *sub)
|
554
|
+
{
|
555
|
+
// Check every lhs selector against right hand
|
556
|
+
for(size_t i = 0, L = length(); i < L; ++i) {
|
557
|
+
if ((*this)[i]->is_superselector_of(sub)) return true;
|
558
|
+
}
|
559
|
+
return false;
|
560
|
+
}
|
561
|
+
|
496
562
|
/* not used anymore - remove?
|
497
563
|
Selector_Placeholder* Selector_List::find_placeholder()
|
498
564
|
{
|
@@ -663,7 +729,7 @@ namespace Sass {
|
|
663
729
|
// skip already canceled out unit
|
664
730
|
if (exponents[denom] >= 0) continue;
|
665
731
|
// skip all units we don't know how to convert
|
666
|
-
if (string_to_unit(denom) ==
|
732
|
+
if (string_to_unit(denom) == UNKNOWN) continue;
|
667
733
|
// now search for nominator
|
668
734
|
while (nom_it != nom_end)
|
669
735
|
{
|
@@ -672,7 +738,7 @@ namespace Sass {
|
|
672
738
|
// skip already canceled out unit
|
673
739
|
if (exponents[nom] <= 0) continue;
|
674
740
|
// skip all units we don't know how to convert
|
675
|
-
if (string_to_unit(nom) ==
|
741
|
+
if (string_to_unit(nom) == UNKNOWN) continue;
|
676
742
|
// we now have two convertable units
|
677
743
|
// add factor for current conversion
|
678
744
|
factor *= conversion_factor(nom, denom);
|
@@ -707,7 +773,10 @@ namespace Sass {
|
|
707
773
|
|
708
774
|
// maybe convert to other unit
|
709
775
|
// easier implemented on its own
|
710
|
-
convert(prefered);
|
776
|
+
try { convert(prefered); }
|
777
|
+
catch (incompatibleUnits& err)
|
778
|
+
{ error(err.what(), pstate()); }
|
779
|
+
catch (...) { throw; }
|
711
780
|
|
712
781
|
}
|
713
782
|
|
@@ -743,7 +812,7 @@ namespace Sass {
|
|
743
812
|
// skip already canceled out unit
|
744
813
|
if (exponents[denom] >= 0) continue;
|
745
814
|
// skip all units we don't know how to convert
|
746
|
-
if (string_to_unit(denom) ==
|
815
|
+
if (string_to_unit(denom) == UNKNOWN) continue;
|
747
816
|
// we now have two convertable units
|
748
817
|
// add factor for current conversion
|
749
818
|
factor *= conversion_factor(denom, prefered);
|
@@ -764,7 +833,7 @@ namespace Sass {
|
|
764
833
|
// skip already canceled out unit
|
765
834
|
if (exponents[nom] <= 0) continue;
|
766
835
|
// skip all units we don't know how to convert
|
767
|
-
if (string_to_unit(nom) ==
|
836
|
+
if (string_to_unit(nom) == UNKNOWN) continue;
|
768
837
|
// we now have two convertable units
|
769
838
|
// add factor for current conversion
|
770
839
|
factor *= conversion_factor(nom, prefered);
|
@@ -801,11 +870,11 @@ namespace Sass {
|
|
801
870
|
{
|
802
871
|
for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) {
|
803
872
|
string u(numerator_units_[i]);
|
804
|
-
if (string_to_unit(u) !=
|
873
|
+
if (string_to_unit(u) != UNKNOWN) return u;
|
805
874
|
}
|
806
875
|
for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) {
|
807
876
|
string u(denominator_units_[i]);
|
808
|
-
if (string_to_unit(u) !=
|
877
|
+
if (string_to_unit(u) != UNKNOWN) return u;
|
809
878
|
}
|
810
879
|
return string();
|
811
880
|
}
|
@@ -853,6 +922,18 @@ namespace Sass {
|
|
853
922
|
return operator==(&rhs);
|
854
923
|
}
|
855
924
|
|
925
|
+
size_t List::size() const {
|
926
|
+
if (!is_arglist_) return length();
|
927
|
+
// arglist expects a list of arguments
|
928
|
+
// so we need to break before keywords
|
929
|
+
for (size_t i = 0, L = length(); i < L; ++i) {
|
930
|
+
if (Argument* arg = dynamic_cast<Argument*>((*this)[i])) {
|
931
|
+
if (!arg->name().empty()) return i;
|
932
|
+
}
|
933
|
+
}
|
934
|
+
return length();
|
935
|
+
}
|
936
|
+
|
856
937
|
Expression* Hashed::at(Expression* k) const
|
857
938
|
{
|
858
939
|
if (elements_.count(k))
|
data/ext/libsass/ast.hpp
CHANGED
@@ -757,6 +757,7 @@ namespace Sass {
|
|
757
757
|
bool is_invisible() { return !length(); }
|
758
758
|
Expression* value_at_index(size_t i);
|
759
759
|
|
760
|
+
virtual size_t size() const;
|
760
761
|
virtual bool operator==(Expression& rhs) const;
|
761
762
|
virtual bool operator==(Expression* rhs) const;
|
762
763
|
|
@@ -1359,21 +1360,22 @@ namespace Sass {
|
|
1359
1360
|
////////////////////////////////////////////////////////
|
1360
1361
|
class String_Constant : public String {
|
1361
1362
|
ADD_PROPERTY(char, quote_mark);
|
1363
|
+
ADD_PROPERTY(bool, can_compress_whitespace);
|
1362
1364
|
ADD_PROPERTY(string, value);
|
1363
1365
|
protected:
|
1364
1366
|
size_t hash_;
|
1365
1367
|
public:
|
1366
1368
|
String_Constant(ParserState pstate, string val)
|
1367
|
-
: String(pstate), quote_mark_(0), value_(read_css_string(val)), hash_(0)
|
1369
|
+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val)), hash_(0)
|
1368
1370
|
{ }
|
1369
1371
|
String_Constant(ParserState pstate, const char* beg)
|
1370
|
-
: String(pstate), quote_mark_(0), value_(read_css_string(string(beg))), hash_(0)
|
1372
|
+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(string(beg))), hash_(0)
|
1371
1373
|
{ }
|
1372
1374
|
String_Constant(ParserState pstate, const char* beg, const char* end)
|
1373
|
-
: String(pstate), quote_mark_(0), value_(read_css_string(string(beg, end-beg))), hash_(0)
|
1375
|
+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(string(beg, end-beg))), hash_(0)
|
1374
1376
|
{ }
|
1375
1377
|
String_Constant(ParserState pstate, const Token& tok)
|
1376
|
-
: String(pstate), quote_mark_(0), value_(read_css_string(string(tok.begin, tok.end))), hash_(0)
|
1378
|
+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(string(tok.begin, tok.end))), hash_(0)
|
1377
1379
|
{ }
|
1378
1380
|
string type() { return "string"; }
|
1379
1381
|
static string type_name() { return "string"; }
|
@@ -1941,7 +1943,9 @@ namespace Sass {
|
|
1941
1943
|
return (*this)[0];
|
1942
1944
|
return 0;
|
1943
1945
|
}
|
1944
|
-
bool is_superselector_of(Compound_Selector*
|
1946
|
+
bool is_superselector_of(Compound_Selector* sub);
|
1947
|
+
// bool is_superselector_of(Complex_Selector* sub);
|
1948
|
+
// bool is_superselector_of(Selector_List* sub);
|
1945
1949
|
virtual unsigned long specificity()
|
1946
1950
|
{
|
1947
1951
|
int sum = 0;
|
@@ -1998,8 +2002,9 @@ namespace Sass {
|
|
1998
2002
|
Complex_Selector* context(Context&);
|
1999
2003
|
Complex_Selector* innermost();
|
2000
2004
|
size_t length();
|
2001
|
-
bool is_superselector_of(Compound_Selector*);
|
2002
|
-
bool is_superselector_of(Complex_Selector*);
|
2005
|
+
bool is_superselector_of(Compound_Selector* sub);
|
2006
|
+
bool is_superselector_of(Complex_Selector* sub);
|
2007
|
+
bool is_superselector_of(Selector_List* sub);
|
2003
2008
|
// virtual Selector_Placeholder* find_placeholder();
|
2004
2009
|
Combinator clear_innermost();
|
2005
2010
|
void set_innermost(Complex_Selector*, Combinator);
|
@@ -2084,6 +2089,9 @@ namespace Sass {
|
|
2084
2089
|
: Selector(pstate), Vectorized<Complex_Selector*>(s), wspace_(0)
|
2085
2090
|
{ }
|
2086
2091
|
// virtual Selector_Placeholder* find_placeholder();
|
2092
|
+
bool is_superselector_of(Compound_Selector* sub);
|
2093
|
+
bool is_superselector_of(Complex_Selector* sub);
|
2094
|
+
bool is_superselector_of(Selector_List* sub);
|
2087
2095
|
virtual unsigned long specificity()
|
2088
2096
|
{
|
2089
2097
|
unsigned long sum = 0;
|
data/ext/libsass/bind.cpp
CHANGED
@@ -47,14 +47,40 @@ namespace Sass {
|
|
47
47
|
|
48
48
|
// If the current parameter is the rest parameter, process and break the loop
|
49
49
|
if (p->is_rest_parameter()) {
|
50
|
+
// The next argument by coincidence provides a rest argument
|
50
51
|
if (a->is_rest_argument()) {
|
51
|
-
//
|
52
|
-
if (
|
53
|
-
|
54
|
-
|
52
|
+
// We should always get a list for rest arguments
|
53
|
+
if (List* rest = dynamic_cast<List*>(a->value())) {
|
54
|
+
// arg contains a list
|
55
|
+
List* args = rest;
|
56
|
+
// make sure it's an arglist
|
57
|
+
if (rest->is_arglist()) {
|
58
|
+
// can pass it through as it was
|
59
|
+
env->local_frame()[p->name()] = args;
|
60
|
+
}
|
61
|
+
// create a new list and wrap each item as an argument
|
62
|
+
// otherwise we will not be able to fetch it again
|
63
|
+
else {
|
64
|
+
// create a new list object for wrapped items
|
65
|
+
List* arglist = new (ctx.mem) List(p->pstate(),
|
66
|
+
0,
|
67
|
+
rest->separator(),
|
68
|
+
true);
|
69
|
+
// wrap each item from list as an argument
|
70
|
+
for (Expression* item : rest->elements()) {
|
71
|
+
(*arglist) << new (ctx.mem) Argument(item->pstate(),
|
72
|
+
item,
|
73
|
+
"",
|
74
|
+
false,
|
75
|
+
false);
|
76
|
+
}
|
77
|
+
// assign new arglist to environment
|
78
|
+
env->local_frame()[p->name()] = arglist;
|
79
|
+
}
|
55
80
|
}
|
81
|
+
// invalid state
|
56
82
|
else {
|
57
|
-
|
83
|
+
throw runtime_error("invalid state");
|
58
84
|
}
|
59
85
|
} else if (a->is_keyword_argument()) {
|
60
86
|
|
@@ -67,27 +93,43 @@ namespace Sass {
|
|
67
93
|
(*arglist) << new (ctx.mem) Argument(key->pstate(),
|
68
94
|
argmap->at(key),
|
69
95
|
name,
|
96
|
+
false,
|
70
97
|
false);
|
71
98
|
}
|
72
99
|
|
73
100
|
} else {
|
74
101
|
|
75
|
-
//
|
102
|
+
// create a new list object for wrapped items
|
76
103
|
List* arglist = new (ctx.mem) List(p->pstate(),
|
77
104
|
0,
|
78
105
|
List::COMMA,
|
79
106
|
true);
|
80
|
-
|
107
|
+
// consume the next args
|
81
108
|
while (ia < LA) {
|
82
|
-
|
109
|
+
// get and post inc
|
110
|
+
a = (*as)[ia++];
|
111
|
+
// wrap current argument into new object
|
83
112
|
(*arglist) << new (ctx.mem) Argument(a->pstate(),
|
84
113
|
a->value(),
|
85
114
|
a->name(),
|
115
|
+
false,
|
86
116
|
false);
|
87
|
-
|
117
|
+
// check if we have rest argument
|
118
|
+
if (a->is_rest_argument()) {
|
119
|
+
// preserve the list separator from rest args
|
120
|
+
if (List* rest = dynamic_cast<List*>(a->value())) {
|
121
|
+
arglist->separator(rest->separator());
|
122
|
+
}
|
123
|
+
// no more arguments
|
124
|
+
break;
|
125
|
+
}
|
88
126
|
}
|
127
|
+
// assign new arglist to environment
|
128
|
+
env->local_frame()[p->name()] = arglist;
|
89
129
|
}
|
130
|
+
// consumed parameter
|
90
131
|
++ip;
|
132
|
+
// no more paramaters
|
91
133
|
break;
|
92
134
|
}
|
93
135
|
|
@@ -104,7 +146,11 @@ namespace Sass {
|
|
104
146
|
a = static_cast<Argument*>((*arglist)[0]);
|
105
147
|
} else {
|
106
148
|
Expression* a_to_convert = (*arglist)[0];
|
107
|
-
a = new (ctx.mem) Argument(a_to_convert->pstate(),
|
149
|
+
a = new (ctx.mem) Argument(a_to_convert->pstate(),
|
150
|
+
a_to_convert,
|
151
|
+
"",
|
152
|
+
false,
|
153
|
+
false);
|
108
154
|
}
|
109
155
|
arglist->elements().erase(arglist->elements().begin());
|
110
156
|
if (!arglist->length() || (!arglist->is_arglist() && ip + 1 == LP)) {
|
@@ -162,6 +208,7 @@ namespace Sass {
|
|
162
208
|
env->local_frame()[a->name()] = a->value();
|
163
209
|
}
|
164
210
|
}
|
211
|
+
// EO while ia
|
165
212
|
|
166
213
|
// If we make it here, we're out of args but may have leftover params.
|
167
214
|
// That's only okay if they have default values, or were already bound by
|