@@ -58,15 +58,16 @@ updateTargetAnnotation t ta = ta{taTarget = taTarget ta <> t}
58
58
-- doc for more info).
59
59
annotateCondTree
60
60
:: forall a
61
- . Monoid a
61
+ . ( Eq a , Monoid a )
62
62
=> [PackageFlag ] -- User flags.
63
63
-> TargetAnnotation a
64
64
-> CondTree ConfVar [Dependency ] a
65
65
-> CondTree ConfVar [Dependency ] (TargetAnnotation a )
66
66
annotateCondTree fs ta (CondNode a c bs) =
67
67
let ta' = updateTargetAnnotation a ta
68
68
bs' = map (annotateBranch ta') bs
69
- in CondNode ta' c bs'
69
+ bs'' = crossAnnotateBranches defTrueFlags bs'
70
+ in CondNode ta' c bs''
70
71
where
71
72
annotateBranch
72
73
:: TargetAnnotation a
@@ -107,12 +108,55 @@ annotateCondTree fs ta (CondNode a c bs) =
107
108
)
108
109
fs
109
110
111
+ defTrueFlags :: [PackageFlag ]
112
+ defTrueFlags = filter flagDefault fs
113
+
114
+ -- Propagate contextual information in CondTree branches. This is
115
+ -- needed as CondTree is a rosetree and not a binary tree.
116
+ crossAnnotateBranches
117
+ :: forall a
118
+ . (Eq a , Monoid a )
119
+ => [PackageFlag ] -- `default: true` flags.
120
+ -> [CondBranch ConfVar [Dependency ] (TargetAnnotation a )]
121
+ -> [CondBranch ConfVar [Dependency ] (TargetAnnotation a )]
122
+ crossAnnotateBranches fs bs = map crossAnnBranch bs
123
+ where
124
+ crossAnnBranch
125
+ :: CondBranch ConfVar [Dependency ] (TargetAnnotation a )
126
+ -> CondBranch ConfVar [Dependency ] (TargetAnnotation a )
127
+ crossAnnBranch wr =
128
+ let
129
+ rs = filter (/= wr) bs
130
+ ts = mapMaybe realiseBranch rs
131
+ in
132
+ updateTargetAnnBranch (mconcat ts) wr
133
+
134
+ realiseBranch :: CondBranch ConfVar [Dependency ] (TargetAnnotation a ) -> Maybe a
135
+ realiseBranch b =
136
+ let
137
+ -- We are only interested in True by default package flags.
138
+ realiseBranchFunction :: ConfVar -> Either ConfVar Bool
139
+ realiseBranchFunction (PackageFlag n) | elem n (map flagName fs) = Right True
140
+ realiseBranchFunction _ = Right False
141
+ ms = simplifyCondBranch realiseBranchFunction (fmap taTarget b)
142
+ in
143
+ fmap snd ms
144
+
145
+ updateTargetAnnBranch
146
+ :: a
147
+ -> CondBranch ConfVar [Dependency ] (TargetAnnotation a )
148
+ -> CondBranch ConfVar [Dependency ] (TargetAnnotation a )
149
+ updateTargetAnnBranch a (CondBranch k t mt) =
150
+ let updateTargetAnnTree (CondNode ka c wbs) =
151
+ (CondNode (updateTargetAnnotation a ka) c wbs)
152
+ in CondBranch k (updateTargetAnnTree t) (updateTargetAnnTree <$> mt)
153
+
110
154
-- | A conditional target is a library, exe, benchmark etc., destructured
111
155
-- in a CondTree. Traversing method: we render the branches, pass a
112
156
-- relevant context, collect checks.
113
157
checkCondTarget
114
158
:: forall m a
115
- . (Monad m , Monoid a )
159
+ . (Monad m , Eq a , Monoid a )
116
160
=> [PackageFlag ] -- User flags.
117
161
-> (a -> CheckM m () ) -- Check function (a = target).
118
162
-> (UnqualComponentName -> a -> a )
@@ -131,7 +175,7 @@ checkCondTarget fs cf nf (unqualName, ct) =
131
175
:: CondTree ConfVar [Dependency ] (TargetAnnotation a )
132
176
-> CheckM m ()
133
177
wTree (CondNode ta _ bs)
134
- -- There are no branches (and [] == True) *or* every branch
178
+ -- There are no branches ([] == True) *or* every branch
135
179
-- is “simple” (i.e. missing a 'condBranchIfFalse' part).
136
180
-- This is convenient but not necessarily correct in all
137
181
-- cases; a more precise way would be to check incompatibility
0 commit comments