Add a primop unsafeGetAttrPos to return the position of an attribute
This commit is contained in:
parent
fc33fd86b7
commit
285df765b9
|
@ -410,6 +410,19 @@ void EvalState::mkThunk_(Value & v, Expr * expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EvalState::mkPos(Value & v, Pos * pos)
|
||||||
|
{
|
||||||
|
if (pos) {
|
||||||
|
mkAttrs(v, 3);
|
||||||
|
mkString(*allocAttr(v, sFile), pos->file);
|
||||||
|
mkInt(*allocAttr(v, sLine), pos->line);
|
||||||
|
mkInt(*allocAttr(v, sColumn), pos->column);
|
||||||
|
v.attrs->sort();
|
||||||
|
} else
|
||||||
|
mkNull(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create a thunk for the delayed computation of the given expression
|
/* Create a thunk for the delayed computation of the given expression
|
||||||
in the given environment. But if the expression is a variable,
|
in the given environment. But if the expression is a variable,
|
||||||
then look it up right away. This significantly reduces the number
|
then look it up right away. This significantly reduces the number
|
||||||
|
@ -1044,11 +1057,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
state.mkAttrs(v, 3);
|
state.mkPos(v, &pos);
|
||||||
mkString(*state.allocAttr(v, state.sFile), pos.file);
|
|
||||||
mkInt(*state.allocAttr(v, state.sLine), pos.line);
|
|
||||||
mkInt(*state.allocAttr(v, state.sColumn), pos.column);
|
|
||||||
v.attrs->sort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -243,6 +243,7 @@ public:
|
||||||
void mkList(Value & v, unsigned int length);
|
void mkList(Value & v, unsigned int length);
|
||||||
void mkAttrs(Value & v, unsigned int expected);
|
void mkAttrs(Value & v, unsigned int expected);
|
||||||
void mkThunk_(Value & v, Expr * expr);
|
void mkThunk_(Value & v, Expr * expr);
|
||||||
|
void mkPos(Value & v, Pos * pos);
|
||||||
|
|
||||||
void concatLists(Value & v, unsigned int nrLists, Value * * lists);
|
void concatLists(Value & v, unsigned int nrLists, Value * * lists);
|
||||||
|
|
||||||
|
|
|
@ -776,6 +776,19 @@ void prim_getAttr(EvalState & state, Value * * args, Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return position information of the specified attribute. */
|
||||||
|
void prim_unsafeGetAttrPos(EvalState & state, Value * * args, Value & v)
|
||||||
|
{
|
||||||
|
string attr = state.forceStringNoCtx(*args[0]);
|
||||||
|
state.forceAttrs(*args[1]);
|
||||||
|
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
||||||
|
if (i == args[1]->attrs->end())
|
||||||
|
mkNull(v);
|
||||||
|
else
|
||||||
|
state.mkPos(v, i->pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Dynamic version of the `?' operator. */
|
/* Dynamic version of the `?' operator. */
|
||||||
static void prim_hasAttr(EvalState & state, Value * * args, Value & v)
|
static void prim_hasAttr(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
@ -1201,7 +1214,7 @@ void EvalState::createBaseEnv()
|
||||||
mkBool(v, false);
|
mkBool(v, false);
|
||||||
addConstant("false", v);
|
addConstant("false", v);
|
||||||
|
|
||||||
v.type = tNull;
|
mkNull(v);
|
||||||
addConstant("null", v);
|
addConstant("null", v);
|
||||||
|
|
||||||
mkInt(v, time(0));
|
mkInt(v, time(0));
|
||||||
|
@ -1252,6 +1265,7 @@ void EvalState::createBaseEnv()
|
||||||
// Sets
|
// Sets
|
||||||
addPrimOp("__attrNames", 1, prim_attrNames);
|
addPrimOp("__attrNames", 1, prim_attrNames);
|
||||||
addPrimOp("__getAttr", 2, prim_getAttr);
|
addPrimOp("__getAttr", 2, prim_getAttr);
|
||||||
|
addPrimOp("__unsafeGetAttrPos", 2, prim_unsafeGetAttrPos);
|
||||||
addPrimOp("__hasAttr", 2, prim_hasAttr);
|
addPrimOp("__hasAttr", 2, prim_hasAttr);
|
||||||
addPrimOp("__isAttrs", 1, prim_isAttrs);
|
addPrimOp("__isAttrs", 1, prim_isAttrs);
|
||||||
addPrimOp("removeAttrs", 2, prim_removeAttrs);
|
addPrimOp("removeAttrs", 2, prim_removeAttrs);
|
||||||
|
|
|
@ -116,6 +116,13 @@ static inline void mkBool(Value & v, bool b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void mkNull(Value & v)
|
||||||
|
{
|
||||||
|
v.type = tNull;
|
||||||
|
v.app.left = v.app.right = 00; // scrub
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void mkApp(Value & v, Value & left, Value & right)
|
static inline void mkApp(Value & v, Value & left, Value & right)
|
||||||
{
|
{
|
||||||
v.type = tApp;
|
v.type = tApp;
|
||||||
|
|
1
tests/lang/eval-okay-getattrpos.exp
Normal file
1
tests/lang/eval-okay-getattrpos.exp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ column = 5; file = "eval-okay-getattrpos.nix"; line = 3; }
|
6
tests/lang/eval-okay-getattrpos.nix
Normal file
6
tests/lang/eval-okay-getattrpos.nix
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
let
|
||||||
|
as = {
|
||||||
|
foo = "bar";
|
||||||
|
};
|
||||||
|
pos = builtins.unsafeGetAttrPos "foo" as;
|
||||||
|
in { inherit (pos) column line; file = baseNameOf pos.file; }
|
Loading…
Reference in a new issue