forked from lix-project/lix
* Check for duplicate attributes and formal parameters in Nix
expressions.
This commit is contained in:
parent
97c93526da
commit
08df443618
|
@ -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…
Reference in a new issue