Commit 21f6a358 by Aaron Leung

Handling Sass's scoping and shadowing behavior properly with regard to mixins.

parent e0aec359
......@@ -20,7 +20,7 @@ namespace Sass {
}
else if (peek< include >(position)) {
Node call(parse_mixin_call());
call << root;
// call << root;
root << call;
lex< exactly<';'> >();
context.pending.push_back(call);
......@@ -331,13 +331,14 @@ namespace Sass {
}
else if (peek< include >(position)) {
Node call(parse_mixin_call());
call << block;
// call << block;
block << call;
if (!definition) context.pending.push_back(call);
}
else if (lex< variable >()) {
Node assn(parse_assignment());
semicolon = true;
block << assn;
if (!definition) context.pending.push_back(assn);
}
// else if (look_for_rule(position)) {
......
......@@ -11,22 +11,24 @@ namespace Sass {
{
case Node::mixin: {
env[expr[0].token] = expr;
// cerr << "DEFINED MIXIN: " << string(expr[0].token) << endl << endl;
return expr;
} break;
case Node::expansion: {
Token name(expr[0].token);
// cerr << "EVALUATING EXPANSION: " << string(name) << endl;
Node args(expr[1]);
Node parent(expr[2]);
// Node parent(expr[2]);
Node mixin(env[name]);
Node expansion(apply(mixin, args, env));
parent.has_rules_or_comments |= expansion.has_rules_or_comments;
parent.has_rulesets |= expansion.has_rulesets;
parent.has_propsets |= expansion.has_propsets;
// Node expansion(apply(mixin, args, env));
// parent.has_rules_or_comments |= expansion.has_rules_or_comments;
// parent.has_rulesets |= expansion.has_rulesets;
// parent.has_propsets |= expansion.has_propsets;
expr.children->pop_back();
expr.children->pop_back();
expr.children->pop_back();
expr += expansion;
// expr.children->pop_back();
expr += Node(apply(mixin, args, env));
return expr;
} break;
......@@ -224,9 +226,11 @@ namespace Sass {
Node apply(Node& mixin, const Node& args, Environment& env)
{
// cerr << "APPLYING MIXIN: " << string(mixin[0].token) << endl;
Node params(mixin[1]);
Node body(mixin[2].clone());
Environment m_env;
// cerr << "CLONED BODY" << endl;
// bind arguments
for (int i = 0, j = 0; i < args.size(); ++i) {
if (args[i].type == Node::assignment) {
......@@ -244,6 +248,7 @@ namespace Sass {
++j;
}
}
// cerr << "BOUND ARGS FOR " << string(mixin[0].token) << endl;
// plug the holes with default arguments if any
for (int i = 0; i < params.size(); ++i) {
if (params[i].type == Node::assignment) {
......@@ -254,8 +259,9 @@ namespace Sass {
}
}
}
m_env.link(env);
// cerr << "BOUND DEFAULT ARGS FOR " << string(mixin[0].token) << endl;
m_env.link(env.parent ? *env.parent : env);
// cerr << "LINKED ENVIRONMENT FOR " << string(mixin[0].token) << endl << endl;
for (int i = 0; i < body.size(); ++i) {
body[i] = eval(body[i], m_env);
}
......
$x: global x;
$y: global y;
@mixin foo($x) {
f-a: $x;
f-b: $y;
$x: local x changed by foo;
$y: global y changed by foo;
f-a: $x;
f-b: $y;
}
div {
a: $x;
b: $y;
@include foo(arg);
a: $x;
b: $y;
}
\ No newline at end of file
div {
a: global x;
b: global y;
f-a: arg;
f-b: global y;
f-a: local x changed by foo;
f-b: global y changed by foo;
a: global x;
b: global y changed by foo; }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment