* Check for duplicate attributes and formal parameters in Nix

expressions.
This commit is contained in:
Eelco Dolstra 2005-03-10 11:33:46 +00:00
parent 97c93526da
commit 08df443618
7 changed files with 93 additions and 1 deletions

View file

@ -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;

View file

@ -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;
} }

View file

@ -0,0 +1,4 @@
{ x = 123;
y = 456;
x = 789;
}

View file

@ -0,0 +1,13 @@
let {
as = {
x = 123;
y = 456;
};
bs = {
x = 789;
inherit (as) x;
};
}

View file

@ -0,0 +1,13 @@
let {
as = {
x = 123;
y = 456;
};
bs = rec {
x = 789;
inherit (as) x;
};
}

View file

@ -0,0 +1 @@
{x, y, x}: x