11{-# LANGUAGE DeriveFunctor #-}
2- {-# LANGUAGE RecordWildCards #-}
3- module Distribution.Solver.Modular.Dependency (
4- -- * Variables
5- Var (.. )
2+
3+ module Distribution.Solver.Modular.Dependency
4+ ( -- * Variables
5+ Var (.. )
66 , showVar
77 , varPN
8+
89 -- * Conflict sets
910 , ConflictSet
1011 , ConflictMap
1112 , CS. showConflictSet
13+
1214 -- * Constrained instances
13- , CI (.. )
15+ , CI (.. )
16+
1417 -- * Flagged dependencies
1518 , FlaggedDeps
16- , FlaggedDep (.. )
17- , LDep (.. )
18- , Dep (.. )
19- , PkgComponent (.. )
20- , ExposedComponent (.. )
21- , DependencyReason (.. )
19+ , FlaggedDep (.. )
20+ , LDep (.. )
21+ , Dep (.. )
22+ , PkgComponent (.. )
23+ , ExposedComponent (.. )
24+ , DependencyReason (.. )
2225 , showDependencyReason
2326 , flattenFlaggedDeps
24- , QualifyOptions (.. )
2527 , qualifyDeps
2628 , unqualifyDeps
29+
2730 -- * Reverse dependency map
2831 , RevDepMap
32+
2933 -- * Goals
30- , Goal (.. )
31- , GoalReason (.. )
34+ , Goal (.. )
35+ , GoalReason (.. )
3236 , QGoalReason
3337 , goalToVar
3438 , varToConflictSet
@@ -39,21 +43,21 @@ module Distribution.Solver.Modular.Dependency (
3943 , dependencyReasonToConflictSetWithVersionConflict
4044 ) where
4145
42- import Prelude ()
4346import qualified Data.Map as M
4447import qualified Data.Set as S
4548import Distribution.Solver.Compat.Prelude hiding (pi )
49+ import Prelude ()
4650
47- import Language.Haskell.Extension (Extension (.. ), Language (.. ))
51+ import Language.Haskell.Extension (Extension (.. ), Language (.. ))
4852
49- import Distribution.Solver.Modular.ConflictSet (ConflictSet , ConflictMap )
53+ import Distribution.Solver.Modular.ConflictSet (ConflictMap , ConflictSet )
54+ import qualified Distribution.Solver.Modular.ConflictSet as CS
5055import Distribution.Solver.Modular.Flag
5156import Distribution.Solver.Modular.Package
5257import Distribution.Solver.Modular.Var
5358import Distribution.Solver.Modular.Version
54- import qualified Distribution.Solver.Modular.ConflictSet as CS
5559
56- import Distribution.Solver.Types.ComponentDeps (Component (.. ))
60+ import Distribution.Solver.Types.ComponentDeps (Component (.. ))
5761import Distribution.Solver.Types.PackagePath
5862import Distribution.Types.LibraryName
5963import Distribution.Types.PkgconfigVersionRange
@@ -85,14 +89,14 @@ type FlaggedDeps qpn = [FlaggedDep qpn]
8589
8690-- | Flagged dependencies can either be plain dependency constraints,
8791-- or flag-dependent dependency trees.
88- data FlaggedDep qpn =
89- -- | Dependencies which are conditional on a flag choice.
92+ data FlaggedDep qpn
93+ = -- | Dependencies which are conditional on a flag choice.
9094 Flagged (FN qpn ) FInfo (TrueFlaggedDeps qpn ) (FalseFlaggedDeps qpn )
91- -- | Dependencies which are conditional on whether or not a stanza
95+ | -- | Dependencies which are conditional on whether or not a stanza
9296 -- (e.g., a test suite or benchmark) is enabled.
93- | Stanza (SN qpn ) (TrueFlaggedDeps qpn )
94- -- | Dependencies which are always enabled, for the component 'comp'.
95- | Simple (LDep qpn ) Component
97+ Stanza (SN qpn ) (TrueFlaggedDeps qpn )
98+ | -- | Dependencies which are always enabled, for the component 'comp'.
99+ Simple (LDep qpn ) Component
96100
97101-- | Conservatively flatten out flagged dependencies
98102--
@@ -102,10 +106,10 @@ flattenFlaggedDeps = concatMap aux
102106 where
103107 aux :: FlaggedDep qpn -> [(LDep qpn , Component )]
104108 aux (Flagged _ _ t f) = flattenFlaggedDeps t ++ flattenFlaggedDeps f
105- aux (Stanza _ t) = flattenFlaggedDeps t
106- aux (Simple d c) = [(d, c)]
109+ aux (Stanza _ t) = flattenFlaggedDeps t
110+ aux (Simple d c) = [(d, c)]
107111
108- type TrueFlaggedDeps qpn = FlaggedDeps qpn
112+ type TrueFlaggedDeps qpn = FlaggedDeps qpn
109113type FalseFlaggedDeps qpn = FlaggedDeps qpn
110114
111115-- | A 'Dep' labeled with the reason it was introduced.
@@ -119,11 +123,16 @@ data LDep qpn = LDep (DependencyReason qpn) (Dep qpn)
119123-- | A dependency (constraint) associates a package name with a constrained
120124-- instance. It can also represent other types of dependencies, such as
121125-- dependencies on language extensions.
122- data Dep qpn = Dep (PkgComponent qpn ) CI -- ^ dependency on a package component
123- | Ext Extension -- ^ dependency on a language extension
124- | Lang Language -- ^ dependency on a language version
125- | Pkg PkgconfigName PkgconfigVersionRange -- ^ dependency on a pkg-config package
126- deriving Functor
126+ data Dep qpn
127+ = -- | dependency on a package component
128+ Dep (PkgComponent qpn ) CI
129+ | -- | dependency on a language extension
130+ Ext Extension
131+ | -- | dependency on a language version
132+ Lang Language
133+ | -- | dependency on a pkg-config package
134+ Pkg PkgconfigName PkgconfigVersionRange
135+ deriving (Functor )
127136
128137-- | An exposed component within a package. This type is used to represent
129138-- build-depends and build-tool-depends dependencies.
@@ -132,8 +141,8 @@ data PkgComponent qpn = PkgComponent qpn ExposedComponent
132141
133142-- | A component that can be depended upon by another package, i.e., a library
134143-- or an executable.
135- data ExposedComponent =
136- ExposedLib LibraryName
144+ data ExposedComponent
145+ = ExposedLib LibraryName
137146 | ExposedExe UnqualComponentName
138147 deriving (Eq , Ord , Show )
139148
@@ -147,43 +156,25 @@ data DependencyReason qpn = DependencyReason qpn (Map Flag FlagValue) (S.Set Sta
147156-- | Print the reason that a dependency was introduced.
148157showDependencyReason :: DependencyReason QPN -> String
149158showDependencyReason (DependencyReason qpn flags stanzas) =
150- intercalate " " $
151- showQPN qpn
159+ intercalate " " $
160+ showQPN qpn
152161 : map (uncurry showFlagValue) (M. toList flags)
153- ++ map (\ s -> showSBool s True ) (S. toList stanzas)
154-
155- -- | Options for goal qualification (used in 'qualifyDeps')
156- --
157- -- See also 'defaultQualifyOptions'
158- data QualifyOptions = QO {
159- -- | Do we have a version of base relying on another version of base?
160- qoBaseShim :: Bool
161-
162- -- Should dependencies of the setup script be treated as independent?
163- , qoSetupIndependent :: Bool
164- }
165- deriving Show
162+ ++ map (\ s -> showSBool s True ) (S. toList stanzas)
166163
167164-- | Apply built-in rules for package qualifiers
168165--
169- -- Although the behaviour of 'qualifyDeps' depends on the 'QualifyOptions',
170- -- it is important that these 'QualifyOptions' are _static_. Qualification
171- -- does NOT depend on flag assignment; in other words, it behaves the same no
172- -- matter which choices the solver makes (modulo the global 'QualifyOptions');
173- -- we rely on this in 'linkDeps' (see comment there).
174- --
175166-- NOTE: It's the _dependencies_ of a package that may or may not be independent
176167-- from the package itself. Package flag choices must of course be consistent.
177- qualifyDeps :: QualifyOptions -> QPN -> FlaggedDeps PN -> FlaggedDeps QPN
178- qualifyDeps QO { .. } (Q pp@ (PackagePath ns q) pn) = go
168+ qualifyDeps :: QPN -> FlaggedDeps PN -> FlaggedDeps QPN
169+ qualifyDeps (Q pp@ (PackagePath ns q) pn) = go
179170 where
180171 go :: FlaggedDeps PN -> FlaggedDeps QPN
181172 go = map go1
182173
183174 go1 :: FlaggedDep PN -> FlaggedDep QPN
184175 go1 (Flagged fn nfo t f) = Flagged (fmap (Q pp) fn) nfo (go t) (go f)
185- go1 (Stanza sn t) = Stanza (fmap (Q pp) sn) (go t)
186- go1 (Simple dep comp) = Simple (goLDep dep comp) comp
176+ go1 (Stanza sn t) = Stanza (fmap (Q pp) sn) (go t)
177+ go1 (Simple dep comp) = Simple (goLDep dep comp) comp
187178
188179 -- Suppose package B has a setup dependency on package A.
189180 -- This will be recorded as something like
@@ -197,15 +188,14 @@ qualifyDeps QO{..} (Q pp@(PackagePath ns q) pn) = go
197188 goLDep (LDep dr dep) comp = LDep (fmap (Q pp) dr) (goD dep comp)
198189
199190 goD :: Dep PN -> Component -> Dep QPN
200- goD (Ext ext) _ = Ext ext
201- goD (Lang lang) _ = Lang lang
202- goD (Pkg pkn vr) _ = Pkg pkn vr
191+ goD (Ext ext) _ = Ext ext
192+ goD (Lang lang) _ = Lang lang
193+ goD (Pkg pkn vr) _ = Pkg pkn vr
203194 goD (Dep dep@ (PkgComponent qpn (ExposedExe _)) ci) _ =
204- Dep (Q (PackagePath ns (QualExe pn qpn)) <$> dep) ci
205- goD (Dep dep@ (PkgComponent qpn (ExposedLib _)) ci) comp
206- | qBase qpn = Dep (Q (PackagePath ns (QualBase pn)) <$> dep) ci
207- | qSetup comp = Dep (Q (PackagePath ns (QualSetup pn)) <$> dep) ci
208- | otherwise = Dep (Q (PackagePath ns inheritedQ ) <$> dep) ci
195+ Dep (Q (PackagePath ns (QualExe pn qpn)) <$> dep) ci
196+ goD (Dep dep@ (PkgComponent _qpn (ExposedLib _)) ci) comp
197+ | comp == ComponentSetup = Dep (Q (PackagePath ns (QualSetup pn)) <$> dep) ci
198+ | otherwise = Dep (Q (PackagePath ns inheritedQ) <$> dep) ci
209199
210200 -- If P has a setup dependency on Q, and Q has a regular dependency on R, then
211201 -- we say that the 'Setup' qualifier is inherited: P has an (indirect) setup
@@ -216,18 +206,9 @@ qualifyDeps QO{..} (Q pp@(PackagePath ns q) pn) = go
216206 -- a detailed discussion.
217207 inheritedQ :: Qualifier
218208 inheritedQ = case q of
219- QualSetup _ -> q
220- QualExe _ _ -> q
221- QualToplevel -> q
222- QualBase _ -> QualToplevel
223-
224- -- Should we qualify this goal with the 'Base' package path?
225- qBase :: PN -> Bool
226- qBase dep = qoBaseShim && unPackageName dep == " base"
227-
228- -- Should we qualify this goal with the 'Setup' package path?
229- qSetup :: Component -> Bool
230- qSetup comp = qoSetupIndependent && comp == ComponentSetup
209+ QualSetup _ -> q
210+ QualExe _ _ -> q
211+ QualToplevel -> q
231212
232213-- | Remove qualifiers from set of dependencies
233214--
@@ -244,8 +225,8 @@ unqualifyDeps = go
244225
245226 go1 :: FlaggedDep QPN -> FlaggedDep PN
246227 go1 (Flagged fn nfo t f) = Flagged (fmap unq fn) nfo (go t) (go f)
247- go1 (Stanza sn t) = Stanza (fmap unq sn) (go t)
248- go1 (Simple dep comp) = Simple (goLDep dep) comp
228+ go1 (Stanza sn t) = Stanza (fmap unq sn) (go t)
229+ go1 (Simple dep comp) = Simple (goLDep dep) comp
249230
250231 goLDep :: LDep QPN -> LDep PN
251232 goLDep (LDep dr dep) = LDep (fmap unq dr) (fmap unq dep)
@@ -271,8 +252,8 @@ data Goal qpn = Goal (Var qpn) (GoalReason qpn)
271252 deriving (Eq , Show , Functor )
272253
273254-- | Reason why a goal is being added to a goal set.
274- data GoalReason qpn =
275- UserGoal -- introduced by a build target
255+ data GoalReason qpn
256+ = UserGoal -- introduced by a build target
276257 | DependencyGoal (DependencyReason qpn ) -- introduced by a package
277258 deriving (Eq , Show , Functor )
278259
@@ -288,7 +269,7 @@ varToConflictSet = CS.singleton
288269-- | Convert a 'GoalReason' to a 'ConflictSet' that can be used when the goal
289270-- leads to a conflict.
290271goalReasonToConflictSet :: GoalReason QPN -> ConflictSet
291- goalReasonToConflictSet UserGoal = CS. empty
272+ goalReasonToConflictSet UserGoal = CS. empty
292273goalReasonToConflictSet (DependencyGoal dr) = dependencyReasonToConflictSet dr
293274
294275-- | Convert a 'GoalReason' to a 'ConflictSet' containing the reason that the
@@ -302,14 +283,14 @@ goalReasonToConflictSetWithConflict :: QPN -> GoalReason QPN -> ConflictSet
302283goalReasonToConflictSetWithConflict goal (DependencyGoal (DependencyReason qpn flags stanzas))
303284 | M. null flags && S. null stanzas =
304285 CS. singletonWithConflict (P qpn) $ CS. GoalConflict goal
305- goalReasonToConflictSetWithConflict _ gr = goalReasonToConflictSet gr
286+ goalReasonToConflictSetWithConflict _ gr = goalReasonToConflictSet gr
306287
307288-- | This function returns the solver variables responsible for the dependency.
308289-- It drops the values chosen for flag and stanza variables, which are only
309290-- needed for log messages.
310291dependencyReasonToConflictSet :: DependencyReason QPN -> ConflictSet
311292dependencyReasonToConflictSet (DependencyReason qpn flags stanzas) =
312- CS. fromList $ P qpn : flagVars ++ map stanzaToVar (S. toList stanzas)
293+ CS. fromList $ P qpn : flagVars ++ map stanzaToVar (S. toList stanzas)
313294 where
314295 -- Filter out any flags that introduced the dependency with both values.
315296 -- They don't need to be included in the conflict set, because changing the
@@ -327,16 +308,19 @@ dependencyReasonToConflictSet (DependencyReason qpn flags stanzas) =
327308-- This function currently only specifies the reason for the conflict in the
328309-- simple case where the 'DependencyReason' does not involve any flags or
329310-- stanzas. Otherwise, it falls back to calling 'dependencyReasonToConflictSet'.
330- dependencyReasonToConflictSetWithVersionConstraintConflict :: QPN
331- -> Ver
332- -> DependencyReason QPN
333- -> ConflictSet
334311dependencyReasonToConflictSetWithVersionConstraintConflict
335- dependency excludedVersion dr@ (DependencyReason qpn flags stanzas)
336- | M. null flags && S. null stanzas =
337- CS. singletonWithConflict (P qpn) $
338- CS. VersionConstraintConflict dependency excludedVersion
339- | otherwise = dependencyReasonToConflictSet dr
312+ :: QPN
313+ -> Ver
314+ -> DependencyReason QPN
315+ -> ConflictSet
316+ dependencyReasonToConflictSetWithVersionConstraintConflict
317+ dependency
318+ excludedVersion
319+ dr@ (DependencyReason qpn flags stanzas)
320+ | M. null flags && S. null stanzas =
321+ CS. singletonWithConflict (P qpn) $
322+ CS. VersionConstraintConflict dependency excludedVersion
323+ | otherwise = dependencyReasonToConflictSet dr
340324
341325-- | Convert a 'DependencyReason' to a 'ConflictSet' specifying that the
342326-- conflict occurred because the conflict set variables introduced a version of
@@ -346,13 +330,16 @@ dependencyReasonToConflictSetWithVersionConstraintConflict
346330-- This function currently only specifies the reason for the conflict in the
347331-- simple case where the 'DependencyReason' does not involve any flags or
348332-- stanzas. Otherwise, it falls back to calling 'dependencyReasonToConflictSet'.
349- dependencyReasonToConflictSetWithVersionConflict :: QPN
350- -> CS. OrderedVersionRange
351- -> DependencyReason QPN
352- -> ConflictSet
353333dependencyReasonToConflictSetWithVersionConflict
354- pkgWithVersionConstraint constraint dr@ (DependencyReason qpn flags stanzas)
355- | M. null flags && S. null stanzas =
356- CS. singletonWithConflict (P qpn) $
357- CS. VersionConflict pkgWithVersionConstraint constraint
358- | otherwise = dependencyReasonToConflictSet dr
334+ :: QPN
335+ -> CS. OrderedVersionRange
336+ -> DependencyReason QPN
337+ -> ConflictSet
338+ dependencyReasonToConflictSetWithVersionConflict
339+ pkgWithVersionConstraint
340+ constraint
341+ dr@ (DependencyReason qpn flags stanzas)
342+ | M. null flags && S. null stanzas =
343+ CS. singletonWithConflict (P qpn) $
344+ CS. VersionConflict pkgWithVersionConstraint constraint
345+ | otherwise = dependencyReasonToConflictSet dr
0 commit comments