PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/ghc-7.0.4/utils/haddock/src/Haddock/GhcUtils.hs

http://picorec.googlecode.com/
Haskell | 246 lines | 123 code | 79 blank | 44 comment | 1 complexity | ac7afbecc2af8d0d4e96ad96c2ba4e28 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. {-# LANGUAGE FlexibleInstances #-}
  2. {-# OPTIONS_GHC -fno-warn-orphans #-}
  3. {-# OPTIONS_HADDOCK hide #-}
  4. -----------------------------------------------------------------------------
  5. -- |
  6. -- Module : Haddock.GhcUtils
  7. -- Copyright : (c) David Waern 2006-2009
  8. -- License : BSD-like
  9. --
  10. -- Maintainer : haddock@projects.haskell.org
  11. -- Stability : experimental
  12. -- Portability : portable
  13. --
  14. -- Utils for dealing with types from the GHC API
  15. -----------------------------------------------------------------------------
  16. module Haddock.GhcUtils where
  17. import Data.Version
  18. import Control.Arrow
  19. import Data.Foldable hiding (concatMap)
  20. import Data.Traversable
  21. import Distribution.Compat.ReadP
  22. import Distribution.Text
  23. import Exception
  24. import Outputable
  25. import Name
  26. import Packages
  27. import Module
  28. import RdrName (GlobalRdrEnv)
  29. #if MIN_VERSION_ghc(7,1,0)
  30. import GhcMonad (withSession)
  31. #endif
  32. import HscTypes
  33. import UniqFM
  34. import GHC
  35. moduleString :: Module -> String
  36. moduleString = moduleNameString . moduleName
  37. -- return the (name,version) of the package
  38. modulePackageInfo :: Module -> (String, [Char])
  39. modulePackageInfo modu = case unpackPackageId pkg of
  40. Nothing -> (packageIdString pkg, "")
  41. Just x -> (display $ pkgName x, showVersion (pkgVersion x))
  42. where pkg = modulePackageId modu
  43. -- This was removed from GHC 6.11
  44. -- XXX we shouldn't be using it, probably
  45. -- | Try and interpret a GHC 'PackageId' as a cabal 'PackageIdentifer'. Returns @Nothing@ if
  46. -- we could not parse it as such an object.
  47. unpackPackageId :: PackageId -> Maybe PackageIdentifier
  48. unpackPackageId p
  49. = case [ pid | (pid,"") <- readP_to_S parse str ] of
  50. [] -> Nothing
  51. (pid:_) -> Just pid
  52. where str = packageIdString p
  53. mkModuleNoPackage :: String -> Module
  54. mkModuleNoPackage str = mkModule (stringToPackageId "") (mkModuleName str)
  55. lookupLoadedHomeModuleGRE :: GhcMonad m => ModuleName -> m (Maybe GlobalRdrEnv)
  56. lookupLoadedHomeModuleGRE mod_name = withSession $ \hsc_env ->
  57. case lookupUFM (hsc_HPT hsc_env) mod_name of
  58. Just mod_info -> return (mi_globals (hm_iface mod_info))
  59. _not_a_home_module -> return Nothing
  60. isNameSym :: Name -> Bool
  61. isNameSym = isSymOcc . nameOccName
  62. isVarSym :: OccName -> Bool
  63. isVarSym = isLexVarSym . occNameFS
  64. getMainDeclBinder :: HsDecl name -> Maybe name
  65. getMainDeclBinder (TyClD d) = Just (tcdName d)
  66. getMainDeclBinder (ValD d) =
  67. case collectHsBindBinders d of
  68. [] -> Nothing
  69. (name:_) -> Just name
  70. getMainDeclBinder (SigD d) = sigNameNoLoc d
  71. getMainDeclBinder (ForD (ForeignImport name _ _)) = Just (unLoc name)
  72. getMainDeclBinder (ForD (ForeignExport _ _ _)) = Nothing
  73. getMainDeclBinder _ = Nothing
  74. isTyClD :: HsDecl a -> Bool
  75. isTyClD (TyClD _) = True
  76. isTyClD _ = False
  77. isClassD :: HsDecl a -> Bool
  78. isClassD (TyClD d) = isClassDecl d
  79. isClassD _ = False
  80. isDocD :: HsDecl a -> Bool
  81. isDocD (DocD _) = True
  82. isDocD _ = False
  83. isInstD :: HsDecl a -> Bool
  84. isInstD (InstD _) = True
  85. isInstD (TyClD d) = isFamInstDecl d
  86. isInstD _ = False
  87. declATs :: HsDecl a -> [a]
  88. declATs (TyClD d) | isClassDecl d = map (tcdName . unL) $ tcdATs d
  89. declATs _ = []
  90. pretty :: Outputable a => a -> String
  91. pretty x = showSDoc (ppr x)
  92. trace_ppr :: Outputable a => a -> b -> b
  93. trace_ppr x y = trace (pretty x) y
  94. -------------------------------------------------------------------------------
  95. -- * Located
  96. -------------------------------------------------------------------------------
  97. unL :: Located a -> a
  98. unL (L _ x) = x
  99. reL :: a -> Located a
  100. reL = L undefined
  101. instance Foldable Located where
  102. foldMap f (L _ x) = f x
  103. instance Traversable Located where
  104. mapM f (L l x) = (return . L l) =<< f x
  105. -------------------------------------------------------------------------------
  106. -- * NamedThing instances
  107. -------------------------------------------------------------------------------
  108. instance NamedThing (TyClDecl Name) where
  109. getName = tcdName
  110. instance NamedThing (ConDecl Name) where
  111. getName = unL . con_name
  112. -------------------------------------------------------------------------------
  113. -- * Subordinates
  114. -------------------------------------------------------------------------------
  115. class Parent a where
  116. children :: a -> [Name]
  117. instance Parent (ConDecl Name) where
  118. children con =
  119. case con_details con of
  120. RecCon fields -> map (unL . cd_fld_name) fields
  121. _ -> []
  122. instance Parent (TyClDecl Name) where
  123. children d
  124. | isDataDecl d = map (unL . con_name . unL) . tcdCons $ d
  125. | isClassDecl d =
  126. map (tcdName . unL) (tcdATs d) ++
  127. [ unL n | L _ (TypeSig n _) <- tcdSigs d ]
  128. | otherwise = []
  129. -- | A parent and its children
  130. family :: (NamedThing a, Parent a) => a -> (Name, [Name])
  131. family = getName &&& children
  132. -- | A mapping from the parent (main-binder) to its children and from each
  133. -- child to its grand-children, recursively.
  134. families :: TyClDecl Name -> [(Name, [Name])]
  135. families d
  136. | isDataDecl d = family d : map (family . unL) (tcdCons d)
  137. | isClassDecl d = family d : concatMap (families . unL) (tcdATs d)
  138. | otherwise = []
  139. -- | A mapping from child to parent
  140. parentMap :: TyClDecl Name -> [(Name, Name)]
  141. parentMap d = [ (c, p) | (p, cs) <- families d, c <- cs ]
  142. -- | The parents of a subordinate in a declaration
  143. parents :: Name -> HsDecl Name -> [Name]
  144. parents n (TyClD d) = [ p | (c, p) <- parentMap d, c == n ]
  145. parents _ _ = []
  146. -------------------------------------------------------------------------------
  147. -- * Utils that work in monads defined by GHC
  148. -------------------------------------------------------------------------------
  149. modifySessionDynFlags :: (DynFlags -> DynFlags) -> Ghc ()
  150. modifySessionDynFlags f = do
  151. dflags <- getSessionDynFlags
  152. _ <- setSessionDynFlags (f dflags)
  153. return ()
  154. -- | A variant of 'gbracket' where the return value from the first computation
  155. -- is not required.
  156. gbracket_ :: ExceptionMonad m => m a -> m b -> m c -> m c
  157. gbracket_ before after thing = gbracket before (const after) (const thing)
  158. -------------------------------------------------------------------------------
  159. -- * DynFlags
  160. -------------------------------------------------------------------------------
  161. setObjectDir, setHiDir, setStubDir, setOutputDir :: String -> DynFlags -> DynFlags
  162. setObjectDir f d = d{ objectDir = Just f}
  163. setHiDir f d = d{ hiDir = Just f}
  164. setStubDir f d = d{ stubDir = Just f, includePaths = f : includePaths d }
  165. -- -stubdir D adds an implicit -I D, so that gcc can find the _stub.h file
  166. -- \#included from the .hc file when compiling with -fvia-C.
  167. setOutputDir f = setObjectDir f . setHiDir f . setStubDir f