Refactor a bit to add names to intermediate computations. Add a cross

temporary result to fetch information from the evaluation to make them
available inside the option declaration.

Add: isNotDefined flag inside the option.

svn path=/nixpkgs/trunk/; revision=17766
This commit is contained in:
Nicolas Pierron 2009-10-12 17:51:21 +00:00
parent 81694a7f54
commit b15cbb639e

View File

@ -165,7 +165,7 @@ rec {
declarationsOf = name: filter (m: m ? options) (modulesOf name); declarationsOf = name: filter (m: m ? options) (modulesOf name);
definitionsOf = name: filter (m: m ? config ) (modulesOf name); definitionsOf = name: filter (m: m ? config ) (modulesOf name);
recurseInto = name: modules: recurseInto = name:
moduleMerge (addName name) (modulesOf name); moduleMerge (addName name) (modulesOf name);
recurseForOption = name: modules: recurseForOption = name: modules:
@ -184,105 +184,126 @@ rec {
eol = "\n"; eol = "\n";
errDefinedWithoutDeclaration = name: allNames = modulesNames modules;
let
badModules = getResults = m:
filter (m: ! isAttrs m.config) let fetchResult = s: mapAttrs (n: v: v.result) s; in {
(definitionsOf name); options = fetchResult m.options;
in config = fetchResult m.config;
"${eol };
}Option '${addName name}' defined without option declaration.${eol
}${errorSource badModules}${eol
}";
endRecursion = { options = {}; config = {}; }; endRecursion = { options = {}; config = {}; };
in if modules == [] then endRecursion else in if modules == [] then endRecursion else
getResults (fix (crossResults: moduleZip {
options = lib.zipWithNames allNames (name: values: rec {
config = lib.getAttr name crossResults.config;
declarations = declarationsOf name;
declarationSources =
map (m: {
source = m.key;
}) declarations;
hasOptions = values != [];
isOption = any lib.isOption values;
lib.fix (result:
moduleZip {
options = lib.zip (name: values:
if any isOption values then
let
decls = # add location to sub-module options. decls = # add location to sub-module options.
map (m: map (m:
mapSubOptions mapSubOptions
(unifyOptionModule {inherit (m) key;}) (unifyOptionModule {inherit (m) key;})
m.options m.options
) (declarationsOf name); ) declarations;
in
decl =
addOptionMakeUp addOptionMakeUp
{ name = addName name; recurseInto = recurseForOption; } { name = addName name; recurseInto = recurseForOption; }
(mergeOptionDecls decls) (mergeOptionDecls decls);
// {
declarations =
map (m: {
source = m.key;
}) (declarationsOf name);
definitions = value = decl // (with config; {
map (m: { inherit (config) isNotDefined;
source = m.key; declarations = declarationSources;
value = m.config; definitions = definitionSources;
}) (definitionsOf name); config = strictResult;
});
config = builtins.tryEval recurse = (recurseInto name).options;
(builtins.toXML (lib.getAttr name result.config));
} result =
else if all isAttrs values then if isOption then value
(recurseInto name modules).options else if all isAttrs values then recurse
else else
throw "${eol throw "${eol
}Unexpected type where option declarations are expected.${eol }Unexpected type where option declarations are expected.${eol
}${errorSource (declarationsOf name)}${eol }${errorSource declarations}${eol
}" }";
);
});
config = lib.zipWithNames allNames (name: values_: rec {
option = lib.getAttr name crossResults.options;
definitions = definitionsOf name;
definitionSources =
map (m: {
source = m.key;
value = m.config;
}) definitions;
config = lib.zipWithNames (modulesNames modules) (name: values_:
let
hasOpt = builtins.hasAttr name result.options;
opt = lib.getAttr name result.options;
values = values_ ++ values = values_ ++
optionals optionals (option.isOption && option.decl ? extraConfigs)
(hasOpt && isOption opt && opt ? extraConfigs) option.decl.extraConfigs;
opt.extraConfigs;
in if hasOpt && isOption opt then defs = evalDefinitions option.decl values;
let defs = evalDefinitions opt values; in
isNotDefined = defs == [];
value =
lib.addErrorContext "${eol lib.addErrorContext "${eol
}while evaluating the option '${addName name}'.${eol }while evaluating the option '${addName name}'.${eol
}${errorSource (modulesOf name)}${eol }${errorSource (modulesOf name)}${eol
}" ( }" (
let opt = option.decl; in
opt.apply ( opt.apply (
if defs == [] then if isNotDefined then
if opt ? default then opt.default if opt ? default then opt.default
else throw "Not defined." else throw "Not defined."
else opt.merge defs else opt.merge defs
) )
) );
else if hasOpt && lib.attrNames opt == [] then strictResult = builtins.tryEval (builtins.toXML value);
throw (errDefinedWithoutDeclaration name)
else if any (v: isOption (rmProperties v)) values then recurse = (recurseInto name).config;
let
badModules = configIsAnOption = v: isOption (rmProperties v);
filter (m: isOption m.config) errConfigIsAnOption =
(definitionsOf name); let badModules = filter (m: configIsAnOption m.config) definitions; in
in "${eol
throw "${eol
}Option ${addName name} is defined in the configuration section.${eol }Option ${addName name} is defined in the configuration section.${eol
}${errorSource badModules}${eol }${errorSource badModules}${eol
}" }";
else if all isAttrs values then errDefinedWithoutDeclaration =
(recurseInto name modules).config let badModules = definitions; in
else "${eol
throw (errDefinedWithoutDeclaration name) }Option '${addName name}' defined without option declaration.${eol
); }${errorSource badModules}${eol
}";
result =
if option.isOption then value
else if !option.hasOptions then throw errDefinedWithoutDeclaration
else if any configIsAnOption values then throw errConfigIsAnOption
else if all isAttrs values then recurse
# plain value during the traversal
else throw errDefinedWithoutDeclaration;
});
} modules));
} modules
);
fixMergeModules = initModules: {...}@args: fixMergeModules = initModules: {...}@args:
lib.fix (result: lib.fix (result: