From e2d5e40f4fdd98e5d2ad7b77c00fb97caa3aa259 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 7 May 2010 12:11:05 +0000 Subject: * Keep track of the source positions of attributes. --- src/libexpr/eval.cc | 59 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index cb124ab8ba44..b8ec410f3993 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -44,7 +44,7 @@ std::ostream & operator << (std::ostream & str, Value & v) case tAttrs: str << "{ "; foreach (Bindings::iterator, i, *v.attrs) - str << (string) i->first << " = " << i->second << "; "; + str << (string) i->first << " = " << i->second.value << "; "; str << "}"; break; case tList: @@ -128,7 +128,7 @@ void EvalState::addConstant(const string & name, Value & v) staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v; string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; - (*baseEnv.values[0].attrs)[symbols.create(name2)] = v; + (*baseEnv.values[0].attrs)[symbols.create(name2)].value = v; } @@ -143,7 +143,7 @@ void EvalState::addPrimOp(const string & name, v.primOp.name = strdup(name2.c_str()); staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v; - (*baseEnv.values[0].attrs)[symbols.create(name2)] = v; + (*baseEnv.values[0].attrs)[symbols.create(name2)].value = v; } @@ -202,6 +202,11 @@ LocalNoInline(void addErrorPrefix(Error & e, const char * s, const Pos & pos)) e.addPrefix(format(s) % pos); } +LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2, const Pos & pos)) +{ + e.addPrefix(format(s) % s2 % pos); +} + void mkString(Value & v, const char * s) { @@ -239,7 +244,7 @@ Value * EvalState::lookupVar(Env * env, const VarRef & var) while (1) { Bindings::iterator j = env->values[0].attrs->find(var.name); if (j != env->values[0].attrs->end()) - return &j->second; + return &j->second.value; if (env->prevWith == 0) throwEvalError("undefined variable `%1%'", var.name); for (unsigned int l = env->prevWith; l; --l, env = env->up) ; @@ -290,8 +295,11 @@ void EvalState::mkThunk_(Value & v, Expr * expr) void EvalState::cloneAttrs(Value & src, Value & dst) { mkAttrs(dst); - foreach (Bindings::iterator, i, *src.attrs) - mkCopy((*dst.attrs)[i->first], i->second); + foreach (Bindings::iterator, i, *src.attrs) { + Attr & a = (*dst.attrs)[i->first]; + mkCopy(a.value, i->second.value); + a.pos = i->second.pos; + } } @@ -414,15 +422,16 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) /* The recursive attributes are evaluated in the new environment. */ foreach (Attrs::iterator, i, attrs) { - Value & v2 = (*v.attrs)[i->first]; - mkCopy(v2, env2.values[displ]); + nix::Attr & a = (*v.attrs)[i->first]; + mkCopy(a.value, env2.values[displ]); mkThunk(env2.values[displ++], env2, i->second.first); + a.pos = &i->second.second; } /* The inherited attributes, on the other hand, are evaluated in the original environment. */ foreach (list::iterator, i, inherited) { - Value & v2 = (*v.attrs)[i->name]; + Value & v2 = (*v.attrs)[i->name].value; Value * v3 = state.lookupVar(&env, *i); mkCopy(v2, *v3); mkCopy(env2.values[displ++], *v3); @@ -432,12 +441,13 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) else { foreach (Attrs::iterator, i, attrs) { - Value & v2 = (*v.attrs)[i->first]; - mkThunk(v2, env, i->second.first); + nix::Attr & a = (*v.attrs)[i->first]; + mkThunk(a.value, env, i->second.first); + a.pos = &i->second.second; } foreach (list::iterator, i, inherited) { - Value & v2 = (*v.attrs)[i->name]; + Value & v2 = (*v.attrs)[i->name].value; mkCopy(v2, *state.lookupVar(&env, *i)); } } @@ -494,12 +504,13 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) if (i == v2.attrs->end()) throwEvalError("attribute `%1%' missing", name); try { - state.forceValue(i->second); + state.forceValue(i->second.value); } catch (Error & e) { - addErrorPrefix(e, "while evaluating the attribute `%1%':\n", name); + addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n", + name, *i->second.pos); throw; } - v = i->second; + v = i->second.value; } @@ -601,7 +612,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v) mkThunk(env2.values[displ++], env2, i->def); } else { attrsUsed++; - mkCopy(env2.values[displ++], j->second); + mkCopy(env2.values[displ++], j->second.value); } } @@ -721,8 +732,11 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v) state.evalAttrs(env, e2, v2); - foreach (Bindings::iterator, i, *v2.attrs) - mkCopy((*v.attrs)[i->first], i->second); + foreach (Bindings::iterator, i, *v2.attrs) { + Attr & a = (*v.attrs)[i->first]; + mkCopy(a.value, i->second.value); + a.pos = i->second.pos; + } } @@ -802,7 +816,7 @@ void EvalState::strictForceValue(Value & v) if (v.type == tAttrs) { foreach (Bindings::iterator, i, *v.attrs) - strictForceValue(i->second); + strictForceValue(i->second.value); } else if (v.type == tList) { @@ -887,7 +901,7 @@ bool EvalState::isDerivation(Value & v) { if (v.type != tAttrs) return false; Bindings::iterator i = v.attrs->find(sType); - return i != v.attrs->end() && forceStringNoCtx(i->second) == "derivation"; + return i != v.attrs->end() && forceStringNoCtx(i->second.value) == "derivation"; } @@ -933,7 +947,7 @@ string EvalState::coerceToString(Value & v, PathSet & context, Bindings::iterator i = v.attrs->find(sOutPath); if (i == v.attrs->end()) throwTypeError("cannot coerce an attribute set (except a derivation) to a string"); - return coerceToString(i->second, context, coerceMore, copyToStore); + return coerceToString(i->second.value, context, coerceMore, copyToStore); } if (coerceMore) { @@ -1021,7 +1035,8 @@ bool EvalState::eqValues(Value & v1, Value & v2) if (v1.attrs->size() != v2.attrs->size()) return false; Bindings::iterator i, j; for (i = v1.attrs->begin(), j = v2.attrs->begin(); i != v1.attrs->end(); ++i, ++j) - if (i->first != j->first || !eqValues(i->second, j->second)) return false; + if (i->first != j->first || !eqValues(i->second.value, j->second.value)) + return false; return true; } -- cgit 1.4.1