aboutsummaryrefslogtreecommitdiff
path: root/src/HaddockUtil.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/HaddockUtil.hs')
-rw-r--r--src/HaddockUtil.hs94
1 files changed, 71 insertions, 23 deletions
diff --git a/src/HaddockUtil.hs b/src/HaddockUtil.hs
index ef209f98..58033edc 100644
--- a/src/HaddockUtil.hs
+++ b/src/HaddockUtil.hs
@@ -9,7 +9,7 @@ module HaddockUtil (
-- * Misc utilities
nameOfQName, collectNames, declBinders, declMainBinder, splitTyConApp,
- restrictTo,
+ restrictTo, declDoc, parseModuleHeader,
-- * Filename utilities
basename, dirname, splitFilename3,
@@ -25,6 +25,7 @@ import HsSyn
import List ( intersect )
import IO ( hPutStr, stderr )
import System
+import RegexString
-- -----------------------------------------------------------------------------
-- Some Utilities
@@ -38,25 +39,25 @@ collectNames ds = concat (map declBinders ds)
declMainBinder :: HsDecl -> Maybe HsName
declMainBinder d =
case d of
- HsTypeDecl _ n _ _ -> Just n
- HsDataDecl _ _ n _ cons _ -> Just n
- HsNewTypeDecl _ _ n _ _ _ -> Just n
- HsClassDecl _ qt _ decls -> Just (exQtNm qt)
- HsTypeSig _ [n] _ -> Just n
- HsTypeSig _ ns _ -> error "declMainBinder"
- HsForeignImport _ _ _ _ n _ -> Just n
- _ -> Nothing
+ HsTypeDecl _ n _ _ _ -> Just n
+ HsDataDecl _ _ n _ cons _ _ -> Just n
+ HsNewTypeDecl _ _ n _ _ _ _ -> Just n
+ HsClassDecl _ qt _ decls _ -> Just (exQtNm qt)
+ HsTypeSig _ [n] _ _ -> Just n
+ HsTypeSig _ ns _ _ -> error "declMainBinder"
+ HsForeignImport _ _ _ _ n _ _ -> Just n
+ _ -> Nothing
declBinders :: HsDecl -> [HsName]
declBinders d =
case d of
- HsTypeDecl _ n _ _ -> [n]
- HsDataDecl _ _ n _ cons _ -> n : concat (map conDeclBinders cons)
- HsNewTypeDecl _ _ n _ con _ -> n : conDeclBinders con
- HsClassDecl _ qt _ decls -> exQtNm qt : collectNames decls
- HsTypeSig _ ns _ -> ns
- HsForeignImport _ _ _ _ n _ -> [n]
- _ -> []
+ HsTypeDecl _ n _ _ _ -> [n]
+ HsDataDecl _ _ n _ cons _ _ -> n : concat (map conDeclBinders cons)
+ HsNewTypeDecl _ _ n _ con _ _ -> n : conDeclBinders con
+ HsClassDecl _ qt _ decls _ -> exQtNm qt : collectNames decls
+ HsTypeSig _ ns _ _ -> ns
+ HsForeignImport _ _ _ _ n _ _ -> [n]
+ _ -> []
conDeclBinders (HsConDecl _ n _ _ _ _) = [n]
conDeclBinders (HsRecDecl _ n _ _ fields _) =
@@ -67,7 +68,7 @@ fieldDeclBinders (HsFieldDecl ns _ _) = ns
exQtNm (HsForAllType _ _ t) = nameOfQName (fst (splitTyConApp t))
exQtNm t = nameOfQName (fst (splitTyConApp t))
-splitTyConApp :: HsType -> (HsQName,[HsType])
+splitTyConApp :: HsType -> (HsQName, [HsType])
splitTyConApp t = split t []
where
split :: HsType -> [HsType] -> (HsQName,[HsType])
@@ -80,12 +81,12 @@ splitTyConApp t = split t []
restrictTo :: [HsName] -> HsDecl -> HsDecl
restrictTo names decl = case decl of
- HsDataDecl loc ctxt n xs cons drv ->
- HsDataDecl loc ctxt n xs (restrictCons names cons) drv
- HsNewTypeDecl loc ctxt n xs con drv ->
- HsDataDecl loc ctxt n xs (restrictCons names [con]) drv
- HsClassDecl loc qt fds decls ->
- HsClassDecl loc qt fds (restrictDecls names decls)
+ HsDataDecl loc ctxt n xs cons drv doc ->
+ HsDataDecl loc ctxt n xs (restrictCons names cons) drv doc
+ HsNewTypeDecl loc ctxt n xs con drv doc ->
+ HsDataDecl loc ctxt n xs (restrictCons names [con]) drv doc
+ HsClassDecl loc qt fds decls doc ->
+ HsClassDecl loc qt fds (restrictDecls names decls) doc
_ -> decl
restrictCons :: [HsName] -> [HsConDecl] -> [HsConDecl]
@@ -100,6 +101,52 @@ restrictDecls names decls = filter keep decls
-- ToDo: not really correct
-- -----------------------------------------------------------------------------
+-- Extract documentation from a declaration
+
+declDoc (HsTypeDecl _ _ _ _ d) = d
+declDoc (HsDataDecl _ _ _ _ _ _ d) = d
+declDoc (HsNewTypeDecl _ _ _ _ _ _ d) = d
+declDoc (HsClassDecl _ _ _ _ d) = d
+declDoc (HsTypeSig _ _ _ d) = d
+declDoc (HsForeignImport _ _ _ _ _ _ d) = d
+declDoc _ = Nothing
+
+-- -----------------------------------------------------------------------------
+-- Parsing module headers
+
+parseModuleHeader :: String -> (String, Maybe ModuleInfo)
+parseModuleHeader str =
+ case matchRegexAll moduleHeaderRE str of
+ Just (before, match, after, _, (_:_:_:s1:s2:s3:_)) ->
+ (after, Just (ModuleInfo {
+ portability = s3,
+ stability = s2,
+ maintainer = s1 }))
+ _other -> (str, Nothing)
+
+moduleHeaderRE = mkRegexWithOpts
+ "^([ \t\n]*Module[ \t]*:.*\n)?\
+ \([ \t\n]*Copyright[ \t]*:.*\n)?\
+ \([ \t\n]*License[ \t]*:.*\n)?\
+ \[ \t\n]*Maintainer[ \t]*:(.*)\n\
+ \[ \t\n]*Stability[ \t]*:(.*)\n\
+ \[ \t\n]*Portability[ \t]*:([^\n]*)\n"
+ True -- match "\n" with "."
+ False -- not case sensitive
+ -- All fields except the last (Portability) may be multi-line.
+ -- This is so that the portability field doesn't swallow up the
+ -- rest of the module documentation - we might want to revist
+ -- this at some point (perhaps have a separator between the
+ -- portability field and the module documentation?).
+
+#if __GLASGOW_HASKELL__ < 500
+mkRegexWithOpts :: String -> Bool -> Bool -> Regex
+mkRegexWithOpts s single_line case_sensitive
+ = unsafePerformIO (re_compile_pattern (packString s)
+ single_line case_sensitive)
+#endif
+
+-- -----------------------------------------------------------------------------
-- Filename mangling functions stolen from GHC's main/DriverUtil.lhs.
type Suffix = String
@@ -159,3 +206,4 @@ mapSnd f ((x,y):xs) = (x,f y) : mapSnd f xs
mapMaybeM :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
mapMaybeM f Nothing = return Nothing
mapMaybeM f (Just a) = f a >>= return . Just
+