diff options
Diffstat (limited to 'src/Haddock/Interface/LexParseRn.hs')
-rw-r--r-- | src/Haddock/Interface/LexParseRn.hs | 100 |
1 files changed, 79 insertions, 21 deletions
diff --git a/src/Haddock/Interface/LexParseRn.hs b/src/Haddock/Interface/LexParseRn.hs index d013ca27..f70c5953 100644 --- a/src/Haddock/Interface/LexParseRn.hs +++ b/src/Haddock/Interface/LexParseRn.hs @@ -8,28 +8,34 @@ -- Stability : experimental -- Portability : portable ----------------------------------------------------------------------------- -module Haddock.Interface.LexParseRn ( - HaddockCommentType(..), - lexParseRnHaddockComment, - lexParseRnHaddockCommentList, - lexParseRnMbHaddockComment, - lexParseRnHaddockModHeader +module Haddock.Interface.LexParseRn + ( HaddockCommentType(..) + , lexParseRnHaddockComment + , lexParseRnHaddockCommentList + , lexParseRnMbHaddockComment + , lexParseRnHaddockModHeader ) where + import Haddock.Types import Haddock.Lex import Haddock.Parse -import Haddock.Interface.Rn import Haddock.Interface.ParseModuleHeader import Haddock.Doc + +import Control.Applicative import Data.Maybe import FastString import GHC -import Outputable ( showPpr ) +import Name +import Outputable import RdrName +import RnEnv + data HaddockCommentType = NormalHaddockComment | DocSectionComment + lexParseRnHaddockCommentList :: DynFlags -> HaddockCommentType -> GlobalRdrEnv -> [HsDocString] -> ErrMsgM (Maybe (Doc Name)) lexParseRnHaddockCommentList dflags hty gre docStrs = do docMbs <- mapM (lexParseRnHaddockComment dflags hty gre) docStrs @@ -39,6 +45,7 @@ lexParseRnHaddockCommentList dflags hty gre docStrs = do DocEmpty -> return Nothing _ -> return (Just doc) + lexParseRnHaddockComment :: DynFlags -> HaddockCommentType -> GlobalRdrEnv -> HsDocString -> ErrMsgM (Maybe (Doc Name)) lexParseRnHaddockComment dflags hty gre (HsDocString fs) = do @@ -51,27 +58,78 @@ lexParseRnHaddockComment dflags hty gre (HsDocString fs) = do Nothing -> do tell ["doc comment parse failed: "++str] return Nothing - Just doc -> return (Just (rnDoc gre doc)) + Just doc -> return (Just (rename gre doc)) + lexParseRnMbHaddockComment :: DynFlags -> HaddockCommentType -> GlobalRdrEnv -> Maybe HsDocString -> ErrMsgM (Maybe (Doc Name)) lexParseRnMbHaddockComment _ _ _ Nothing = return Nothing lexParseRnMbHaddockComment dflags hty gre (Just d) = lexParseRnHaddockComment dflags hty gre d + -- yes, you always get a HaddockModInfo though it might be empty lexParseRnHaddockModHeader :: DynFlags -> GlobalRdrEnv -> GhcDocHdr -> ErrMsgM (HaddockModInfo Name, Maybe (Doc Name)) lexParseRnHaddockModHeader dflags gre mbStr = do - (hmod, docn) <- case mbStr of - Nothing -> return failure - Just (L _ (HsDocString fs)) -> do - let str = unpackFS fs - case parseModuleHeader dflags str of - Left mess -> do - tell ["haddock module header parse failed: " ++ mess] - return failure - Right (info, doc) -> - return (rnHaddockModInfo gre info, Just (rnDoc gre doc)) - return (hmod { hmi_safety = safety }, docn) - + (hmi, docn) <- + case mbStr of + Nothing -> return failure + Just (L _ (HsDocString fs)) -> do + let str = unpackFS fs + case parseModuleHeader dflags str of + Left mess -> do + tell ["haddock module header parse failed: " ++ mess] + return failure + Right (info, doc) -> return (renameHmi gre info, Just (rename gre doc)) + return (hmi { hmi_safety = safety }, docn) where safety = Just $ showPpr $ safeHaskell dflags failure = (emptyHaddockModInfo, Nothing) + + +renameHmi :: GlobalRdrEnv -> HaddockModInfo RdrName -> HaddockModInfo Name +renameHmi gre hmi = hmi { hmi_description = rename gre <$> hmi_description hmi } + + +rename :: GlobalRdrEnv -> Doc RdrName -> Doc Name +rename gre = rn + where + rn d = case d of + DocAppend a b -> DocAppend (rn a) (rn b) + DocParagraph doc -> DocParagraph (rn doc) + DocIdentifier x -> do + let choices = dataTcOccs x + let names = concatMap (\c -> map gre_name (lookupGRE_RdrName c gre)) choices + case names of + [] -> + case choices of + [] -> DocMonospaced (DocString (showSDoc $ ppr x)) + [a] -> outOfScope a + a:b:_ | isRdrTc a -> outOfScope a | otherwise -> outOfScope b + [a] -> DocIdentifier a + a:b:_ | isTyConName a -> DocIdentifier a | otherwise -> DocIdentifier b + -- If an id can refer to multiple things, we give precedence to type + -- constructors. + DocEmphasis doc -> DocEmphasis (rn doc) + DocMonospaced doc -> DocMonospaced (rn doc) + DocUnorderedList docs -> DocUnorderedList (map rn docs) + DocOrderedList docs -> DocOrderedList (map rn docs) + DocDefList list -> DocDefList [ (rn a, rn b) | (a, b) <- list ] + DocCodeBlock doc -> DocCodeBlock (rn doc) + DocIdentifierUnchecked x -> DocIdentifierUnchecked x + DocModule str -> DocModule str + DocURL str -> DocURL str + DocPic str -> DocPic str + DocAName str -> DocAName str + DocExamples e -> DocExamples e + DocEmpty -> DocEmpty + DocString str -> DocString str + + +outOfScope :: RdrName -> Doc a +outOfScope x = + case x of + Unqual occ -> monospaced occ + Qual mdl occ -> DocIdentifierUnchecked (mdl, occ) + Orig _ occ -> monospaced occ + Exact name -> monospaced name -- Shouldn't happen since x is out of scope + where + monospaced a = DocMonospaced (DocString (showSDoc $ ppr a)) |