Skip to content

Commit

Permalink
Implement passing arguments to @content
Browse files Browse the repository at this point in the history
  • Loading branch information
xzyfer committed Nov 26, 2018
1 parent eb15533 commit c04f5d7
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 19 deletions.
16 changes: 9 additions & 7 deletions src/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -994,14 +994,16 @@ namespace Sass {
class Mixin_Call final : public Has_Block {
ADD_CONSTREF(std::string, name)
ADD_PROPERTY(Arguments_Obj, arguments)
ADD_PROPERTY(Parameters_Obj, block_parameters)
public:
Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Block_Obj b = {})
: Has_Block(pstate, b), name_(n), arguments_(args)
Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Parameters_Obj b_params = {}, Block_Obj b = {})
: Has_Block(pstate, b), name_(n), arguments_(args), block_parameters_(b_params)
{ }
Mixin_Call(const Mixin_Call* ptr)
: Has_Block(ptr),
name_(ptr->name_),
arguments_(ptr->arguments_)
arguments_(ptr->arguments_),
block_parameters_(ptr->block_parameters_)
{ }
ATTACH_AST_OPERATIONS(Mixin_Call)
ATTACH_CRTP_PERFORM_METHODS()
Expand All @@ -1011,15 +1013,15 @@ namespace Sass {
// The @content directive for mixin content blocks.
///////////////////////////////////////////////////
class Content final : public Statement {
ADD_PROPERTY(Media_Block_Ptr, media_block)
ADD_PROPERTY(Arguments_Obj, arguments)
public:
Content(ParserState pstate)
Content(ParserState pstate, Arguments_Obj args)
: Statement(pstate),
media_block_(NULL)
arguments_(args)
{ statement_type(CONTENT); }
Content(const Content* ptr)
: Statement(ptr),
media_block_(ptr->media_block_)
arguments_(ptr->arguments_)
{ statement_type(CONTENT); }
ATTACH_AST_OPERATIONS(Content)
ATTACH_CRTP_PERFORM_METHODS()
Expand Down
3 changes: 3 additions & 0 deletions src/constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ namespace Sass {
extern const char true_kwd[] = "true";
extern const char false_kwd[] = "false";

// definition keywords
extern const char using_kwd[] = "using";

// miscellaneous punctuation and delimiters
extern const char percent_str[] = "%";
extern const char empty_str[] = "";
Expand Down
3 changes: 3 additions & 0 deletions src/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ namespace Sass {
extern const char true_kwd[];
extern const char false_kwd[];

// definition keywords
extern const char using_kwd[];

// miscellaneous punctuation and delimiters
extern const char percent_str[];
extern const char empty_str[];
Expand Down
11 changes: 3 additions & 8 deletions src/debugger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,8 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
Content_Ptr block = Cast<Content>(node);
std::cerr << ind << "Content " << block;
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [@media:" << block->media_block() << "]";
std::cerr << " " << block->tabs() << std::endl;
debug_ast(block->arguments(), ind + " args: ", env);
} else if (Cast<Import_Stub>(node)) {
Import_Stub_Ptr block = Cast<Import_Stub>(node);
std::cerr << ind << "Import_Stub " << block;
Expand Down Expand Up @@ -480,7 +480,8 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
std::cerr << " (" << pstate_source_position(block) << ")";
std::cerr << " [" << block->name() << "]";
std::cerr << " [has_content: " << block->has_content() << "] " << std::endl;
debug_ast(block->arguments(), ind + " args: ");
debug_ast(block->arguments(), ind + " args: ", env);
debug_ast(block->block_parameters(), ind + " block_params: ", env);
if (block->block()) debug_ast(block->block(), ind + " ", env);
} else if (Ruleset_Ptr ruleset = Cast<Ruleset>(node)) {
std::cerr << ind << "Ruleset " << ruleset;
Expand Down Expand Up @@ -605,12 +606,6 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
" [hash: " << expression->hash() << "] " <<
std::endl;
for(const auto& i : expression->elements()) { debug_ast(i, ind + " ", env); }
} else if (Cast<Content>(node)) {
Content_Ptr expression = Cast<Content>(node);
std::cerr << ind << "Content " << expression;
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [@media:" << expression->media_block() << "]";
std::cerr << " [Statement]" << std::endl;
} else if (Cast<Boolean>(node)) {
Boolean_Ptr expression = Cast<Boolean>(node);
std::cerr << ind << "Boolean " << expression;
Expand Down
9 changes: 7 additions & 2 deletions src/expand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,11 +730,13 @@ namespace Sass {
Env new_env(def->environment());
env_stack.push_back(&new_env);
if (c->block()) {
Parameters_Obj params = c->block_parameters();
if (!params) params = SASS_MEMORY_NEW(Parameters, c->pstate());
// represent mixin content blocks as thunks/closures
Definition_Obj thunk = SASS_MEMORY_NEW(Definition,
c->pstate(),
"@content",
SASS_MEMORY_NEW(Parameters, c->pstate()),
params,
c->block(),
Definition::MIXIN);
thunk->environment(env);
Expand Down Expand Up @@ -779,10 +781,13 @@ namespace Sass {
selector_stack.push_back({});
}

Arguments_Obj args = c->arguments();
if (!args) args = SASS_MEMORY_NEW(Arguments, c->pstate());

Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call,
c->pstate(),
"@content",
SASS_MEMORY_NEW(Arguments, c->pstate()));
args);

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

Expand Down
21 changes: 19 additions & 2 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,13 +644,27 @@ namespace Sass {
// normalize underscores to hyphens
std::string name(Util::normalize_underscores(lexed));
// create the initial mixin call object
Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, {}, {});
Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, {}, {}, {});
// parse mandatory arguments
call->arguments(parse_arguments());
// parse using and optional block parameters
bool has_parameters = lex< kwd_using >();

if (has_parameters) {
if (!peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \"(\", was ");
} else {
if (peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \";\", was ");
}

if (has_parameters) call->block_parameters(parse_parameters());

// parse optional block
if (peek < exactly <'{'> >()) {
call->block(parse_block());
}
else if (has_parameters) {
css_error("Invalid CSS", " after ", ": expected \"{\", was ");
}
// return ast node
return call.detach();
}
Expand Down Expand Up @@ -2202,7 +2216,10 @@ namespace Sass {

Content_Obj Parser::parse_content_directive()
{
return SASS_MEMORY_NEW(Content, pstate);
ParserState call_pos = pstate;
Arguments_Obj args = parse_arguments();

return SASS_MEMORY_NEW(Content, call_pos, args);
}

If_Obj Parser::parse_if_directive(bool else_if)
Expand Down
3 changes: 3 additions & 0 deletions src/prelexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,9 @@ namespace Sass {
const char* kwd_lte(const char* src) {
return exactly<lte>(src);
}
const char* kwd_using(const char* src) {
return keyword<using_kwd>(src);
}

// match specific IE syntax
const char* ie_progid(const char* src) {
Expand Down
1 change: 1 addition & 0 deletions src/prelexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace Sass {
const char* kwd_gte(const char* src);
const char* kwd_lt(const char* src);
const char* kwd_lte(const char* src);
const char* kwd_using(const char* src);

// Match standard control chars
const char* kwd_at(const char* src);
Expand Down

0 comments on commit c04f5d7

Please sign in to comment.