···
(concatMap (m: map (config: { inherit (m) file; inherit config; }) (pushDownProperties m.config)) modules);
mergeModules' = prefix: options: configs:
195
-
listToAttrs (map (name: {
196
+
/* byName is like foldAttrs, but will look for attributes to merge in the
197
+
specified attribute name.
199
+
byName "foo" (module: value: ["module.hidden=${module.hidden},value=${value}"])
203
+
foo={qux="bar"; gla="flop";};
207
+
foo={qux="gne"; gli="flip";};
212
+
gla = [ "module.hidden=baz,value=flop" ];
213
+
gli = [ "module.hidden=fli,value=flip" ];
214
+
qux = [ "module.hidden=baz,value=bar" "module.hidden=fli,value=gne" ];
217
+
byName = attr: f: modules: foldl' (acc: module:
218
+
foldl' (inner: name:
219
+
inner // { ${name} = (acc.${name} or []) ++ (f module module.${attr}.${name}); }
220
+
) acc (attrNames module.${attr})
222
+
# an attrset 'name' => list of submodules that declare ‘name’.
223
+
declsByName = byName "options"
224
+
(module: option: [{ inherit (module) file; options = option; }])
226
+
# an attrset 'name' => list of submodules that define ‘name’.
227
+
defnsByName = byName "config" (module: value:
228
+
map (config: { inherit (module) file; inherit config; }) (pushDownProperties value)
230
+
# extract the definitions for each loc
231
+
defnsByName' = byName "config"
232
+
(module: value: [{ inherit (module) file; inherit value; }])
235
+
(flip mapAttrs declsByName (name: decls:
# We're descending into attribute ‘name’.
201
-
# Get all submodules that declare ‘name’.
202
-
decls = concatMap (m:
203
-
if m.options ? ${name}
204
-
then [ { inherit (m) file; options = m.options.${name}; } ]
207
-
# Get all submodules that define ‘name’.
208
-
defns = concatMap (m:
209
-
if m.config ? ${name}
210
-
then map (config: { inherit (m) file; inherit config; })
211
-
(pushDownProperties m.config.${name})
239
+
defns = defnsByName.${name} or [];
240
+
defns' = defnsByName'.${name} or [];
nrOptions = count (m: isOption m.options) decls;
215
-
# Extract the definitions for this loc
216
-
defns' = map (m: { inherit (m) file; value = m.config.${name}; })
217
-
(filter (m: m.config ? ${name}) configs);
if nrOptions == length decls then
let opt = fixupOptionType loc (mergeOptionDecls loc decls);
···
throw "The option `${showOption loc}' in `${firstOption.file}' is a prefix of options in `${firstNonOption.file}'."
229
-
mergeModules' loc decls defns;
230
-
}) (concatMap (m: attrNames m.options) options))
253
+
mergeModules' loc decls defns
// { _definedNames = map (m: { inherit (m) file; names = attrNames m.config; }) configs; };
/* Merge multiple option declarations into a single declaration. In