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
 | ||||
|    in the given environment.  But if the expression is a variable, | ||||
|    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) | ||||
| { | ||||
|     state.mkAttrs(v, 3); | ||||
|     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(); | ||||
|     state.mkPos(v, &pos); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -243,6 +243,7 @@ public: | |||
|     void mkList(Value & v, unsigned int length); | ||||
|     void mkAttrs(Value & v, unsigned int expected); | ||||
|     void mkThunk_(Value & v, Expr * expr); | ||||
|     void mkPos(Value & v, Pos * pos); | ||||
| 
 | ||||
|     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. */ | ||||
| static void prim_hasAttr(EvalState & state, Value * * args, Value & v) | ||||
| { | ||||
|  | @ -1201,7 +1214,7 @@ void EvalState::createBaseEnv() | |||
|     mkBool(v, false); | ||||
|     addConstant("false", v); | ||||
| 
 | ||||
|     v.type = tNull; | ||||
|     mkNull(v); | ||||
|     addConstant("null", v); | ||||
| 
 | ||||
|     mkInt(v, time(0)); | ||||
|  | @ -1252,6 +1265,7 @@ void EvalState::createBaseEnv() | |||
|     // Sets
 | ||||
|     addPrimOp("__attrNames", 1, prim_attrNames); | ||||
|     addPrimOp("__getAttr", 2, prim_getAttr); | ||||
|     addPrimOp("__unsafeGetAttrPos", 2, prim_unsafeGetAttrPos); | ||||
|     addPrimOp("__hasAttr", 2, prim_hasAttr); | ||||
|     addPrimOp("__isAttrs", 1, prim_isAttrs); | ||||
|     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) | ||||
| { | ||||
|     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