diff --git a/debugger.hpp b/debugger.hpp index fdd2003c1d..e000e2fe3f 100644 --- a/debugger.hpp +++ b/debugger.hpp @@ -69,7 +69,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0) case Complex_Selector::ADJACENT_TO: cerr << "{+}"; break; case Complex_Selector::ANCESTOR_OF: cerr << "{ }"; break; } - cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << "> X <" << prettyprint(selector->pstate().token.ws_after()) << ">" << endl; + cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl; debug_ast(selector->head(), ind + " ", env); debug_ast(selector->tail(), ind + "-", env); } else if (dynamic_cast(node)) { @@ -81,7 +81,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0) << (selector->is_optional() ? " [is_optional]": " -") << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << - " <" << prettyprint(selector->pstate().token.ws_before()) << "> X <" << prettyprint(selector->pstate().token.ws_after()) << ">" << endl; + " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl; for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast(node)) { Propset* selector = dynamic_cast(node); @@ -105,7 +105,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0) } else if (dynamic_cast(node)) { Type_Selector* selector = dynamic_cast(node); cerr << ind << "Type_Selector " << selector << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << - " <" << prettyprint(selector->pstate().token.ws_before()) << "> X <" << prettyprint(selector->pstate().token.ws_after()) << ">" << endl; + " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl; } else if (dynamic_cast(node)) { Selector_Placeholder* selector = dynamic_cast(node); @@ -187,7 +187,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0) } else if (dynamic_cast(node)) { Comment* block = dynamic_cast(node); cerr << ind << "Comment " << block << " " << block->tabs() << - " <" << prettyprint(block->pstate().token.ws_before()) << "> X <" << prettyprint(block->pstate().token.ws_after()) << ">" << endl; + " <" << prettyprint(block->pstate().token.ws_before()) << ">" << endl; debug_ast(block->text(), ind + "// ", env); } else if (dynamic_cast(node)) { If* block = dynamic_cast(node); @@ -322,13 +322,13 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0) (expression->is_delayed() ? " {delayed}" : "") << (expression->sass_fix_1291() ? " {sass_fix_1291}" : "") << (expression->quote_mark() != 0 ? " {qm:" + string(1, expression->quote_mark()) + "}" : "") << - " <" << prettyprint(expression->pstate().token.ws_before()) << "> X <" << prettyprint(expression->pstate().token.ws_after()) << ">" << endl; + " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl; } else if (dynamic_cast(node)) { String_Constant* expression = dynamic_cast(node); cerr << ind << "String_Constant : " << expression << " [" << prettyprint(expression->value()) << "]" << (expression->is_delayed() ? " {delayed}" : "") << (expression->sass_fix_1291() ? " {sass_fix_1291}" : "") << - " <" << prettyprint(expression->pstate().token.ws_before()) << "> X <" << prettyprint(expression->pstate().token.ws_after()) << ">" << endl; + " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl; } else if (dynamic_cast(node)) { String_Schema* expression = dynamic_cast(node); cerr << ind << "String_Schema " << expression << " " << expression->concrete_type() << diff --git a/environment.hpp b/environment.hpp index 3ea1283c9e..57a733e698 100644 --- a/environment.hpp +++ b/environment.hpp @@ -37,12 +37,29 @@ namespace Sass { bool current_frame_has(const string key) const { return !!current_frame_.count(key); } + void current_frame_set(const string key, T val) + { current_frame_[key] = val; } + + void global_frame_set(const string key, T val) + { global_frame()->current_frame_[key] = val; } + Environment* grandparent() const { if(parent_ && parent_->parent_) return parent_->parent_; else return 0; } + Environment* global_frame() + { + Environment* cur = this; + // looks like global variables + // are in the second last parent + while (cur->grandparent()) { + cur = cur->parent_; + } + return cur; + } + bool global_frame_has(const string key) const { if(parent_ && !grandparent()) { @@ -63,6 +80,7 @@ namespace Sass { else return current_frame_[key]; } +#ifdef DEBUG void print() { for (typename map::iterator i = current_frame_.begin(); i != current_frame_.end(); ++i) { @@ -73,6 +91,8 @@ namespace Sass { parent_->print(); } } +#endif + }; } diff --git a/eval.cpp b/eval.cpp index 6258084d4c..c5b6aafb52 100644 --- a/eval.cpp +++ b/eval.cpp @@ -64,12 +64,15 @@ namespace Sass { Expression* Eval::operator()(Assignment* a) { string var(a->variable()); - if (env->has(var)) { + if (a->is_global()) { + env->global_frame_set(var, a->value()->perform(this)); + } + else if (env->has(var)) { Expression* v = static_cast((*env)[var]); if (!a->is_guarded() || v->concrete_type() == Expression::NULL_VAL) (*env)[var] = a->value()->perform(this); } else { - env->current_frame()[var] = a->value()->perform(this); + env->current_frame_set(var, a->value()->perform(this)); } return 0; } diff --git a/expand.cpp b/expand.cpp index 900a974cac..a439da2f60 100644 --- a/expand.cpp +++ b/expand.cpp @@ -219,12 +219,15 @@ namespace Sass { { string var(a->variable()); Selector* p = selector_stack.size() <= 1 ? 0 : selector_stack.back(); - if (env->has(var)) { + if (a->is_global()) { + env->global_frame_set(var, a->value()->perform(eval->with(p, env, backtrace))); + } + else if (env->has(var)) { Expression* v = static_cast((*env)[var]); if (!a->is_guarded() || v->concrete_type() == Expression::NULL_VAL) (*env)[var] = a->value()->perform(eval->with(p, env, backtrace)); } else { - env->current_frame()[var] = a->value()->perform(eval->with(p, env, backtrace)); + env->current_frame_set(var, a->value()->perform(eval->with(p, env, backtrace))); } return 0; } diff --git a/functions.cpp b/functions.cpp index c2c8d71668..b97ecc4326 100644 --- a/functions.cpp +++ b/functions.cpp @@ -145,7 +145,9 @@ namespace Sass { static mt19937 rand(static_cast(GetSeed())); // features - static set features; + static set features { + "global-variable-shadowing" + }; //////////////// // RGB FUNCTIONS