* 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. |     # Evaluate each blacklist item. | ||||||
|     foreach my $item ($blacklist->getChildrenByTagName("item")) { |     foreach my $item ($blacklist->getChildrenByTagName("item")) { | ||||||
|         my $itemId = $item->getAttributeNode("id")->getValue; |         my $itemId = $item->getAttributeNode("id")->getValue; | ||||||
|         print "  CHECKING FOR $itemId\n"; | #        print "  CHECKING FOR $itemId\n"; | ||||||
| 
 | 
 | ||||||
|         my $condition = ($item->getChildrenByTagName("condition"))[0]; |         my $condition = ($item->getChildrenByTagName("condition"))[0]; | ||||||
|         die unless $condition; |         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, | static Expr parse(EvalState & state, | ||||||
|     const char * text, const Path & path, |     const char * text, const Path & path, | ||||||
|     const Path & basePath) |     const Path & basePath) | ||||||
|  | @ -96,6 +155,8 @@ static Expr parse(EvalState & state, | ||||||
|     } catch (Error & e) { |     } catch (Error & e) { | ||||||
|         throw Error(format("%1%, in `%2%'") % e.msg() % path); |         throw Error(format("%1%, in `%2%'") % e.msg() % path); | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     checkAttrSets(data.result); | ||||||
| 
 | 
 | ||||||
|     return 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