module Haddock.GhcUtils where
import Control.Arrow
import Data.Function
import Exception
import Outputable
import Name
import Lexeme
import Module
import RdrName (GlobalRdrEnv)
import GhcMonad (withSession)
import HscTypes
import UniqFM
import GHC
import Class
moduleString :: Module -> String
moduleString = moduleNameString . moduleName
lookupLoadedHomeModuleGRE :: GhcMonad m => ModuleName -> m (Maybe GlobalRdrEnv)
lookupLoadedHomeModuleGRE mod_name = withSession $ \hsc_env ->
case lookupUFM (hsc_HPT hsc_env) mod_name of
Just mod_info -> return (mi_globals (hm_iface mod_info))
_not_a_home_module -> return Nothing
isNameSym :: Name -> Bool
isNameSym = isSymOcc . nameOccName
isVarSym :: OccName -> Bool
isVarSym = isLexVarSym . occNameFS
isConSym :: OccName -> Bool
isConSym = isLexConSym . occNameFS
getMainDeclBinder :: HsDecl name -> [name]
getMainDeclBinder (TyClD d) = [tcdName d]
getMainDeclBinder (ValD d) =
case collectHsBindBinders d of
[] -> []
(name:_) -> [name]
getMainDeclBinder (SigD d) = sigNameNoLoc d
getMainDeclBinder (ForD (ForeignImport name _ _ _)) = [unLoc name]
getMainDeclBinder (ForD (ForeignExport _ _ _ _)) = []
getMainDeclBinder _ = []
getInstLoc :: InstDecl name -> SrcSpan
getInstLoc (ClsInstD (ClsInstDecl { cid_poly_ty = L l _ })) = l
getInstLoc (DataFamInstD (DataFamInstDecl { dfid_tycon = L l _ })) = l
getInstLoc (TyFamInstD (TyFamInstDecl
{ tfid_eqn = L _ (TyFamEqn { tfe_rhs = L l _ })})) = l
filterLSigNames :: (name -> Bool) -> LSig name -> Maybe (LSig name)
filterLSigNames p (L loc sig) = L loc <$> (filterSigNames p sig)
filterSigNames :: (name -> Bool) -> Sig name -> Maybe (Sig name)
filterSigNames p orig@(SpecSig n _ _) = ifTrueJust (p $ unLoc n) orig
filterSigNames p orig@(InlineSig n _) = ifTrueJust (p $ unLoc n) orig
filterSigNames p (FixSig (FixitySig ns ty)) =
case filter (p . unLoc) ns of
[] -> Nothing
filtered -> Just (FixSig (FixitySig filtered ty))
filterSigNames _ orig@(MinimalSig _ _) = Just orig
filterSigNames p (TypeSig ns ty nwcs) =
case filter (p . unLoc) ns of
[] -> Nothing
filtered -> Just (TypeSig filtered ty nwcs)
filterSigNames _ _ = Nothing
ifTrueJust :: Bool -> name -> Maybe name
ifTrueJust True = Just
ifTrueJust False = const Nothing
sigName :: LSig name -> [name]
sigName (L _ sig) = sigNameNoLoc sig
sigNameNoLoc :: Sig name -> [name]
sigNameNoLoc (TypeSig ns _ _) = map unLoc ns
sigNameNoLoc (PatSynSig n _ _ _ _) = [unLoc n]
sigNameNoLoc (SpecSig n _ _) = [unLoc n]
sigNameNoLoc (InlineSig n _) = [unLoc n]
sigNameNoLoc (FixSig (FixitySig ns _)) = map unLoc ns
sigNameNoLoc _ = []
isTyClD :: HsDecl a -> Bool
isTyClD (TyClD _) = True
isTyClD _ = False
isClassD :: HsDecl a -> Bool
isClassD (TyClD d) = isClassDecl d
isClassD _ = False
isDocD :: HsDecl a -> Bool
isDocD (DocD _) = True
isDocD _ = False
isInstD :: HsDecl a -> Bool
isInstD (InstD _) = True
isInstD _ = False
isValD :: HsDecl a -> Bool
isValD (ValD _) = True
isValD _ = False
declATs :: HsDecl a -> [a]
declATs (TyClD d) | isClassDecl d = map (unL . fdLName . unL) $ tcdATs d
declATs _ = []
pretty :: Outputable a => DynFlags -> a -> String
pretty = showPpr
trace_ppr :: Outputable a => DynFlags -> a -> b -> b
trace_ppr dflags x y = trace (pretty dflags x) y
unL :: Located a -> a
unL (L _ x) = x
reL :: a -> Located a
reL = L undefined
before :: Located a -> Located a -> Bool
before = (<) `on` getLoc
instance NamedThing (TyClDecl Name) where
getName = tcdName
class Parent a where
children :: a -> [Name]
instance Parent (ConDecl Name) where
children con =
case con_details con of
RecCon fields -> map unL $ concatMap (cd_fld_names . unL) (unL fields)
_ -> []
instance Parent (TyClDecl Name) where
children d
| isDataDecl d = map unL $ concatMap (con_names . unL)
$ (dd_cons . tcdDataDefn) $ d
| isClassDecl d =
map (unL . fdLName . unL) (tcdATs d) ++
[ unL n | L _ (TypeSig ns _ _) <- tcdSigs d, n <- ns ]
| otherwise = []
family :: (NamedThing a, Parent a) => a -> (Name, [Name])
family = getName &&& children
familyConDecl :: ConDecl Name -> [(Name, [Name])]
familyConDecl d = zip (map unL (con_names d)) (repeat $ children d)
families :: TyClDecl Name -> [(Name, [Name])]
families d
| isDataDecl d = family d : concatMap (familyConDecl . unL) (dd_cons (tcdDataDefn d))
| isClassDecl d = [family d]
| otherwise = []
parentMap :: TyClDecl Name -> [(Name, Name)]
parentMap d = [ (c, p) | (p, cs) <- families d, c <- cs ]
parents :: Name -> HsDecl Name -> [Name]
parents n (TyClD d) = [ p | (c, p) <- parentMap d, c == n ]
parents _ _ = []
modifySessionDynFlags :: (DynFlags -> DynFlags) -> Ghc ()
modifySessionDynFlags f = do
dflags <- getSessionDynFlags
_ <- setSessionDynFlags (f dflags)
return ()
gbracket_ :: ExceptionMonad m => m a -> m b -> m c -> m c
gbracket_ before_ after thing = gbracket before_ (const after) (const thing)
minimalDef :: GhcMonad m => Name -> m (Maybe ClassMinimalDef)
minimalDef n = do
mty <- lookupGlobalName n
case mty of
Just (ATyCon (tyConClass_maybe -> Just c)) -> return . Just $ classMinimalDef c
_ -> return Nothing
setObjectDir, setHiDir, setStubDir, setOutputDir :: String -> DynFlags -> DynFlags
setObjectDir f d = d{ objectDir = Just f}
setHiDir f d = d{ hiDir = Just f}
setStubDir f d = d{ stubDir = Just f, includePaths = f : includePaths d }
setOutputDir f = setObjectDir f . setHiDir f . setStubDir f