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 { ...@@ -20,7 +20,7 @@ namespace Sass {
} }
else if (peek< include >(position)) { else if (peek< include >(position)) {
Node call(parse_mixin_call()); Node call(parse_mixin_call());
call << root; // call << root;
root << call; root << call;
lex< exactly<';'> >(); lex< exactly<';'> >();
context.pending.push_back(call); context.pending.push_back(call);
...@@ -331,13 +331,14 @@ namespace Sass { ...@@ -331,13 +331,14 @@ namespace Sass {
} }
else if (peek< include >(position)) { else if (peek< include >(position)) {
Node call(parse_mixin_call()); Node call(parse_mixin_call());
call << block; // call << block;
block << call; block << call;
if (!definition) context.pending.push_back(call); if (!definition) context.pending.push_back(call);
} }
else if (lex< variable >()) { else if (lex< variable >()) {
Node assn(parse_assignment()); Node assn(parse_assignment());
semicolon = true; semicolon = true;
block << assn;
if (!definition) context.pending.push_back(assn); if (!definition) context.pending.push_back(assn);
} }
// else if (look_for_rule(position)) { // else if (look_for_rule(position)) {
......
...@@ -11,22 +11,24 @@ namespace Sass { ...@@ -11,22 +11,24 @@ namespace Sass {
{ {
case Node::mixin: { case Node::mixin: {
env[expr[0].token] = expr; env[expr[0].token] = expr;
// cerr << "DEFINED MIXIN: " << string(expr[0].token) << endl << endl;
return expr; return expr;
} break; } break;
case Node::expansion: { case Node::expansion: {
Token name(expr[0].token); Token name(expr[0].token);
// cerr << "EVALUATING EXPANSION: " << string(name) << endl;
Node args(expr[1]); Node args(expr[1]);
Node parent(expr[2]); // Node parent(expr[2]);
Node mixin(env[name]); Node mixin(env[name]);
Node expansion(apply(mixin, args, env)); // Node expansion(apply(mixin, args, env));
parent.has_rules_or_comments |= expansion.has_rules_or_comments; // parent.has_rules_or_comments |= expansion.has_rules_or_comments;
parent.has_rulesets |= expansion.has_rulesets; // parent.has_rulesets |= expansion.has_rulesets;
parent.has_propsets |= expansion.has_propsets; // parent.has_propsets |= expansion.has_propsets;
expr.children->pop_back(); expr.children->pop_back();
expr.children->pop_back(); expr.children->pop_back();
expr.children->pop_back(); // expr.children->pop_back();
expr += expansion; expr += Node(apply(mixin, args, env));
return expr; return expr;
} break; } break;
...@@ -224,9 +226,11 @@ namespace Sass { ...@@ -224,9 +226,11 @@ namespace Sass {
Node apply(Node& mixin, const Node& args, Environment& env) Node apply(Node& mixin, const Node& args, Environment& env)
{ {
// cerr << "APPLYING MIXIN: " << string(mixin[0].token) << endl;
Node params(mixin[1]); Node params(mixin[1]);
Node body(mixin[2].clone()); Node body(mixin[2].clone());
Environment m_env; Environment m_env;
// cerr << "CLONED BODY" << endl;
// bind arguments // bind arguments
for (int i = 0, j = 0; i < args.size(); ++i) { for (int i = 0, j = 0; i < args.size(); ++i) {
if (args[i].type == Node::assignment) { if (args[i].type == Node::assignment) {
...@@ -244,6 +248,7 @@ namespace Sass { ...@@ -244,6 +248,7 @@ namespace Sass {
++j; ++j;
} }
} }
// cerr << "BOUND ARGS FOR " << string(mixin[0].token) << endl;
// plug the holes with default arguments if any // plug the holes with default arguments if any
for (int i = 0; i < params.size(); ++i) { for (int i = 0; i < params.size(); ++i) {
if (params[i].type == Node::assignment) { if (params[i].type == Node::assignment) {
...@@ -254,8 +259,9 @@ namespace Sass { ...@@ -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) { for (int i = 0; i < body.size(); ++i) {
body[i] = eval(body[i], m_env); 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