{-# LANGUAGE TypeFamilies #-}
module Hint.Export(exportHint) where
import Hint.Type(ModuHint, ModuleEx(..),ideaNote,ignore,Note(..))
import GHC.Hs
import Module
import SrcLoc
import OccName
import RdrName
exportHint :: ModuHint
exportHint :: ModuHint
exportHint Scope
_ (ModuleEx (L SrcSpan
s m :: HsModule GhcPs
m@HsModule {hsmodName :: forall pass. HsModule pass -> Maybe (Located ModuleName)
hsmodName = Just Located ModuleName
name, hsmodExports :: forall pass. HsModule pass -> Maybe (Located [LIE pass])
hsmodExports = Maybe (Located [LIE GhcPs])
exports}) ApiAnns
_)
| Maybe (Located [LIE GhcPs])
Nothing <- Maybe (Located [LIE GhcPs])
exports =
let r :: HsModule GhcPs
r = HsModule GhcPs
o{ hsmodExports :: Maybe (Located [LIE GhcPs])
hsmodExports = Located [LIE GhcPs] -> Maybe (Located [LIE GhcPs])
forall a. a -> Maybe a
Just (SrcSpanLess (Located [LIE GhcPs]) -> Located [LIE GhcPs]
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc [SrcSpanLess (LIE GhcPs) -> LIE GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XIEModuleContents GhcPs -> Located ModuleName -> IE GhcPs
forall pass.
XIEModuleContents pass -> Located ModuleName -> IE pass
IEModuleContents NoExtField
XIEModuleContents GhcPs
noExtField Located ModuleName
name)] )} in
[(String
-> GenLocated SrcSpan (HsModule GhcPs)
-> GenLocated SrcSpan (HsModule GhcPs)
-> [Refactoring SrcSpan]
-> Idea
forall a.
(HasSrcSpan a, Outputable a) =>
String -> a -> a -> [Refactoring SrcSpan] -> Idea
ignore String
"Use module export list" (SrcSpan -> HsModule GhcPs -> GenLocated SrcSpan (HsModule GhcPs)
forall l e. l -> e -> GenLocated l e
L SrcSpan
s HsModule GhcPs
o) (SrcSpanLess (GenLocated SrcSpan (HsModule GhcPs))
-> GenLocated SrcSpan (HsModule GhcPs)
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc HsModule GhcPs
SrcSpanLess (GenLocated SrcSpan (HsModule GhcPs))
r) []){ideaNote :: [Note]
ideaNote = [String -> Note
Note String
"an explicit list is usually better"]}]
| Just (L SrcSpan
_ [LIE GhcPs]
xs) <- Maybe (Located [LIE GhcPs])
exports
, [LIE GhcPs]
mods <- [LIE GhcPs
x | LIE GhcPs
x <- [LIE GhcPs]
xs, LIE GhcPs -> Bool
forall l pass. GenLocated l (IE pass) -> Bool
isMod LIE GhcPs
x]
, String
modName <- ModuleName -> String
moduleNameString (Located ModuleName -> SrcSpanLess (Located ModuleName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located ModuleName
name)
, [String]
names <- [ ModuleName -> String
moduleNameString (Located ModuleName -> SrcSpanLess (Located ModuleName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located ModuleName
n) | (L SrcSpan
_ (IEModuleContents XIEModuleContents GhcPs
_ Located ModuleName
n)) <- [LIE GhcPs]
mods]
, [LIE GhcPs]
exports' <- [LIE GhcPs
x | LIE GhcPs
x <- [LIE GhcPs]
xs, Bool -> Bool
not (String -> LIE GhcPs -> Bool
forall l pass. String -> GenLocated l (IE pass) -> Bool
matchesModName String
modName LIE GhcPs
x)]
, String
modName String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
names =
let dots :: RdrName
dots = OccName -> RdrName
mkRdrUnqual (String -> OccName
mkVarOcc String
" ... ")
r :: HsModule GhcPs
r = HsModule GhcPs
o{ hsmodExports :: Maybe (Located [LIE GhcPs])
hsmodExports = Located [LIE GhcPs] -> Maybe (Located [LIE GhcPs])
forall a. a -> Maybe a
Just (SrcSpanLess (Located [LIE GhcPs]) -> Located [LIE GhcPs]
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (SrcSpanLess (LIE GhcPs) -> LIE GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XIEVar GhcPs -> LIEWrappedName (IdP GhcPs) -> IE GhcPs
forall pass. XIEVar pass -> LIEWrappedName (IdP pass) -> IE pass
IEVar NoExtField
XIEVar GhcPs
noExtField (SrcSpanLess (LIEWrappedName RdrName) -> LIEWrappedName RdrName
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (Located RdrName -> IEWrappedName RdrName
forall name. Located name -> IEWrappedName name
IEName (SrcSpanLess (Located RdrName) -> Located RdrName
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc RdrName
SrcSpanLess (Located RdrName)
dots)))) LIE GhcPs -> [LIE GhcPs] -> [LIE GhcPs]
forall a. a -> [a] -> [a]
: [LIE GhcPs]
exports') )}
in
[String
-> GenLocated SrcSpan (HsModule GhcPs)
-> GenLocated SrcSpan (HsModule GhcPs)
-> [Refactoring SrcSpan]
-> Idea
forall a.
(HasSrcSpan a, Outputable a) =>
String -> a -> a -> [Refactoring SrcSpan] -> Idea
ignore String
"Use explicit module export list" (SrcSpan -> HsModule GhcPs -> GenLocated SrcSpan (HsModule GhcPs)
forall l e. l -> e -> GenLocated l e
L SrcSpan
s HsModule GhcPs
o) (SrcSpanLess (GenLocated SrcSpan (HsModule GhcPs))
-> GenLocated SrcSpan (HsModule GhcPs)
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc HsModule GhcPs
SrcSpanLess (GenLocated SrcSpan (HsModule GhcPs))
r) []]
where
o :: HsModule GhcPs
o = HsModule GhcPs
m{hsmodImports :: [LImportDecl GhcPs]
hsmodImports=[], hsmodDecls :: [LHsDecl GhcPs]
hsmodDecls=[], hsmodDeprecMessage :: Maybe (Located WarningTxt)
hsmodDeprecMessage=Maybe (Located WarningTxt)
forall a. Maybe a
Nothing, hsmodHaddockModHeader :: Maybe LHsDocString
hsmodHaddockModHeader=Maybe LHsDocString
forall a. Maybe a
Nothing }
isMod :: GenLocated l (IE pass) -> Bool
isMod (L l
_ (IEModuleContents XIEModuleContents pass
_ Located ModuleName
_)) = Bool
True
isMod GenLocated l (IE pass)
_ = Bool
False
matchesModName :: String -> GenLocated l (IE pass) -> Bool
matchesModName String
m (L l
_ (IEModuleContents XIEModuleContents pass
_ (L SrcSpan
_ ModuleName
n))) = ModuleName -> String
moduleNameString ModuleName
n String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
m
matchesModName String
_ GenLocated l (IE pass)
_ = Bool
False
exportHint Scope
_ ModuleEx
_ = []