@@ -202,7 +202,7 @@ namespace Sass {
202
202
if (!lex< identifier >()) throw_syntax_error (" invalid name in @include directive" );
203
203
Node name (context.new_Node (Node::identifier, path, line, lexed));
204
204
Node args (parse_arguments ());
205
- Node the_call (context.new_Node (Node::expansion , path, line, 2 ));
205
+ Node the_call (context.new_Node (Node::mixin_call , path, line, 2 ));
206
206
the_call << name << args;
207
207
return the_call;
208
208
}
@@ -215,12 +215,10 @@ namespace Sass {
215
215
if (lex< exactly<' (' > >()) {
216
216
if (!peek< exactly<' )' > >(position)) {
217
217
Node arg (parse_argument (Node::none));
218
- arg.should_eval () = true ;
219
218
args << arg;
220
219
if (arg.type () == Node::assignment) arg_type = Node::assignment;
221
220
while (lex< exactly<' ,' > >()) {
222
221
Node arg (parse_argument (arg_type));
223
- arg.should_eval () = true ;
224
222
args << arg;
225
223
if (arg.type () == Node::assignment) arg_type = Node::assignment;
226
224
}
@@ -239,6 +237,7 @@ namespace Sass {
239
237
Node var (context.new_Node (Node::variable, path, line, lexed));
240
238
lex< exactly<' :' > >();
241
239
Node val (parse_space_list ());
240
+ val.should_eval () = true ;
242
241
Node assn (context.new_Node (Node::assignment, path, line, 2 ));
243
242
assn << var << val;
244
243
return assn;
@@ -254,23 +253,14 @@ namespace Sass {
254
253
Node var (context.new_Node (Node::variable, path, line, lexed));
255
254
lex< exactly<' :' > >();
256
255
Node val (parse_space_list ());
256
+ val.should_eval () = true ;
257
257
Node assn (context.new_Node (Node::assignment, path, line, 2 ));
258
258
assn << var << val;
259
259
return assn;
260
260
}
261
- return parse_space_list ();
262
- // if (peek< sequence < variable, spaces_and_comments, exactly<':'> > >()) {
263
- // lex< variable >();
264
- // Node var(context.new_Node(Node::variable, path, line, lexed));
265
- // lex< exactly<':'> >();
266
- // Node val(parse_space_list());
267
- // Node assn(context.new_Node(Node::assignment, path, line, 2));
268
- // assn << var << val;
269
- // return assn;
270
- // }
271
- // else {
272
- // return parse_space_list();
273
- // }
261
+ Node val (parse_space_list ());
262
+ val.should_eval () = true ;
263
+ return val;
274
264
}
275
265
276
266
Node Document::parse_assignment ()
@@ -365,12 +355,15 @@ namespace Sass {
365
355
Node seq1 (parse_simple_selector_sequence ());
366
356
if (peek< exactly<' ,' > >() ||
367
357
peek< exactly<' )' > >() ||
368
- peek< exactly<' {' > >()) return seq1;
358
+ peek< exactly<' {' > >() ||
359
+ peek< exactly<' ;' > >()) return seq1;
369
360
370
361
Node selector (context.new_Node (Node::selector, path, line, 2 ));
371
362
selector << seq1;
372
363
373
- while (!peek< exactly<' {' > >() && !peek< exactly<' ,' > >()) {
364
+ while (!peek< exactly<' {' > >() &&
365
+ !peek< exactly<' ,' > >() &&
366
+ !peek< exactly<' ;' > >()) {
374
367
selector << parse_simple_selector_sequence ();
375
368
}
376
369
return selector;
@@ -598,11 +591,16 @@ namespace Sass {
598
591
semicolon = true ;
599
592
}
600
593
else if (lex< extend >()) {
601
- if (surrounding_ruleset.is_null_ptr ()) throw_syntax_error (" @extend directive may only be used within rules" );
602
- Node extendee (parse_simple_selector_sequence ());
603
- context.extensions .insert (pair<Node, Node>(extendee, surrounding_ruleset));
604
- context.has_extensions = true ;
594
+ Node request (context.new_Node (Node::extend_directive, path, line, 1 ));
595
+ Selector_Lookahead lookahead = lookahead_for_extension_target (position);
596
+
597
+ if (!lookahead.found ) throw_syntax_error (" invalid selector for @extend" );
598
+
599
+ if (lookahead.has_interpolants ) request << parse_selector_schema (lookahead.found );
600
+ else request << parse_selector_group ();
601
+
605
602
semicolon = true ;
603
+ block << request;
606
604
}
607
605
else if (peek< media >()) {
608
606
block << parse_media_query (inside_of);
@@ -1016,6 +1014,7 @@ namespace Sass {
1016
1014
if (lex< interpolant >()) {
1017
1015
Token insides (Token::make (lexed.begin + 2 , lexed.end - 1 ));
1018
1016
Node interp_node (Document::make_from_token (context, insides, path, line).parse_list ());
1017
+ interp_node.should_eval () = true ;
1019
1018
schema << interp_node;
1020
1019
}
1021
1020
else if (lex< identifier >()) {
@@ -1080,6 +1079,7 @@ namespace Sass {
1080
1079
else if (lex< interpolant >()) {
1081
1080
Token insides (Token::make (lexed.begin + 2 , lexed.end - 1 ));
1082
1081
Node interp_node (Document::make_from_token (context, insides, path, line).parse_list ());
1082
+ interp_node.should_eval () = true ;
1083
1083
schema << interp_node;
1084
1084
}
1085
1085
else if (lex< sequence< identifier, exactly<' :' > > >()) {
@@ -1343,5 +1343,56 @@ namespace Sass {
1343
1343
1344
1344
return result;
1345
1345
}
1346
+
1347
+ Selector_Lookahead Document::lookahead_for_extension_target (const char * start)
1348
+ {
1349
+ const char * p = start ? start : position;
1350
+ const char * q;
1351
+ bool saw_interpolant = false ;
1352
+
1353
+ while ((q = peek< identifier >(p)) ||
1354
+ (q = peek< id_name >(p)) ||
1355
+ (q = peek< class_name >(p)) ||
1356
+ (q = peek< sequence< pseudo_prefix, identifier > >(p)) ||
1357
+ (q = peek< string_constant >(p)) ||
1358
+ (q = peek< exactly<' *' > >(p)) ||
1359
+ (q = peek< exactly<' (' > >(p)) ||
1360
+ (q = peek< exactly<' )' > >(p)) ||
1361
+ (q = peek< exactly<' [' > >(p)) ||
1362
+ (q = peek< exactly<' ]' > >(p)) ||
1363
+ (q = peek< exactly<' +' > >(p)) ||
1364
+ (q = peek< exactly<' ~' > >(p)) ||
1365
+ (q = peek< exactly<' >' > >(p)) ||
1366
+ (q = peek< exactly<' ,' > >(p)) ||
1367
+ (q = peek< binomial >(p)) ||
1368
+ (q = peek< sequence< optional<sign>,
1369
+ optional<digits>,
1370
+ exactly<' n' > > >(p)) ||
1371
+ (q = peek< sequence< optional<sign>,
1372
+ digits > >(p)) ||
1373
+ (q = peek< number >(p)) ||
1374
+ (q = peek< exactly<' &' > >(p)) ||
1375
+ (q = peek< alternatives<exact_match,
1376
+ class_match,
1377
+ dash_match,
1378
+ prefix_match,
1379
+ suffix_match,
1380
+ substring_match> >(p)) ||
1381
+ (q = peek< sequence< exactly<' .' >, interpolant > >(p)) ||
1382
+ (q = peek< sequence< exactly<' #' >, interpolant > >(p)) ||
1383
+ (q = peek< sequence< exactly<' -' >, interpolant > >(p)) ||
1384
+ (q = peek< sequence< pseudo_prefix, interpolant > >(p)) ||
1385
+ (q = peek< interpolant >(p))) {
1386
+ p = q;
1387
+ if (*(p - 1 ) == ' }' ) saw_interpolant = true ;
1388
+ }
1389
+
1390
+ Selector_Lookahead result;
1391
+ result.found = peek< alternatives< exactly<' ;' >, exactly<' }' > > >(p) ? p : 0 ;
1392
+ result.has_interpolants = saw_interpolant;
1393
+
1394
+ return result;
1395
+ }
1396
+
1346
1397
1347
1398
}
0 commit comments