aboutsummaryrefslogtreecommitdiff
path: root/src/Haddock/GhcUtils.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Haddock/GhcUtils.hs')
-rw-r--r--src/Haddock/GhcUtils.hs195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/Haddock/GhcUtils.hs b/src/Haddock/GhcUtils.hs
new file mode 100644
index 00000000..af091a7a
--- /dev/null
+++ b/src/Haddock/GhcUtils.hs
@@ -0,0 +1,195 @@
+--
+-- Haddock - A Haskell Documentation Tool
+--
+-- (c) Simon Marlow 2003
+--
+
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_HADDOCK hide #-}
+
+
+module Haddock.GhcUtils where
+
+
+import Data.Char
+import Data.Version
+import qualified Data.Map as Map
+import Control.Arrow
+import Data.Foldable hiding (concatMap)
+import Data.Traversable
+
+import HsSyn
+import SrcLoc
+import Outputable
+import Name
+import Packages
+import Module
+
+
+moduleString :: Module -> String
+moduleString = moduleNameString . moduleName
+
+
+-- return the name of the package, with version info
+modulePackageString :: Module -> String
+modulePackageString = packageIdString . modulePackageId
+
+
+-- return the (name,version) of the package
+modulePackageInfo :: Module -> (String, [Char])
+modulePackageInfo modu = case unpackPackageId pkg of
+ Nothing -> (packageIdString pkg, "")
+#if __GLASGOW_HASKELL__ >= 609
+ Just x -> (display $ pkgName x, showVersion (pkgVersion x))
+#else
+ Just x -> (pkgName x, showVersion (pkgVersion x))
+#endif
+ where pkg = modulePackageId modu
+
+
+mkModuleNoPackage :: String -> Module
+mkModuleNoPackage str = mkModule (stringToPackageId "") (mkModuleName str)
+
+
+instance (Outputable a, Outputable b) => Outputable (Map.Map a b) where
+ ppr m = ppr (Map.toList m)
+
+
+isNameSym :: Name -> Bool
+isNameSym = isSymOcc . nameOccName
+
+
+isVarSym :: OccName -> Bool
+isVarSym = isLexVarSym . occNameFS
+
+
+getMainDeclBinder :: HsDecl name -> Maybe name
+getMainDeclBinder (TyClD d) = Just (tcdName d)
+getMainDeclBinder (ValD d)
+ = case collectAcc d [] of
+ [] -> Nothing
+ (name:_) -> Just (unLoc name)
+getMainDeclBinder (SigD d) = sigNameNoLoc d
+getMainDeclBinder (ForD (ForeignImport name _ _)) = Just (unLoc name)
+getMainDeclBinder (ForD (ForeignExport _ _ _)) = Nothing
+getMainDeclBinder _ = Nothing
+
+
+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 (TyClD d) = isFamInstDecl d
+isInstD _ = False
+
+
+declATs :: HsDecl a -> [a]
+declATs (TyClD d) | isClassDecl d = map (tcdName . unL) $ tcdATs d
+declATs _ = []
+
+
+pretty :: Outputable a => a -> String
+pretty x = showSDoc (ppr x)
+
+
+trace_ppr :: Outputable a => a -> b -> b
+trace_ppr x y = trace (pretty x) y
+
+
+-------------------------------------------------------------------------------
+-- Located
+-------------------------------------------------------------------------------
+
+
+unL :: Located a -> a
+unL (L _ x) = x
+
+
+reL :: a -> Located a
+reL = L undefined
+
+
+instance Foldable Located where
+ foldMap f (L _ x) = f x
+
+
+instance Traversable Located where
+ mapM f (L l x) = (return . L l) =<< f x
+
+
+-------------------------------------------------------------------------------
+-- NamedThing instances
+-------------------------------------------------------------------------------
+
+
+instance NamedThing (TyClDecl Name) where
+ getName = tcdName
+
+
+instance NamedThing (ConDecl Name) where
+ getName = unL . con_name
+
+
+-------------------------------------------------------------------------------
+-- Subordinates
+-------------------------------------------------------------------------------
+
+
+class Parent a where
+ children :: a -> [Name]
+
+
+instance Parent (ConDecl Name) where
+ children con =
+ case con_details con of
+ RecCon fields -> map (unL . cd_fld_name) fields
+ _ -> []
+
+
+instance Parent (TyClDecl Name) where
+ children d
+ | isDataDecl d = map (unL . con_name . unL) . tcdCons $ d
+ | isClassDecl d =
+ map (tcdName . unL) (tcdATs d) ++
+ [ unL n | L _ (TypeSig n _) <- tcdSigs d ]
+ | otherwise = []
+
+
+-- | A parent and its children
+family :: (NamedThing a, Parent a) => a -> (Name, [Name])
+family = getName &&& children
+
+
+-- | A mapping from the parent (main-binder) to its children and from each
+-- child to its grand-children, recursively.
+families :: TyClDecl Name -> [(Name, [Name])]
+families d
+ | isDataDecl d = family d : map (family . unL) (tcdCons d)
+ | isClassDecl d = family d : concatMap (families . unL) (tcdATs d)
+ | otherwise = []
+
+
+-- | A mapping from child to parent
+parentMap :: TyClDecl Name -> [(Name, Name)]
+parentMap d = [ (c, p) | (p, cs) <- families d, c <- cs ]
+
+
+-- | The parents of a subordinate in a declaration
+parents :: Name -> HsDecl Name -> [Name]
+parents n (TyClD d) = [ p | (c, p) <- parentMap d, c == n ]
+parents _ _ = []