node_modules/@bigcommerce/node-sass/src/libsass/src/expand.cpp
// Eval does not create a new env scope
// But iteration vars are reset afterwards
Eval does not create a new env scope
But iteration vars are reset afterwards
Eval does not create a new env scope But iteration vars are reset afterwards
Statement* Expand::operator()(Each* e)
  {
    std::vector<std::string> variables(e->variables());
    Expression* expr = e->list()->perform(&eval);
    List* list = 0;
    Map* map = 0;
    if (expr->concrete_type() == Expression::MAP) {
      map = static_cast<Map*>(expr);
    }
    else if (expr->concrete_type() != Expression::LIST) {
      list = SASS_MEMORY_NEW(ctx.mem, List, expr->pstate(), 1, SASS_COMMA);
      *list << expr;
    }
    else {
      list = static_cast<List*>(expr);
    }
    Env* env = environment();
    std::vector<AST_Node*> old_vars(variables.size());
    for (size_t i = 0, L = variables.size(); i < L; ++i) {
      old_vars[i] = env->has_local(variables[i]) ? env->get_local(variables[i]) : 0;
      env->set_local(variables[i], 0);
    }
    Block* body = e->block();
    if (map) {
      for (auto key : map->keys()) {
        Expression* k = key->perform(&eval);
        Expression* v = map->at(key)->perform(&eval);
        if (variables.size() == 1) {
          List* variable = SASS_MEMORY_NEW(ctx.mem, List, map->pstate(), 2, SASS_SPACE);
          *variable << k;
          *variable << v;
          env->set_local(variables[0], variable);
        } else {
          env->set_local(variables[0], k);
          env->set_local(variables[1], v);
        }
        append_block(body);
      }
    }
    else {
      bool arglist = list->is_arglist();
      for (size_t i = 0, L = list->length(); i < L; ++i) {
        Expression* e = (*list)[i];
        if (Argument* arg = dynamic_cast<Argument*>(e)) e = arg->value();
        if (List* scalars = dynamic_cast<List*>(e)) {
          if (variables.size() == 1) {
            Expression* var = scalars;
            if (arglist) var = (*scalars)[0];
            env->set_local(variables[0], var);
          } else {
            for (size_t j = 0, K = variables.size(); j < K; ++j) {
              Expression* res = j >= scalars->length()
                ? SASS_MEMORY_NEW(ctx.mem, Null, expr->pstate())
                : (*scalars)[j]->perform(&eval);
              env->set_local(variables[j], res);
            }
          }
        } else {
          if (variables.size() > 0) {
            env->set_local(variables[0], e);
            for (size_t j = 1, K = variables.size(); j < K; ++j) {
              Expression* res = SASS_MEMORY_NEW(ctx.mem, Null, expr->pstate());
              env->set_local(variables[j], res);
            }
          }
        }
        append_block(body);
      }
    }
    for (size_t j = 0, K = variables.size(); j < K; ++j) {
      if(!old_vars[j]) env->del_local(variables[j]);
      else env->set_local(variables[j], old_vars[j]);
    }
    return 0;
  }
Statement * Expand :: operator () ( Each * e ) { std :: vector < std :: string > variables ( e -> variables ( ) ) ; Expression * expr = e -> list ( ) -> perform ( & eval ) ; List * list = 0 ; Map * map = 0 ; if ( expr -> concrete_type ( ) == Expression :: MAP ) { map = static_cast < Map * > ( expr ) ; } else if ( expr -> concrete_type ( ) != Expression :: LIST ) { list = SASS_MEMORY_NEW ( ctx . mem , List , expr -> pstate ( ) , 1 , SASS_COMMA ) ; * list << expr ; } else { list = static_cast < List * > ( expr ) ; } Env * env = environment ( ) ; std :: vector < AST_Node * > old_vars ( variables . size ( ) ) ; for ( size_t i = 0 , L = variables . size ( ) ; i < L ; ++ i ) { old_vars [ i ] = env -> has_local ( variables [ i ] ) ? env -> get_local ( variables [ i ] ) : 0 ; env -> set_local ( variables [ i ] , 0 ) ; } Block * body = e -> block ( ) ; if ( map ) { for ( auto key : map -> keys ( ) ) { Expression * k = key -> perform ( & eval ) ; Expression * v = map -> at ( key ) -> perform ( & eval ) ; if ( variables . size ( ) == 1 ) { List * variable = SASS_MEMORY_NEW ( ctx . mem , List , map -> pstate ( ) , 2 , SASS_SPACE ) ; * variable << k ; * variable << v ; env -> set_local ( variables [ 0 ] , variable ) ; } else { env -> set_local ( variables [ 0 ] , k ) ; env -> set_local ( variables [ 1 ] , v ) ; } append_block ( body ) ; } } else { bool arglist = list -> is_arglist ( ) ; for ( size_t i = 0 , L = list -> length ( ) ; i < L ; ++ i ) { Expression * e = ( * list ) [ i ] ; if ( Argument * arg = dynamic_cast < Argument * > ( e ) ) e = arg -> value ( ) ; if ( List * scalars = dynamic_cast < List * > ( e ) ) { if ( variables . size ( ) == 1 ) { Expression * var = scalars ; if ( arglist ) var = ( * scalars ) [ 0 ] ; env -> set_local ( variables [ 0 ] , var ) ; } else { for ( size_t j = 0 , K = variables . size ( ) ; j < K ; ++ j ) { Expression * res = j >= scalars -> length ( ) ? SASS_MEMORY_NEW ( ctx . mem , Null , expr -> pstate ( ) ) : ( * scalars ) [ j ] -> perform ( & eval ) ; env -> set_local ( variables [ j ] , res ) ; } } } else { if ( variables . size ( ) > 0 ) { env -> set_local ( variables [ 0 ] , e ) ; for ( size_t j = 1 , K = variables . size ( ) ; j < K ; ++ j ) { Expression * res = SASS_MEMORY_NEW ( ctx . mem , Null , expr -> pstate ( ) ) ; env -> set_local ( variables [ j ] , res ) ; } } } append_block ( body ) ; } } for ( size_t j = 0 , K = variables . size ( ) ; j < K ; ++ j ) { if ( ! old_vars [ j ] ) env -> del_local ( variables [ j ] ) ; else env -> set_local ( variables [ j ] , old_vars [ j ] ) ; } return 0 ; }
Eval does not create a new env scope
But iteration vars are reset afterwards
Eval does not create a new env scope But iteration vars are reset afterwards
// remember variables and then reset them // unwrap value if the expression is an argument // check if we got passed a list of args (investigate) // restore original environment