@ -106,12 +106,9 @@ rec {
else [ ]
) configs ) ;
nrOptions = count ( m : isOption m . options ) decls ;
# Process mkMerge and mkIf properties.
defns' = concatMap ( m :
if m . config ? ${ name }
then map ( m' : { inherit ( m ) file ; value = m' ; } ) ( dischargeProperties m . config . ${ name } )
else [ ]
) configs ;
# Extract the definitions for this loc
defns' = map ( m : { inherit ( m ) file ; value = m . config . ${ name } ; } )
( filter ( m : m . config ? ${ name } ) configs ) ;
in
if nrOptions == length decls then
let opt = fixupOptionType loc ( mergeOptionDecls loc decls ) ;
@ -177,27 +174,17 @@ rec {
config value . * /
evalOptionValue = loc : opt : defs :
let
# Process mkOverride properties, adding in the default
# value specified in the option declaration (if any).
defsFinal' = filterOverrides
( ( if opt ? default then [ { file = head opt . declarations ; value = mkOptionDefault opt . default ; } ] else [ ] ) ++ defs ) ;
# Sort mkOrder properties.
defsFinal =
# Avoid sorting if we don't have to.
if any ( def : def . value . _type or " " == " o r d e r " ) defsFinal'
then sortProperties defsFinal'
else defsFinal' ;
# Add in the default value for this option, if any.
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' ) defsFinal mergedValue ;
files = map ( def : def . file ) defsFinal ;
# Type-check the remaining definitions, and merge them if
# possible.
merged =
if defsFinal == [ ] then
throw " T h e o p t i o n ` ${ showOption loc } ' i s u s e d b u t n o t d e f i n e d . "
else
fold ( def : res :
if opt . type . check def . value then res
else throw " T h e o p t i o n v a l u e ` ${ showOption loc } ' i n ` ${ def . file } ' i s n o t a ${ opt . type . name } . " )
( opt . type . merge loc defsFinal ) defsFinal ;
mergedValue ;
# Finally, apply the ‘apply’ function to the merged
# value. This allows options to yield a value computed
# from the definitions.
@ -209,6 +196,33 @@ rec {
inherit files ;
} ;
# Merge definitions of a value of a given type
mergeDefinitions = loc : type : defs : rec {
defsFinal =
let
# Process mkMerge and mkIf properties
discharged = concatMap ( m :
map ( value : { inherit ( m ) file ; inherit value ; } ) ( dischargeProperties m . value )
) defs ;
# Process mkOverride properties
overridden = filterOverrides discharged ;
# Sort mkOrder properties
sorted =
# Avoid sorting if we don't have to.
if any ( def : def . value . _type or " " == " o r d e r " ) overridden
then sortProperties overridden
else overridden ;
in sorted ;
# Type-check the remaining definitions, and merge them
mergedValue = fold ( def : res :
if type . check def . value then res
else throw " T h e o p t i o n v a l u e ` ${ showOption loc } ' i n ` ${ def . file } ' i s n o t a ${ type . name } . " )
( type . merge loc defsFinal ) defsFinal ;
} ;
/* G i v e n a c o n f i g s e t , e x p a n d m k M e r g e p r o p e r t i e s , a n d p u s h d o w n t h e
other properties into the children . The result is a list of
config sets that do not have properties at top-level . For