@@ -12,6 +12,7 @@ namespace Sass {
12
12
void bind (std::string type, std::string name, Parameters* ps, Arguments* as, Context* ctx, Env* env, Eval* eval)
13
13
{
14
14
std::string callee (type + " " + name);
15
+
15
16
Listize listize (*ctx);
16
17
std::map<std::string, Parameter*> param_map;
17
18
@@ -60,18 +61,9 @@ namespace Sass {
60
61
if (p->is_rest_parameter ()) {
61
62
// The next argument by coincidence provides a rest argument
62
63
if (a->is_rest_argument ()) {
64
+
63
65
// We should always get a list for rest arguments
64
66
if (List* rest = dynamic_cast <List*>(a->value ())) {
65
- // arg contains a list
66
- List* args = rest;
67
- // make sure it's an arglist
68
- if (rest->is_arglist ()) {
69
- // can pass it through as it was
70
- env->local_frame ()[p->name ()] = args;
71
- }
72
- // create a new list and wrap each item as an argument
73
- // otherwise we will not be able to fetch it again
74
- else {
75
67
// create a new list object for wrapped items
76
68
List* arglist = SASS_MEMORY_NEW (ctx->mem , List,
77
69
p->pstate (),
@@ -80,17 +72,20 @@ namespace Sass {
80
72
true );
81
73
// wrap each item from list as an argument
82
74
for (Expression* item : rest->elements ()) {
83
- (*arglist) << SASS_MEMORY_NEW (ctx->mem , Argument,
84
- item->pstate (),
85
- item,
86
- " " ,
87
- false ,
88
- false );
75
+ if (Argument* arg = dynamic_cast <Argument*>(item)) {
76
+ (*arglist) << SASS_MEMORY_NEW (ctx->mem , Argument, *arg);
77
+ } else {
78
+ (*arglist) << SASS_MEMORY_NEW (ctx->mem , Argument,
79
+ item->pstate (),
80
+ item,
81
+ " " ,
82
+ false ,
83
+ false );
84
+ }
89
85
}
90
86
// assign new arglist to environment
91
87
env->local_frame ()[p->name ()] = arglist;
92
88
}
93
- }
94
89
// invalid state
95
90
else {
96
91
throw std::runtime_error (" invalid state" );
@@ -127,27 +122,27 @@ namespace Sass {
127
122
List* ls = dynamic_cast <List*>(a->value ());
128
123
// skip any list completely if empty
129
124
if (ls && ls->empty () && a->is_rest_argument ()) continue ;
130
- // flatten all nested arglists
131
- if (ls && ls->is_arglist ()) {
132
- for (size_t i = 0 , L = ls->size (); i < L; ++i) {
133
- // already have a wrapped argument
134
- if (Argument* arg = dynamic_cast <Argument*>((*ls)[i])) {
135
- (*arglist) << SASS_MEMORY_NEW (ctx->mem , Argument, *arg);
136
- }
137
- // wrap all other value types into Argument
138
- else {
125
+
126
+ if (Argument* arg = dynamic_cast <Argument*>(a->value ())) {
127
+ (*arglist) << SASS_MEMORY_NEW (ctx->mem , Argument, *arg);
128
+ }
129
+ // check if we have rest argument
130
+ else if (a->is_rest_argument ()) {
131
+ // preserve the list separator from rest args
132
+ if (List* rest = dynamic_cast <List*>(a->value ())) {
133
+ arglist->separator (rest->separator ());
134
+
135
+ for (size_t i = 0 , L = rest->size (); i < L; ++i) {
139
136
(*arglist) << SASS_MEMORY_NEW (ctx->mem , Argument,
140
- (*ls )[i]->pstate (),
141
- (*ls )[i],
137
+ (*rest )[i]->pstate (),
138
+ (*rest )[i],
142
139
" " ,
143
140
false ,
144
141
false );
145
142
}
146
143
}
147
- }
148
- // already have a wrapped argument
149
- else if (Argument* arg = dynamic_cast <Argument*>(a->value ())) {
150
- (*arglist) << SASS_MEMORY_NEW (ctx->mem , Argument, *arg);
144
+ // no more arguments
145
+ break ;
151
146
}
152
147
// wrap all other value types into Argument
153
148
else {
@@ -158,15 +153,6 @@ namespace Sass {
158
153
false ,
159
154
false );
160
155
}
161
- // check if we have rest argument
162
- if (a->is_rest_argument ()) {
163
- // preserve the list separator from rest args
164
- if (List* rest = dynamic_cast <List*>(a->value ())) {
165
- arglist->separator (rest->separator ());
166
- }
167
- // no more arguments
168
- break ;
169
- }
170
156
}
171
157
// assign new arglist to environment
172
158
env->local_frame ()[p->name ()] = arglist;
@@ -185,14 +171,18 @@ namespace Sass {
185
171
if (!arglist->length ()) {
186
172
break ;
187
173
} else {
188
- if (arglist->length () + ia > LP && !ps->has_rest_parameter ()) {
174
+ if (arglist->length () > LP - ip && !ps->has_rest_parameter ()) {
189
175
int arg_count = (arglist->length () + LA - 1 );
190
176
std::stringstream msg;
191
177
msg << callee << " takes " << LP;
192
178
msg << (LP == 1 ? " argument" : " arguments" );
193
179
msg << " but " << arg_count;
194
180
msg << (arg_count == 1 ? " was passed" : " were passed." );
195
181
deprecated_bind (msg.str (), as->pstate ());
182
+
183
+ while (arglist->length () > LP - ip) {
184
+ arglist->elements ().erase (arglist->elements ().end () - 1 );
185
+ }
196
186
}
197
187
}
198
188
// otherwise move one of the rest args into the param, converting to argument if necessary
@@ -209,6 +199,7 @@ namespace Sass {
209
199
if (!arglist->length () || (!arglist->is_arglist () && ip + 1 == LP)) {
210
200
++ia;
211
201
}
202
+
212
203
} else if (a->is_keyword_argument ()) {
213
204
Map* argmap = static_cast <Map*>(a->value ());
214
205
0 commit comments