diff options
| author | Alec Theriault <alec.theriault@gmail.com> | 2019-03-08 13:23:37 -0800 | 
|---|---|---|
| committer | Alec Theriault <alec.theriault@gmail.com> | 2019-03-09 11:22:55 -0800 | 
| commit | abb448ff120d6f09b6d070806de1d0eb334bc23b (patch) | |
| tree | 85ae5ea96f3c8b990ae5a2a7dac01230a33c1507 /haddock-api/src | |
| parent | 50cf001765123a6c787795dda50aaefa5f2beed7 (diff) | |
Better support for default methods in classes
  * default methods now get rendered differently
  * default associated types get rendered
  * fix a forgotten `s/TypeSig/ClassOpSig/` refactor in LaTeX backend
  * LaTeX backend now renders default method signatures
NB: there is still no way to document default class members and the
NB: LaTeX backend still crashes on associated types
Diffstat (limited to 'haddock-api/src')
| -rw-r--r-- | haddock-api/src/Haddock/Backends/LaTeX.hs | 47 | ||||
| -rw-r--r-- | haddock-api/src/Haddock/Backends/Xhtml/Decl.hs | 99 | ||||
| -rw-r--r-- | haddock-api/src/Haddock/Backends/Xhtml/Layout.hs | 4 | ||||
| -rw-r--r-- | haddock-api/src/Haddock/Types.hs | 3 | 
4 files changed, 102 insertions, 51 deletions
diff --git a/haddock-api/src/Haddock/Backends/LaTeX.hs b/haddock-api/src/Haddock/Backends/LaTeX.hs index 119bbc01..d2baefac 100644 --- a/haddock-api/src/Haddock/Backends/LaTeX.hs +++ b/haddock-api/src/Haddock/Backends/LaTeX.hs @@ -295,7 +295,7 @@ ppDecl decl pats (doc, fnArgsDoc) instances subdocs _fxts = case unLoc decl of  --    | Just _  <- tcdTyPats d    -> ppTyInst False loc doc d unicode  -- Family instances happen via FamInst now    TyClD _ d@ClassDecl{}          -> ppClassDecl instances doc subdocs d unicode -  SigD _ (TypeSig _ lnames ty)   -> ppFunSig (doc, fnArgsDoc) (map unLoc lnames) (hsSigWcType ty) unicode +  SigD _ (TypeSig _ lnames ty)   -> ppFunSig Nothing (doc, fnArgsDoc) (map unLoc lnames) (hsSigWcType ty) unicode    SigD _ (PatSynSig _ lnames ty) -> ppLPatSig (doc, fnArgsDoc) (map unLoc lnames) ty unicode    ForD _ d                       -> ppFor (doc, fnArgsDoc) d unicode    InstD _ _                      -> empty @@ -307,7 +307,7 @@ ppDecl decl pats (doc, fnArgsDoc) instances subdocs _fxts = case unLoc decl of  ppFor :: DocForDecl DocName -> ForeignDecl DocNameI -> Bool -> LaTeX  ppFor doc (ForeignImport _ (L _ name) typ _) unicode = -  ppFunSig doc [name] (hsSigType typ) unicode +  ppFunSig Nothing doc [name] (hsSigType typ) unicode  ppFor _ _ _ = error "ppFor error in Haddock.Backends.LaTeX"  --  error "foreign declarations are currently not supported by --latex" @@ -414,17 +414,23 @@ ppTySyn _ _ _ = error "declaration not supported by ppTySyn"  ------------------------------------------------------------------------------- -ppFunSig :: DocForDecl DocName -> [DocName] -> LHsType DocNameI -         -> Bool -> LaTeX -ppFunSig doc docnames (L _ typ) unicode = +ppFunSig +  :: Maybe LaTeX         -- ^ a prefix to put right before the signature +  -> DocForDecl DocName  -- ^ documentation +  -> [DocName]           -- ^ pattern names in the pattern signature +  -> LHsType DocNameI    -- ^ type of the pattern synonym +  -> Bool                -- ^ unicode +  -> LaTeX +ppFunSig leader doc docnames (L _ typ) unicode =    ppTypeOrFunSig typ doc -    ( ppTypeSig names typ False -    , hsep . punctuate comma $ map ppSymName names +    ( lead $ ppTypeSig names typ False +    , lead $ hsep . punctuate comma $ map ppSymName names      , dcolon unicode      )      unicode   where     names = map getName docnames +   lead = maybe id (<+>) leader  -- | Pretty-print a pattern synonym  ppLPatSig :: DocForDecl DocName  -- ^ documentation @@ -433,15 +439,7 @@ ppLPatSig :: DocForDecl DocName  -- ^ documentation            -> Bool                -- ^ unicode            -> LaTeX  ppLPatSig doc docnames ty unicode -  = ppTypeOrFunSig typ doc -      ( keyword "pattern" <+> ppTypeSig names typ False -      , keyword "pattern" <+> (hsep . punctuate comma $ map ppSymName names) -      , dcolon unicode -      ) -      unicode -  where -    typ = unLoc (hsSigType ty) -    names = map getName docnames +  = ppFunSig (Just (keyword "pattern")) doc docnames (hsSigType ty) unicode  -- | Pretty-print a type, adding documentation to the whole type and its  -- arguments as needed. @@ -585,6 +583,7 @@ ppFds fds unicode =                             hsep (map (ppDocName . unLoc) vars2) +-- TODO: associated types, associated type defaults, docs on default methods  ppClassDecl :: [DocInstance DocNameI]              -> Documentation DocName -> [(DocName, DocForDecl DocName)]              -> TyClDecl DocNameI -> Bool -> LaTeX @@ -610,13 +609,15 @@ ppClassDecl instances doc subdocs      methodTable =        text "\\haddockpremethods{}" <> emph (text "Methods") $$ -      vcat  [ ppFunSig doc names (hsSigWcType typ) unicode -            | L _ (TypeSig _ lnames typ) <- lsigs -            , let doc = lookupAnySubdoc (head names) subdocs -                  names = map unLoc lnames ] -              -- FIXME: is taking just the first name ok? Is it possible that -              -- there are different subdocs for different names in a single -              -- type signature? +      vcat  [ ppFunSig leader doc names (hsSigType typ) unicode +            | L _ (ClassOpSig _ is_def lnames typ) <- lsigs +            , let doc | is_def = noDocForDecl +                      | otherwise = lookupAnySubdoc (head names) subdocs +                  names = map unLoc lnames +                  leader = if is_def then Just (keyword "default") else Nothing +            ] +            -- N.B. taking just the first name is ok. Signatures with multiple +            -- names are expanded so that each name gets its own signature.      instancesBit = ppDocInstances unicode instances diff --git a/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs b/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs index f2cab635..56a79d57 100644 --- a/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs +++ b/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs @@ -36,6 +36,7 @@ import           Text.XHtml hiding     ( name, title, p, quote )  import BasicTypes (PromotionFlag(..), isPromoted)  import GHC hiding (LexicalFixity(..)) +import qualified GHC  import GHC.Exts  import Name  import BooleanFormula @@ -75,14 +76,14 @@ ppLFunSig :: Bool -> LinksInfo -> SrcSpan -> DocForDecl DocName ->               [Located DocName] -> LHsType DocNameI -> [(DocName, Fixity)] ->               Splice -> Unicode -> Maybe Package -> Qualification -> Html  ppLFunSig summary links loc doc lnames lty fixities splice unicode pkg qual = -  ppFunSig summary links loc doc (map unLoc lnames) lty fixities +  ppFunSig summary links loc noHtml doc (map unLoc lnames) lty fixities             splice unicode pkg qual -ppFunSig :: Bool -> LinksInfo -> SrcSpan -> DocForDecl DocName -> +ppFunSig :: Bool -> LinksInfo -> SrcSpan -> Html -> DocForDecl DocName ->              [DocName] -> LHsType DocNameI -> [(DocName, Fixity)] ->              Splice -> Unicode -> Maybe Package -> Qualification -> Html -ppFunSig summary links loc doc docnames typ fixities splice unicode pkg qual = -  ppSigLike summary links loc mempty doc docnames fixities (unLoc typ, pp_typ) +ppFunSig summary links loc leader doc docnames typ fixities splice unicode pkg qual = +  ppSigLike summary links loc leader doc docnames fixities (unLoc typ, pp_typ)              splice unicode pkg qual HideEmptyContexts    where      pp_typ = ppLType unicode qual HideEmptyContexts typ @@ -218,7 +219,7 @@ ppFor :: Bool -> LinksInfo -> SrcSpan -> DocForDecl DocName        -> Splice -> Unicode -> Maybe Package -> Qualification -> Html  ppFor summary links loc doc (ForeignImport _ (L _ name) typ _) fixities        splice unicode pkg qual -  = ppFunSig summary links loc doc [name] (hsSigType typ) fixities splice unicode pkg qual +  = ppFunSig summary links loc noHtml doc [name] (hsSigType typ) fixities splice unicode pkg qual  ppFor _ _ _ _ _ _ _ _ _ _ = error "ppFor" @@ -496,7 +497,7 @@ ppShortClassDecl summary links (ClassDecl { tcdCtxt = lctxt, tcdLName = lname, t                  -- ToDo: add associated type defaults -            [ ppFunSig summary links loc doc names (hsSigType typ) +            [ ppFunSig summary links loc noHtml doc names (hsSigType typ)                         [] splice unicode pkg qual                | L _ (ClassOpSig _ False lnames typ) <- sigs                , let doc = lookupAnySubdoc (head names) subdocs @@ -517,8 +518,9 @@ ppClassDecl :: Bool -> LinksInfo -> [DocInstance DocNameI] -> [(DocName, Fixity)              -> [(DocName, DocForDecl DocName)] -> TyClDecl DocNameI              -> Splice -> Unicode -> Maybe Package -> Qualification -> Html  ppClassDecl summary links instances fixities loc d subdocs -        decl@(ClassDecl { tcdCtxt = lctxt, tcdLName = lname, tcdTyVars = ltyvars -                        , tcdFDs = lfds, tcdSigs = lsigs, tcdATs = ats }) +        decl@(ClassDecl { tcdCtxt = lctxt, tcdLName = lname@(L _ nm) +                        , tcdTyVars = ltyvars, tcdFDs = lfds, tcdSigs = lsigs +                        , tcdATs = ats, tcdATDefs = atsDefs })              splice unicode pkg qual    | summary = ppShortClassDecl summary links decl loc subdocs splice unicode pkg qual    | otherwise = classheader +++ docSection curname pkg qual d @@ -535,28 +537,68 @@ ppClassDecl summary links instances fixities loc d subdocs      -- Only the fixity relevant to the class header      fixs = ppFixities [ f | f@(n,_) <- fixities, n == unLoc lname ] qual -    nm   = tcdName decl -      hdr = ppClassHdr summary lctxt (unLoc lname) ltyvars lfds -    -- ToDo: add assocatied typ defaults -    atBit = subAssociatedTypes [ ppAssocType summary links doc at subfixs splice unicode pkg qual -                      | at <- ats -                      , let n = unL . fdLName $ unL at -                            doc = lookupAnySubdoc (unL $ fdLName $ unL at) subdocs -                            subfixs = [ f | f@(n',_) <- fixities, n == n' ] ] - -    methodBit = subMethods [ ppFunSig summary links loc doc [name] (hsSigType typ) -                                      subfixs splice unicode pkg qual -                           | L _ (ClassOpSig _ _ lnames typ) <- lsigs -                           , name <- map unLoc lnames -                           , let doc = lookupAnySubdoc name subdocs -                                 subfixs = [ f | f@(n',_) <- fixities -                                               , name == n' ] -                           ] -                           -- N.B. taking just the first name is ok. Signatures with multiple names -                           -- are expanded so that each name gets its own signature. +    -- Associated types +    atBit = subAssociatedTypes +      [ ppAssocType summary links doc at subfixs splice unicode pkg qual +          <+> +        subDefaults (maybeToList defTys) +      | at <- ats +      , let name = unL . fdLName $ unL at +            doc = lookupAnySubdoc name subdocs +            subfixs = filter ((== name) . fst) fixities +            defTys = ppDefaultAssocTy name <$> lookupDAT name +      ] + +    -- Default associated types +    ppDefaultAssocTy n (vs,t,d') = ppTySyn summary links [] loc d' synDecl +      splice unicode pkg qual +      where +        synDecl = SynDecl { tcdSExt = noExt +                          , tcdLName = noLoc n +                          , tcdTyVars = vs +                          , tcdFixity = GHC.Prefix +                          , tcdRhs = t } + +    lookupDAT name = Map.lookup (getName name) defaultAssocTys +    defaultAssocTys = Map.fromList +      [ (getName name, (vs, typ, doc)) +      | L _ (FamEqn { feqn_rhs = typ +                    , feqn_tycon = L _ name +                    , feqn_pats = vs }) <- atsDefs +      , let doc = noDocForDecl -- TODO: get docs for associated type defaults +      ] + +    -- Methods +    methodBit = subMethods +      [ ppFunSig summary links loc noHtml doc [name] (hsSigType typ) +                 subfixs splice unicode pkg qual +          <+> +        subDefaults (maybeToList defSigs) +      | ClassOpSig _ False lnames typ <- sigs +      , name <- map unLoc lnames +      , let doc = lookupAnySubdoc name subdocs +            subfixs = filter ((== name)  . fst) fixities +            defSigs = ppDefaultFunSig name <$> lookupDM name +      ] +      -- N.B. taking just the first name is ok. Signatures with multiple names +      -- are expanded so that each name gets its own signature. + +    -- Default methods +    ppDefaultFunSig n (t, d') = ppFunSig summary links loc (keyword "default") +      d' [n] (hsSigType t) [] splice unicode pkg qual + +    lookupDM name = Map.lookup (getOccString name) defaultMethods +    defaultMethods = Map.fromList +      [ (nameStr, (typ, doc)) +      | ClassOpSig _ True lnames typ <- sigs +      , name <- map unLoc lnames +      , let doc = noDocForDecl -- TODO: get docs for method defaults +            nameStr = getOccString name +      ] +    -- Minimal complete definition      minimalBit = case [ s | MinimalSig _ _ (L _ s) <- sigs ] of        -- Miminal complete definition = every shown method        And xs : _ | sort [getName n | L _ (Var (L _ n)) <- xs] == @@ -565,7 +607,7 @@ ppClassDecl summary links instances fixities loc d subdocs        -- Minimal complete definition = the only shown method        Var (L _ n) : _ | [getName n] == -                        [getName n' | L _ (ClassOpSig _ _ ns _) <- lsigs, L _ n' <- ns] +                        [getName n' | ClassOpSig _ _ ns _ <- sigs, L _ n' <- ns]          -> noHtml        -- Minimal complete definition = nothing @@ -580,6 +622,7 @@ ppClassDecl summary links instances fixities loc d subdocs        where wrap | p = parens | otherwise = id      ppMinimal p (Parens x) = ppMinimal p (unLoc x) +    -- Instances      instancesBit = ppInstances links (OriginClass nm) instances          splice unicode pkg qual diff --git a/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs b/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs index 25d8b07a..4535b897 100644 --- a/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs +++ b/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs @@ -35,6 +35,7 @@ module Haddock.Backends.Xhtml.Layout (    subInstances, subOrphanInstances,    subInstHead, subInstDetails, subFamInstDetails,    subMethods, +  subDefaults,    subMinimal,    topDeclElem, declElem, @@ -259,6 +260,9 @@ instAnchorId iid = makeAnchorId $ "i:" ++ iid  subMethods :: [Html] -> Html  subMethods = divSubDecls "methods" "Methods" . subBlock +subDefaults :: [Html] -> Html +subDefaults = divSubDecls "default" "" . subBlock +  subMinimal :: Html -> Html  subMinimal = divSubDecls "minimal" "Minimal complete definition" . Just . declElem diff --git a/haddock-api/src/Haddock/Types.hs b/haddock-api/src/Haddock/Types.hs index cd4ac1a1..a72247e6 100644 --- a/haddock-api/src/Haddock/Types.hs +++ b/haddock-api/src/Haddock/Types.hs @@ -355,6 +355,9 @@ showWrapped f (Unadorned n) = f n  showWrapped f (Parenthesized n) = "(" ++ f n ++ ")"  showWrapped f (Backticked n) = "`" ++ f n ++ "`" +instance HasOccName DocName where + +    occName = occName . getName  -----------------------------------------------------------------------------  -- * Instances  | 
