Skip to content

Commit 57f61c4

Browse files
committed
Implement passing arguments to @content
See sass/sass#871 Spec sass/sass-spec#1313 Fixes #2723
1 parent c93f058 commit 57f61c4

File tree

8 files changed

+48
-19
lines changed

8 files changed

+48
-19
lines changed

src/ast.hpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -994,14 +994,16 @@ namespace Sass {
994994
class Mixin_Call final : public Has_Block {
995995
ADD_CONSTREF(std::string, name)
996996
ADD_PROPERTY(Arguments_Obj, arguments)
997+
ADD_PROPERTY(Parameters_Obj, block_parameters)
997998
public:
998-
Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Block_Obj b = {})
999-
: Has_Block(pstate, b), name_(n), arguments_(args)
999+
Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Parameters_Obj b_params = {}, Block_Obj b = {})
1000+
: Has_Block(pstate, b), name_(n), arguments_(args), block_parameters_(b_params)
10001001
{ }
10011002
Mixin_Call(const Mixin_Call* ptr)
10021003
: Has_Block(ptr),
10031004
name_(ptr->name_),
1004-
arguments_(ptr->arguments_)
1005+
arguments_(ptr->arguments_),
1006+
block_parameters_(ptr->block_parameters_)
10051007
{ }
10061008
ATTACH_AST_OPERATIONS(Mixin_Call)
10071009
ATTACH_CRTP_PERFORM_METHODS()
@@ -1011,15 +1013,15 @@ namespace Sass {
10111013
// The @content directive for mixin content blocks.
10121014
///////////////////////////////////////////////////
10131015
class Content final : public Statement {
1014-
ADD_PROPERTY(Media_Block_Ptr, media_block)
1016+
ADD_PROPERTY(Arguments_Obj, arguments)
10151017
public:
1016-
Content(ParserState pstate)
1018+
Content(ParserState pstate, Arguments_Obj args)
10171019
: Statement(pstate),
1018-
media_block_(NULL)
1020+
arguments_(args)
10191021
{ statement_type(CONTENT); }
10201022
Content(const Content* ptr)
10211023
: Statement(ptr),
1022-
media_block_(ptr->media_block_)
1024+
arguments_(ptr->arguments_)
10231025
{ statement_type(CONTENT); }
10241026
ATTACH_AST_OPERATIONS(Content)
10251027
ATTACH_CRTP_PERFORM_METHODS()

src/constants.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ namespace Sass {
125125
extern const char true_kwd[] = "true";
126126
extern const char false_kwd[] = "false";
127127

128+
// definition keywords
129+
extern const char using_kwd[] = "using";
130+
128131
// miscellaneous punctuation and delimiters
129132
extern const char percent_str[] = "%";
130133
extern const char empty_str[] = "";

src/constants.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ namespace Sass {
127127
extern const char true_kwd[];
128128
extern const char false_kwd[];
129129

130+
// definition keywords
131+
extern const char using_kwd[];
132+
130133
// miscellaneous punctuation and delimiters
131134
extern const char percent_str[];
132135
extern const char empty_str[];

src/debugger.hpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,8 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
398398
Content_Ptr block = Cast<Content>(node);
399399
std::cerr << ind << "Content " << block;
400400
std::cerr << " (" << pstate_source_position(node) << ")";
401-
std::cerr << " [@media:" << block->media_block() << "]";
402401
std::cerr << " " << block->tabs() << std::endl;
402+
debug_ast(block->arguments(), ind + " args: ", env);
403403
} else if (Cast<Import_Stub>(node)) {
404404
Import_Stub_Ptr block = Cast<Import_Stub>(node);
405405
std::cerr << ind << "Import_Stub " << block;
@@ -480,7 +480,8 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
480480
std::cerr << " (" << pstate_source_position(block) << ")";
481481
std::cerr << " [" << block->name() << "]";
482482
std::cerr << " [has_content: " << block->has_content() << "] " << std::endl;
483-
debug_ast(block->arguments(), ind + " args: ");
483+
debug_ast(block->arguments(), ind + " args: ", env);
484+
debug_ast(block->block_parameters(), ind + " block_params: ", env);
484485
if (block->block()) debug_ast(block->block(), ind + " ", env);
485486
} else if (Ruleset_Ptr ruleset = Cast<Ruleset>(node)) {
486487
std::cerr << ind << "Ruleset " << ruleset;
@@ -605,12 +606,6 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
605606
" [hash: " << expression->hash() << "] " <<
606607
std::endl;
607608
for(const auto& i : expression->elements()) { debug_ast(i, ind + " ", env); }
608-
} else if (Cast<Content>(node)) {
609-
Content_Ptr expression = Cast<Content>(node);
610-
std::cerr << ind << "Content " << expression;
611-
std::cerr << " (" << pstate_source_position(node) << ")";
612-
std::cerr << " [@media:" << expression->media_block() << "]";
613-
std::cerr << " [Statement]" << std::endl;
614609
} else if (Cast<Boolean>(node)) {
615610
Boolean_Ptr expression = Cast<Boolean>(node);
616611
std::cerr << ind << "Boolean " << expression;

src/expand.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,11 +730,13 @@ namespace Sass {
730730
Env new_env(def->environment());
731731
env_stack.push_back(&new_env);
732732
if (c->block()) {
733+
Parameters_Obj params = c->block_parameters();
734+
if (!params) params = SASS_MEMORY_NEW(Parameters, c->pstate());
733735
// represent mixin content blocks as thunks/closures
734736
Definition_Obj thunk = SASS_MEMORY_NEW(Definition,
735737
c->pstate(),
736738
"@content",
737-
SASS_MEMORY_NEW(Parameters, c->pstate()),
739+
params,
738740
c->block(),
739741
Definition::MIXIN);
740742
thunk->environment(env);
@@ -779,10 +781,13 @@ namespace Sass {
779781
selector_stack.push_back({});
780782
}
781783

784+
Arguments_Obj args = c->arguments();
785+
if (!args) args = SASS_MEMORY_NEW(Arguments, c->pstate());
786+
782787
Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call,
783788
c->pstate(),
784789
"@content",
785-
SASS_MEMORY_NEW(Arguments, c->pstate()));
790+
args);
786791

787792
Trace_Obj trace = Cast<Trace>(call->perform(this));
788793

src/parser.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,13 +644,27 @@ namespace Sass {
644644
// normalize underscores to hyphens
645645
std::string name(Util::normalize_underscores(lexed));
646646
// create the initial mixin call object
647-
Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, {}, {});
647+
Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, {}, {}, {});
648648
// parse mandatory arguments
649649
call->arguments(parse_arguments());
650+
// parse using and optional block parameters
651+
bool has_parameters = lex< kwd_using >();
652+
653+
if (has_parameters) {
654+
if (!peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \"(\", was ");
655+
} else {
656+
if (peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \";\", was ");
657+
}
658+
659+
if (has_parameters) call->block_parameters(parse_parameters());
660+
650661
// parse optional block
651662
if (peek < exactly <'{'> >()) {
652663
call->block(parse_block());
653664
}
665+
else if (has_parameters) {
666+
css_error("Invalid CSS", " after ", ": expected \"{\", was ");
667+
}
654668
// return ast node
655669
return call.detach();
656670
}
@@ -2202,7 +2216,10 @@ namespace Sass {
22022216

22032217
Content_Obj Parser::parse_content_directive()
22042218
{
2205-
return SASS_MEMORY_NEW(Content, pstate);
2219+
ParserState call_pos = pstate;
2220+
Arguments_Obj args = parse_arguments();
2221+
2222+
return SASS_MEMORY_NEW(Content, call_pos, args);
22062223
}
22072224

22082225
If_Obj Parser::parse_if_directive(bool else_if)

src/prelexer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,9 @@ namespace Sass {
12601260
const char* kwd_lte(const char* src) {
12611261
return exactly<lte>(src);
12621262
}
1263+
const char* kwd_using(const char* src) {
1264+
return keyword<using_kwd>(src);
1265+
}
12631266

12641267
// match specific IE syntax
12651268
const char* ie_progid(const char* src) {

src/prelexer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace Sass {
2525
const char* kwd_gte(const char* src);
2626
const char* kwd_lt(const char* src);
2727
const char* kwd_lte(const char* src);
28+
const char* kwd_using(const char* src);
2829

2930
// Match standard control chars
3031
const char* kwd_at(const char* src);

0 commit comments

Comments
 (0)