Skip to content

Commit

Permalink
issue 548
Browse files Browse the repository at this point in the history
It handles all the unit tests except the interpolation one.  Still working on that but sending the PR so you all can take a look
  • Loading branch information
Eric Kimn committed Mar 17, 2015
1 parent e1f78c0 commit ef73c1b
Show file tree
Hide file tree
Showing 21 changed files with 261 additions and 120 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ SOURCES = \
constants.cpp \
context.cpp \
contextualize.cpp \
contextualize_eval.cpp \
cssize.cpp \
error_handling.cpp \
eval.cpp \
Expand Down
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ libsass_la_SOURCES = \
constants.cpp constants.hpp \
context.cpp context.hpp \
contextualize.cpp contextualize.hpp \
contextualize_eval.cpp contextualize_eval.hpp \
error_handling.cpp error_handling.hpp \
eval.cpp eval.hpp \
expand.cpp expand.hpp \
Expand Down
17 changes: 17 additions & 0 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace Sass {
STRING,
LIST,
MAP,
SELECTOR,
NULL_VAL,
NUM_TYPES
};
Expand Down Expand Up @@ -1695,6 +1696,22 @@ namespace Sass {
//////////////////////////////////////////////////////////////////////////////////////////
inline Expression* List::value_at_index(size_t i) { return is_arglist_ ? ((Argument*)(*this)[i])->value() : (*this)[i]; }

////////////
// The Parent Selector Expression.
////////////
class Parent_Selector : public Expression {
ADD_PROPERTY(Selector*, selector);
public:
Parent_Selector(ParserState pstate, Selector* r = 0)
: Expression(pstate), selector_(r)
{ concrete_type(SELECTOR); }
virtual Selector* selector() { return selector_; }
string type() { return "selector"; }
static string type_name() { return "selector"; }

ATTACH_OPERATIONS();
};

/////////////////////////////////////////
// Abstract base class for CSS selectors.
/////////////////////////////////////////
Expand Down
2 changes: 2 additions & 0 deletions ast_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,15 @@ namespace Sass {
String_Constant* new_String_Constant(string p, size_t l, const char* beg, const char* end);
Feature_Query_Condition* new_Feature_Query_Condition(string p, size_t l, String* f, Expression* v);
Media_Expression* new_Media_Expression(string p, size_t l, String* f, Expression* v);
Parent_Selector* new_Parent_Selector(string p, size_t l, Selector* s);
// parameters and arguments
Parameter* new_Parameter(string p, size_t l, string n, Expression* def = 0, bool rest = false);
Parameters* new_Parameters(string p, size_t l);
Argument* new_Argument(string p, size_t l, Expression* val, string n = "", bool rest = false);
Arguments* new_Arguments(string p, size_t l);
// selectors
Selector_Schema* new_Selector_Schema(string p, size_t l, String* c);
Attribute_Selector* new_Attribute_Selector(string p, size_t l, string n, string m, String* v);
Simple_Selector* new_Simple_Selector(string p, size_t l, string c);
Reference_Selector* new_Reference_Selector(string p, size_t l);
Placeholder_Selector* new_Placeholder_Selector(string p, size_t l, string n);
Expand Down
1 change: 1 addition & 0 deletions ast_fwd_decl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace Sass {
class Feature_Query_Condition;
class At_Root_Expression;
class Null;
class Parent_Selector;
// parameters and arguments
class Parameter;
class Parameters;
Expand Down
2 changes: 2 additions & 0 deletions bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,11 @@ namespace Sass {
// make sure to eval the default value in the env that we've been populating
Env* old_env = eval->env;
Backtrace* old_bt = eval->backtrace;
Contextualize* old_context = eval->contextualize;
Expression* dv = leftover->default_value()->perform(eval->with(env, eval->backtrace));
eval->env = old_env;
eval->backtrace = old_bt;
eval->contextualize = old_context;
// dv->perform(&to_string);
env->current_frame()[leftover->name()] = dv;
}
Expand Down
8 changes: 5 additions & 3 deletions context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "expand.hpp"
#include "eval.hpp"
#include "contextualize.hpp"
#include "contextualize_eval.hpp"
#include "cssize.hpp"
#include "extend.hpp"
#include "remove_placeholders.hpp"
Expand Down Expand Up @@ -311,9 +312,10 @@ namespace Sass {
for (size_t i = 0, S = c_functions.size(); i < S; ++i) {
register_c_function(*this, &tge, c_functions[i]);
}
Eval eval(*this, &tge, &backtrace);
Contextualize contextualize(*this, &eval, &tge, &backtrace);
Expand expand(*this, &eval, &contextualize, &tge, &backtrace);
Contextualize contextualize(*this, &tge, &backtrace);
Eval eval(*this, &contextualize, &tge, &backtrace);
Contextualize_Eval contextualize_eval(*this, &eval, &tge, &backtrace);
Expand expand(*this, &eval, &contextualize_eval, &tge, &backtrace);
Cssize cssize(*this, &tge, &backtrace);
root = root->perform(&expand)->block();
root = root->perform(&cssize)->block();
Expand Down
30 changes: 2 additions & 28 deletions contextualize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

namespace Sass {

Contextualize::Contextualize(Context& ctx, Eval* eval, Env* env, Backtrace* bt, Selector* placeholder, Selector* extender)
: ctx(ctx), eval(eval), env(env), parent(0), backtrace(bt), placeholder(placeholder), extender(extender)
Contextualize::Contextualize(Context& ctx, Env* env, Backtrace* bt, Selector* placeholder, Selector* extender)
: ctx(ctx), env(env), backtrace(bt), parent(0), placeholder(placeholder), extender(extender)
{ }

Contextualize::~Contextualize() { }
Expand All @@ -26,18 +26,6 @@ namespace Sass {
return this;
}

Selector* Contextualize::operator()(Selector_Schema* s)
{
To_String to_string(&ctx);
string result_str(s->contents()->perform(eval->with(env, backtrace))->perform(&to_string));
result_str += '{'; // the parser looks for a brace to end the selector
Parser p = Parser::from_c_str(result_str.c_str(), ctx, s->pstate());
p.block_stack.push_back(s->last_block());
p.last_media_block = s->media_block();
Selector* result_sel = p.parse_selector_group();
return result_sel->perform(this);
}

Selector* Contextualize::operator()(Selector_List* s)
{
Selector_List* p = static_cast<Selector_List*>(parent);
Expand Down Expand Up @@ -126,18 +114,6 @@ namespace Sass {
Selector* Contextualize::operator()(Pseudo_Selector* s)
{ return s; }

Selector* Contextualize::operator()(Attribute_Selector* s)
{
// the value might be interpolated; evaluate it
String* v = s->value();
if (v && eval) {
v = static_cast<String*>(v->perform(eval->with(env, backtrace)));
}
Attribute_Selector* ss = new (ctx.mem) Attribute_Selector(*s);
ss->value(v);
return ss;
}

Selector* Contextualize::operator()(Selector_Qualifier* s)
{ return s; }

Expand All @@ -162,6 +138,4 @@ namespace Sass {
ss->selector(parent);
return ss;
}


}
16 changes: 6 additions & 10 deletions contextualize.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef SASS_CONTEXTUALIZE_H
#define SASS_CONTEXTUALIZE_H

#include "eval.hpp"
#include "context.hpp"
#include "operation.hpp"
#include "environment.hpp"
Expand All @@ -14,29 +13,26 @@ namespace Sass {

class Contextualize : public Operation_CRTP<Selector*, Contextualize> {


public:
Context& ctx;
Eval* eval;
Env* env;
Selector* parent;
Backtrace* backtrace;

Selector* fallback_impl(AST_Node* n);

public:
Selector* parent;
Selector* placeholder;
Selector* extender;
Contextualize(Context&, Eval*, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);

Selector* fallback_impl(AST_Node* n);
Contextualize(Context&, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);
virtual ~Contextualize();
Contextualize* with(Selector*, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);
using Operation<Selector*>::operator();

Selector* operator()(Selector_Schema*);
Selector* operator()(Selector_List*);
Selector* operator()(Complex_Selector*);
Selector* operator()(Compound_Selector*);
Selector* operator()(Wrapped_Selector*);
Selector* operator()(Pseudo_Selector*);
Selector* operator()(Attribute_Selector*);
Selector* operator()(Selector_Qualifier*);
Selector* operator()(Type_Selector*);
Selector* operator()(Selector_Placeholder*);
Expand Down
93 changes: 93 additions & 0 deletions contextualize_eval.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include "contextualize_eval.hpp"
#include "ast.hpp"
#include "eval.hpp"
#include "backtrace.hpp"
#include "to_string.hpp"
#include "parser.hpp"

namespace Sass {

Contextualize_Eval::Contextualize_Eval(Context& ctx, Eval* eval, Env* env, Backtrace* bt)
: Contextualize(ctx, env, bt), eval(eval)
{ }

Contextualize_Eval::~Contextualize_Eval() { }

Selector* Contextualize_Eval::fallback_impl(AST_Node* n)
{ return Contextualize::parent; }

Contextualize_Eval* Contextualize_Eval::with(Selector* s, Env* e, Backtrace* bt, Selector* p, Selector* ex)
{
Contextualize::with(s, e, bt, p, ex);
eval = eval->with(s, e, bt, p, ex);
return this;
}

Selector* Contextualize_Eval::operator()(Selector_Schema* s)
{
To_String to_string;
string result_str(s->contents()->perform(eval)->perform(&to_string)); //->with(env, backtrace)
result_str += '{'; // the parser looks for a brace to end the selector
Selector* result_sel = Parser::from_c_str(result_str.c_str(), ctx, s->pstate()).parse_selector_group();
return result_sel->perform(this);
}

Selector* Contextualize_Eval::operator()(Selector_List* s)
{
return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Complex_Selector* s)
{
return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Compound_Selector* s)
{
return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Wrapped_Selector* s)
{
return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Pseudo_Selector* s)
{ return Contextualize::operator ()(s); }

Selector* Contextualize_Eval::operator()(Attribute_Selector* s)
{
// the value might be interpolated; evaluate it
String* v = s->value();
if (v && eval) {
v = static_cast<String*>(v->perform(eval->with(env, backtrace)));
}
To_String toString;
Attribute_Selector* ss = new (ctx.mem) Attribute_Selector(*s);
ss->value(v);
return ss;
}

Selector* Contextualize_Eval::operator()(Selector_Qualifier* s)
{ return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Type_Selector* s)
{ return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Selector_Placeholder* p)
{
return Contextualize::operator ()(p);
}

Selector* Contextualize_Eval::operator()(Selector_Reference* s)
{
return Contextualize::operator ()(s);
}

/*
Selector* Contextualize_Eval::operator()(Parent_Selector* p)
{ error("amp", p->pstate()); return p->perform(eval->contextualize); }
*/
}
48 changes: 48 additions & 0 deletions contextualize_eval.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef SASS_CONTEXTUALIZE_EVAL_H
#define SASS_CONTEXTUALIZE_EVAL_H

#include "eval.hpp"
#include "context.hpp"
#include "operation.hpp"
#include "environment.hpp"
#include "ast_fwd_decl.hpp"

namespace Sass {
struct Backtrace;

typedef Environment<AST_Node*> Env;

class Contextualize_Eval : public Contextualize {//Operation_CRTP<Selector*, Contextualize_Eval> {

//Context& ctx;
Eval* eval;
//Env* env;
//Backtrace* backtrace;

Selector* fallback_impl(AST_Node* n);

public:
Contextualize_Eval(Context&, Eval*, Env*, Backtrace*);
virtual ~Contextualize_Eval();
Contextualize_Eval* with(Selector*, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);
using Operation<Selector*>::operator();

Selector* operator()(Selector_Schema*);
Selector* operator()(Selector_List*);
Selector* operator()(Complex_Selector*);
Selector* operator()(Compound_Selector*);
Selector* operator()(Wrapped_Selector*);
Selector* operator()(Pseudo_Selector*);
Selector* operator()(Attribute_Selector*);
Selector* operator()(Selector_Qualifier*);
Selector* operator()(Type_Selector*);
Selector* operator()(Selector_Placeholder*);
Selector* operator()(Selector_Reference*);
//Selector* operator()(Parent_Selector* p);

template <typename U>
Selector* fallback(U x) { return fallback_impl(x); }
};
}

#endif
27 changes: 20 additions & 7 deletions eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,21 @@ namespace Sass {
add, sub, mul, div, fmod
};

Eval::Eval(Context& ctx, Env* env, Backtrace* bt)
: ctx(ctx), env(env), backtrace(bt) { }
Eval::Eval(Context& ctx, Contextualize* contextualize, Env* env, Backtrace* bt)
: ctx(ctx), contextualize(contextualize), env(env), backtrace(bt) { }
Eval::~Eval() { }

Eval* Eval::with(Env* e, Backtrace* bt) // for setting the env before eval'ing an expression
{
contextualize = contextualize->with(0, e, bt);
env = e;
backtrace = bt;
return this;
}

Eval* Eval::with(Selector* c, Env* e, Backtrace* bt, Selector* p, Selector* ex) // for setting the env before eval'ing an expression
{
contextualize = contextualize->with(c, e, bt, p, ex);
env = e;
backtrace = bt;
return this;
Expand Down Expand Up @@ -887,11 +896,6 @@ namespace Sass {
e->is_interpolated());
}

Expression* Eval::operator()(Selector_Reference* e)
{
return e;
}

Expression* Eval::operator()(Null* n)
{
return n;
Expand Down Expand Up @@ -943,6 +947,15 @@ namespace Sass {
return 0;
}

Expression* Eval::operator()(Parent_Selector* p)
{
Selector* sel = p->perform(contextualize);
Inspect isp(0);
sel->perform(&isp);
string str = isp.get_buffer();
return new (ctx.mem) String_Constant(p->pstate(), str);
}

inline Expression* Eval::fallback_impl(AST_Node* n)
{
return static_cast<Expression*>(n);
Expand Down
Loading

0 comments on commit ef73c1b

Please sign in to comment.