sassc 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|