Add a primop unsafeGetAttrPos to return the position of an attribute
This commit is contained in:
		
							parent
							
								
									fc33fd86b7
								
							
						
					
					
						commit
						285df765b9
					
				
					 6 changed files with 44 additions and 6 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue