|
|
|
@ -264,43 +264,46 @@ rec { |
|
|
|
|
defs' = (optional (opt ? default) |
|
|
|
|
{ file = head opt.declarations; value = mkOptionDefault opt.default; }) ++ defs; |
|
|
|
|
|
|
|
|
|
# Handle properties, check types, and merge everything together |
|
|
|
|
inherit (mergeDefinitions loc opt.type defs') isDefined defsFinal mergedValue; |
|
|
|
|
files = map (def: def.file) defsFinal; |
|
|
|
|
merged = |
|
|
|
|
if isDefined then mergedValue |
|
|
|
|
else throw "The option `${showOption loc}' is used but not defined."; |
|
|
|
|
|
|
|
|
|
# Finally, apply the ‘apply’ function to the merged |
|
|
|
|
# value. This allows options to yield a value computed |
|
|
|
|
# from the definitions. |
|
|
|
|
value = (opt.apply or id) merged; |
|
|
|
|
# Handle properties, check types, and merge everything together. |
|
|
|
|
res = mergeDefinitions loc opt.type defs'; |
|
|
|
|
|
|
|
|
|
# Check whether the option is defined, and apply the ‘apply’ |
|
|
|
|
# function to the merged value. This allows options to yield a |
|
|
|
|
# value computed from the definitions. |
|
|
|
|
value = |
|
|
|
|
if !res.isDefined then |
|
|
|
|
throw "The option `${showOption loc}' is used but not defined." |
|
|
|
|
else if opt ? apply then |
|
|
|
|
opt.apply res.mergedValue |
|
|
|
|
else |
|
|
|
|
res.mergedValue; |
|
|
|
|
|
|
|
|
|
in opt // |
|
|
|
|
{ value = addErrorContext "while evaluating the option `${showOption loc}':" value; |
|
|
|
|
definitions = map (def: def.value) defsFinal; |
|
|
|
|
inherit isDefined files; |
|
|
|
|
files = map (def: def.file) res.defsFinal; |
|
|
|
|
inherit (res) isDefined; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
# Merge definitions of a value of a given type. |
|
|
|
|
mergeDefinitions = loc: type: defs: rec { |
|
|
|
|
defsFinal = |
|
|
|
|
let |
|
|
|
|
# Process mkMerge and mkIf properties |
|
|
|
|
processIfAndMerge = defs: concatMap (m: |
|
|
|
|
# Process mkMerge and mkIf properties. |
|
|
|
|
defs' = concatMap (m: |
|
|
|
|
map (value: { inherit (m) file; inherit value; }) (dischargeProperties m.value) |
|
|
|
|
) defs; |
|
|
|
|
|
|
|
|
|
# Process mkOverride properties |
|
|
|
|
processOverride = defs: filterOverrides defs; |
|
|
|
|
# Process mkOverride properties. |
|
|
|
|
defs'' = filterOverrides defs'; |
|
|
|
|
|
|
|
|
|
# Sort mkOrder properties |
|
|
|
|
processOrder = defs: |
|
|
|
|
# Sort mkOrder properties. |
|
|
|
|
defs''' = |
|
|
|
|
# Avoid sorting if we don't have to. |
|
|
|
|
if any (def: def.value._type or "" == "order") defs |
|
|
|
|
then sortProperties defs |
|
|
|
|
else defs; |
|
|
|
|
in |
|
|
|
|
processOrder (processOverride (processIfAndMerge defs)); |
|
|
|
|
if any (def: def.value._type or "" == "order") defs'' |
|
|
|
|
then sortProperties defs'' |
|
|
|
|
else defs''; |
|
|
|
|
in defs'''; |
|
|
|
|
|
|
|
|
|
# Type-check the remaining definitions, and merge them. |
|
|
|
|
mergedValue = foldl' (res: def: |
|
|
|
|