* Check for duplicate attributes and formal parameters in Nix
expressions.
This commit is contained in:
		
							parent
							
								
									97c93526da
								
							
						
					
					
						commit
						08df443618
					
				
					 7 changed files with 93 additions and 1 deletions
				
			
		|  | @ -232,7 +232,7 @@ foreach my $userEnvElem (@userEnvElems) { | |||
|     # Evaluate each blacklist item. | ||||
|     foreach my $item ($blacklist->getChildrenByTagName("item")) { | ||||
|         my $itemId = $item->getAttributeNode("id")->getValue; | ||||
|         print "  CHECKING FOR $itemId\n"; | ||||
| #        print "  CHECKING FOR $itemId\n"; | ||||
| 
 | ||||
|         my $condition = ($item->getChildrenByTagName("condition"))[0]; | ||||
|         die unless $condition; | ||||
|  |  | |||
|  | @ -75,6 +75,65 @@ int yyparse(yyscan_t scanner, ParseData * data); | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void checkAttrs(ATermMap & names, ATermList bnds) | ||||
| { | ||||
|     for (ATermIterator i(bnds); i; ++i) { | ||||
|         ATerm name; | ||||
|         Expr e; | ||||
|         ATerm pos; | ||||
|         if (!matchBind(*i, name, e, pos)) abort(); /* can't happen */ | ||||
|         if (names.get(name)) | ||||
|             throw Error(format("duplicate attribute `%1%' at %2%") | ||||
|                 % aterm2String(name) % showPos(pos)); | ||||
|         names.set(name, name); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void checkAttrSets(ATerm e) | ||||
| { | ||||
|     ATermList formals; | ||||
|     ATerm body, pos; | ||||
|     if (matchFunction(e, formals, body, pos)) { | ||||
|         ATermMap names; | ||||
|         for (ATermIterator i(formals); i; ++i) { | ||||
|             ATerm name; | ||||
|             Expr deflt; | ||||
|             if (!matchNoDefFormal(*i, name) && | ||||
|                 !matchDefFormal(*i, name, deflt)) | ||||
|                 abort(); | ||||
|             if (names.get(name)) | ||||
|                 throw Error(format("duplicate formal function argument `%1%' at %2%") | ||||
|                     % aterm2String(name) % showPos(pos)); | ||||
|             names.set(name, name); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ATermList bnds; | ||||
|     if (matchAttrs(e, bnds)) { | ||||
|         ATermMap names; | ||||
|         checkAttrs(names, bnds); | ||||
|     } | ||||
|      | ||||
|     ATermList rbnds, nrbnds; | ||||
|     if (matchRec(e, rbnds, nrbnds)) { | ||||
|         ATermMap names; | ||||
|         checkAttrs(names, rbnds); | ||||
|         checkAttrs(names, nrbnds); | ||||
|     } | ||||
|      | ||||
|     if (ATgetType(e) == AT_APPL) { | ||||
|         int arity = ATgetArity(ATgetAFun(e)); | ||||
|         for (int i = 0; i < arity; ++i) | ||||
|             checkAttrSets(ATgetArgument(e, i)); | ||||
|     } | ||||
| 
 | ||||
|     else if (ATgetType(e) == AT_LIST) | ||||
|         for (ATermIterator i((ATermList) e); i; ++i) | ||||
|             checkAttrSets(*i); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static Expr parse(EvalState & state, | ||||
|     const char * text, const Path & path, | ||||
|     const Path & basePath) | ||||
|  | @ -96,6 +155,8 @@ static Expr parse(EvalState & state, | |||
|     } catch (Error & e) { | ||||
|         throw Error(format("%1%, in `%2%'") % e.msg() % path); | ||||
|     } | ||||
|      | ||||
|     checkAttrSets(data.result); | ||||
| 
 | ||||
|     return data.result; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										4
									
								
								tests/lang/parse-fail-dup-attrs-1.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								tests/lang/parse-fail-dup-attrs-1.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| { x = 123; | ||||
|   y = 456; | ||||
|   x = 789; | ||||
| } | ||||
							
								
								
									
										13
									
								
								tests/lang/parse-fail-dup-attrs-2.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/lang/parse-fail-dup-attrs-2.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| let { | ||||
| 
 | ||||
|   as = { | ||||
|     x = 123; | ||||
|     y = 456; | ||||
|   }; | ||||
| 
 | ||||
|   bs = { | ||||
|     x = 789; | ||||
|     inherit (as) x; | ||||
|   }; | ||||
|    | ||||
| } | ||||
							
								
								
									
										13
									
								
								tests/lang/parse-fail-dup-attrs-3.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/lang/parse-fail-dup-attrs-3.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| let { | ||||
| 
 | ||||
|   as = { | ||||
|     x = 123; | ||||
|     y = 456; | ||||
|   }; | ||||
| 
 | ||||
|   bs = rec { | ||||
|     x = 789; | ||||
|     inherit (as) x; | ||||
|   }; | ||||
|    | ||||
| } | ||||
							
								
								
									
										1
									
								
								tests/lang/parse-fail-dup-formals.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/lang/parse-fail-dup-formals.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {x, y, x}: x | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue