@@ -31,6 +31,7 @@ import Data.Set qualified as Set
31
31
import Data.Map qualified as Map
32
32
import Data.List.Extra
33
33
import Data.List.NonEmpty (nonEmpty )
34
+ import Data.Either
34
35
import Data.Maybe
35
36
import Data.Monoid
36
37
import Data.Semigroup
@@ -157,6 +158,11 @@ checkPragmas modu flags exts mps =
157
158
, not $ null bad]
158
159
isGood def mp x = maybe def (within modu " " . riWithin) $ Map. lookup x mp
159
160
161
+
162
+ -- | Extension to GHC's 'ImportDeclQualifiedStyle', expressing @qualifiedStyle: unrestricted@,
163
+ -- i.e. the preference of "either pre- or post-, but qualified" in a rule.
164
+ data QualifiedPostOrPre = QualifiedPostOrPre deriving Eq
165
+
160
166
checkImports :: String -> [LImportDecl GhcPs ] -> (Bool , Map. Map String RestrictItem ) -> [Idea ]
161
167
checkImports modu lImportDecls (def, mp) = mapMaybe getImportHint lImportDecls
162
168
where
@@ -190,30 +196,37 @@ checkImports modu lImportDecls (def, mp) = mapMaybe getImportHint lImportDecls
190
196
case fromMaybe ImportStyleUnrestricted $ getAlt riImportStyle of
191
197
ImportStyleUnrestricted
192
198
| NotQualified <- ideclQualified -> (Nothing , Nothing )
193
- | otherwise -> (second (<> " or unqualified" ) <$> expectedQualStyle, Nothing )
194
- ImportStyleQualified -> (expectedQualStyleDef , Nothing )
199
+ | otherwise -> (Just $ second (<> " or unqualified" ) expectedQualStyle, Nothing )
200
+ ImportStyleQualified -> (Just expectedQualStyle , Nothing )
195
201
ImportStyleExplicitOrQualified
196
202
| Just (False , _) <- first (== EverythingBut ) <$> ideclImportList -> (Nothing , Nothing )
197
203
| otherwise ->
198
- ( second (<> " or with an explicit import list" ) <$> expectedQualStyleDef
204
+ ( Just $ second (<> " or with an explicit import list" ) expectedQualStyle
199
205
, Nothing )
200
206
ImportStyleExplicit
201
207
| Just (False , _) <- first (== EverythingBut ) <$> ideclImportList -> (Nothing , Nothing )
202
208
| otherwise ->
203
- ( Just (NotQualified , " unqualified" )
209
+ ( Just (Right NotQualified , " unqualified" )
204
210
, Just $ Just (Exactly , noLocA [] ) )
205
- ImportStyleUnqualified -> (Just (NotQualified , " unqualified" ), Nothing )
206
- expectedQualStyleDef = expectedQualStyle <|> Just (QualifiedPre , " qualified" )
211
+ ImportStyleUnqualified -> (Just (Right NotQualified , " unqualified" ), Nothing )
207
212
expectedQualStyle =
208
213
case fromMaybe QualifiedStyleUnrestricted $ getAlt riQualifiedStyle of
209
- QualifiedStyleUnrestricted -> Nothing
210
- QualifiedStylePost -> Just (QualifiedPost , " post-qualified" )
211
- QualifiedStylePre -> Just (QualifiedPre , " pre-qualified" )
214
+ QualifiedStyleUnrestricted -> (Left QualifiedPostOrPre , " qualified" )
215
+ QualifiedStylePost -> (Right QualifiedPost , " post-qualified" )
216
+ QualifiedStylePre -> (Right QualifiedPre , " pre-qualified" )
217
+ -- unless expectedQual is Nothing, it holds the Idea (hint) to ultimately emit,
218
+ -- except in these cases when the rule's requirements are fulfilled in-source:
212
219
qualIdea
213
- | Just ideclQualified == (fst <$> expectedQual) = Nothing
220
+ -- the rule demands a particular importStyle, and the decl obeys exactly
221
+ | Just (Right ideclQualified) == (fst <$> expectedQual) = Nothing
222
+ -- the rule demands a QualifiedPostOrPre import, and the decl does either
223
+ | Just (Left QualifiedPostOrPre ) == (fst <$> expectedQual)
224
+ && ideclQualified `elem` [QualifiedPost , QualifiedPre ] = Nothing
225
+ -- otherwise, expectedQual gets converted into a warning below (or is Nothing)
214
226
| otherwise = expectedQual
215
227
whenJust qualIdea $ \ (qual, hint) -> do
216
- let i' = noLoc $ (unLoc i){ ideclQualified = qual
228
+ -- convert non-Nothing qualIdea into hlint's refactoring Idea
229
+ let i' = noLoc $ (unLoc i){ ideclQualified = fromRight QualifiedPre qual
217
230
, ideclImportList = fromMaybe ideclImportList expectedHiding }
218
231
msg = moduleNameString (unLoc ideclName) <> " should be imported " <> hint
219
232
Left $ warn msg (reLoc i) i' []
0 commit comments