Skip to content
This repository was archived by the owner on Aug 3, 2024. It is now read-only.

Commit caae45a

Browse files
authored
Merge pull request #1204 from wz1000/wip/haddock-hstocore
Use functions exported from GHC.HsToCore.Docs
2 parents b32845d + 45add0d commit caae45a

File tree

5 files changed

+4
-224
lines changed

5 files changed

+4
-224
lines changed

haddock-api/src/Haddock/GhcUtils.hs

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,32 +56,6 @@ moduleString = moduleNameString . moduleName
5656
isNameSym :: Name -> Bool
5757
isNameSym = isSymOcc . nameOccName
5858

59-
getMainDeclBinder :: (CollectPass (GhcPass p)) => HsDecl (GhcPass p) -> [IdP (GhcPass p)]
60-
getMainDeclBinder (TyClD _ d) = [tcdName d]
61-
getMainDeclBinder (ValD _ d) =
62-
case collectHsBindBinders d of
63-
[] -> []
64-
(name:_) -> [name]
65-
getMainDeclBinder (SigD _ d) = sigNameNoLoc d
66-
getMainDeclBinder (ForD _ (ForeignImport _ name _ _)) = [unLoc name]
67-
getMainDeclBinder (ForD _ (ForeignExport _ _ _ _)) = []
68-
getMainDeclBinder _ = []
69-
70-
-- Extract the source location where an instance is defined. This is used
71-
-- to correlate InstDecls with their Instance/CoAxiom Names, via the
72-
-- instanceMap.
73-
getInstLoc :: InstDecl (GhcPass p) -> SrcSpan
74-
getInstLoc (ClsInstD _ (ClsInstDecl { cid_poly_ty = ty })) = getLoc (hsSigType ty)
75-
getInstLoc (DataFamInstD _ (DataFamInstDecl
76-
{ dfid_eqn = HsIB { hsib_body = FamEqn { feqn_tycon = L l _ }}})) = l
77-
getInstLoc (TyFamInstD _ (TyFamInstDecl
78-
-- Since CoAxioms' Names refer to the whole line for type family instances
79-
-- in particular, we need to dig a bit deeper to pull out the entire
80-
-- equation. This does not happen for data family instances, for some reason.
81-
{ tfid_eqn = HsIB { hsib_body = FamEqn { feqn_rhs = L l _ }}})) = l
82-
83-
84-
8559
-- Useful when there is a signature with multiple names, e.g.
8660
-- foo, bar :: Types..
8761
-- but only one of the names is exported and we have to change the
@@ -139,24 +113,9 @@ isClassD :: HsDecl a -> Bool
139113
isClassD (TyClD _ d) = isClassDecl d
140114
isClassD _ = False
141115

142-
isValD :: HsDecl a -> Bool
143-
isValD (ValD _ _) = True
144-
isValD _ = False
145-
146116
pretty :: Outputable a => DynFlags -> a -> String
147117
pretty = showPpr
148118

149-
nubByName :: (a -> Name) -> [a] -> [a]
150-
nubByName f ns = go emptyNameSet ns
151-
where
152-
go !_ [] = []
153-
go !s (x:xs)
154-
| y `elemNameSet` s = go s xs
155-
| otherwise = let !s' = extendNameSet s y
156-
in x : go s' xs
157-
where
158-
y = f x
159-
160119
-- ---------------------------------------------------------------------
161120

162121
-- These functions are duplicated from the GHC API, as they must be

haddock-api/src/Haddock/Interface.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import GHC.Types.Name (nameIsFromExternalPackage, nameOccName)
6161
import GHC.Types.Name.Occurrence (isTcOcc)
6262
import GHC.Types.Name.Reader (unQualOK, gre_name, globalRdrEnvElts)
6363
import GHC.Utils.Error (withTimingD)
64+
import GHC.HsToCore.Docs
6465

6566
#if defined(mingw32_HOST_OS)
6667
import System.IO

haddock-api/src/Haddock/Interface/AttachInstances.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import GHC.Core.TyCon
4444
import GHC.Core.TyCo.Rep
4545
import GHC.Builtin.Types.Prim( funTyConName )
4646
import GHC.Types.Var hiding (varName)
47+
import GHC.HsToCore.Docs
4748

4849
type ExportedNames = Set.Set Name
4950
type Modules = Set.Set Module

haddock-api/src/Haddock/Interface/Create.hs

Lines changed: 1 addition & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import GHC.Tc.Types
5555
import GHC.Data.FastString ( unpackFS, bytesFS )
5656
import GHC.Types.Basic ( StringLiteral(..), SourceText(..), PromotionFlag(..) )
5757
import qualified GHC.Utils.Outputable as O
58+
import GHC.HsToCore.Docs hiding (mkMaps)
5859

5960
import GHC.Core.Multiplicity
6061

@@ -436,109 +437,6 @@ mkMaps dflags pkgName gre instances decls = do
436437
--------------------------------------------------------------------------------
437438

438439

439-
-- | Get all subordinate declarations inside a declaration, and their docs.
440-
-- A subordinate declaration is something like the associate type or data
441-
-- family of a type class.
442-
subordinates :: InstMap
443-
-> HsDecl GhcRn
444-
-> [(Name, [HsDocString], Map Int HsDocString)]
445-
subordinates instMap decl = case decl of
446-
InstD _ (ClsInstD _ d) -> do
447-
DataFamInstDecl { dfid_eqn = HsIB { hsib_body =
448-
FamEqn { feqn_tycon = L l _
449-
, feqn_rhs = defn }}} <- unLoc <$> cid_datafam_insts d
450-
[ (n, [], M.empty) | Just n <- [SrcLoc.lookupSrcSpan l instMap] ] ++ dataSubs defn
451-
452-
InstD _ (DataFamInstD _ (DataFamInstDecl (HsIB { hsib_body = d })))
453-
-> dataSubs (feqn_rhs d)
454-
TyClD _ d | isClassDecl d -> classSubs d
455-
| isDataDecl d -> dataSubs (tcdDataDefn d)
456-
_ -> []
457-
where
458-
classSubs dd = [ (name, doc, declTypeDocs d) | (L _ d, doc) <- classDecls dd
459-
, name <- getMainDeclBinder d, not (isValD d)
460-
]
461-
dataSubs :: HsDataDefn GhcRn -> [(Name, [HsDocString], Map Int HsDocString)]
462-
dataSubs dd = constrs ++ fields ++ derivs
463-
where
464-
cons = map unL $ (dd_cons dd)
465-
constrs = [ (unL cname, maybeToList $ fmap unL $ con_doc c, conArgDocs c)
466-
| c <- cons, cname <- getConNames c ]
467-
fields = [ (extFieldOcc n, maybeToList $ fmap unL doc, M.empty)
468-
| RecCon flds <- map getConArgs cons
469-
, L _ (ConDeclField _ ns _ doc) <- (unLoc flds)
470-
, L _ n <- ns ]
471-
derivs = [ (instName, [unL doc], M.empty)
472-
| (l, doc) <- mapMaybe (extract_deriv_ty . hsib_body) $
473-
concatMap (unLoc . deriv_clause_tys . unLoc) $
474-
unLoc $ dd_derivs dd
475-
, Just instName <- [SrcLoc.lookupSrcSpan l instMap] ]
476-
477-
extract_deriv_ty :: LHsType GhcRn -> Maybe (SrcSpan, LHsDocString)
478-
extract_deriv_ty (L l ty) =
479-
case ty of
480-
-- deriving (forall a. C a {- ^ Doc comment -})
481-
HsForAllTy{ hst_tele = HsForAllInvis{}
482-
, hst_body = L _ (HsDocTy _ _ doc) }
483-
-> Just (l, doc)
484-
-- deriving (C a {- ^ Doc comment -})
485-
HsDocTy _ _ doc -> Just (l, doc)
486-
_ -> Nothing
487-
488-
-- | Extract constructor argument docs from inside constructor decls.
489-
conArgDocs :: ConDecl GhcRn -> Map Int HsDocString
490-
conArgDocs con = case getConArgs con of
491-
PrefixCon args -> go 0 (map (unLoc . hsScaledThing) args ++ ret)
492-
InfixCon arg1 arg2 -> go 0 ([unLoc (hsScaledThing arg1),
493-
unLoc (hsScaledThing arg2)] ++ ret)
494-
RecCon _ -> go 1 ret
495-
where
496-
go n (HsDocTy _ _ (L _ ds) : tys) = M.insert n ds $ go (n+1) tys
497-
go n (HsBangTy _ _ (L _ (HsDocTy _ _ (L _ ds))) : tys) = M.insert n ds $ go (n+1) tys
498-
go n (_ : tys) = go (n+1) tys
499-
go _ [] = M.empty
500-
501-
ret = case con of
502-
ConDeclGADT { con_res_ty = res_ty } -> [ unLoc res_ty ]
503-
_ -> []
504-
505-
-- | Extract function argument docs from inside top-level decls.
506-
declTypeDocs :: HsDecl GhcRn -> Map Int HsDocString
507-
declTypeDocs (SigD _ (TypeSig _ _ ty)) = typeDocs (unLoc (hsSigWcType ty))
508-
declTypeDocs (SigD _ (ClassOpSig _ _ _ ty)) = typeDocs (unLoc (hsSigType ty))
509-
declTypeDocs (SigD _ (PatSynSig _ _ ty)) = typeDocs (unLoc (hsSigType ty))
510-
declTypeDocs (ForD _ (ForeignImport _ _ ty _)) = typeDocs (unLoc (hsSigType ty))
511-
declTypeDocs (TyClD _ (SynDecl { tcdRhs = ty })) = typeDocs (unLoc ty)
512-
declTypeDocs _ = M.empty
513-
514-
-- | Extract function argument docs from inside types.
515-
typeDocs :: HsType GhcRn -> Map Int HsDocString
516-
typeDocs = go 0
517-
where
518-
go n (HsForAllTy { hst_body = ty }) = go n (unLoc ty)
519-
go n (HsQualTy { hst_body = ty }) = go n (unLoc ty)
520-
go n (HsFunTy _ _w (L _ (HsDocTy _ _ (L _ x))) (L _ ty)) = M.insert n x $ go (n+1) ty
521-
go n (HsFunTy _ _ _ ty) = go (n+1) (unLoc ty)
522-
go n (HsDocTy _ _ (L _ doc)) = M.singleton n doc
523-
go _ _ = M.empty
524-
525-
-- | All the sub declarations of a class (that we handle), ordered by
526-
-- source location, with documentation attached if it exists.
527-
classDecls :: TyClDecl GhcRn -> [(LHsDecl GhcRn, [HsDocString])]
528-
classDecls class_ = filterDecls . collectDocs . SrcLoc.sortLocated $ decls
529-
where
530-
decls = docs ++ defs ++ sigs ++ ats
531-
docs = mkDecls tcdDocs (DocD noExtField) class_
532-
defs = mkDecls (bagToList . tcdMeths) (ValD noExtField) class_
533-
sigs = mkDecls tcdSigs (SigD noExtField) class_
534-
ats = mkDecls tcdATs (TyClD noExtField . FamDecl noExtField) class_
535-
536-
537-
-- | The top-level declarations of a module that we care about,
538-
-- ordered by source location, with documentation attached if it exists.
539-
topDecls :: HsGroup GhcRn -> [(LHsDecl GhcRn, [HsDocString])]
540-
topDecls =
541-
filterClasses . filterDecls . collectDocs . SrcLoc.sortLocated . ungroup
542440

543441
-- | Extract a map of fixity declarations only
544442
mkFixMap :: HsGroup GhcRn -> FixMap
@@ -548,86 +446,6 @@ mkFixMap group_ =
548446
L _ n <- ns ]
549447

550448

551-
-- | Take all declarations except pragmas, infix decls, rules from an 'HsGroup'.
552-
ungroup :: HsGroup GhcRn -> [LHsDecl GhcRn]
553-
ungroup group_ =
554-
mkDecls (tyClGroupTyClDecls . hs_tyclds) (TyClD noExtField) group_ ++
555-
mkDecls hs_derivds (DerivD noExtField) group_ ++
556-
mkDecls hs_defds (DefD noExtField) group_ ++
557-
mkDecls hs_fords (ForD noExtField) group_ ++
558-
mkDecls hs_docs (DocD noExtField) group_ ++
559-
mkDecls (tyClGroupInstDecls . hs_tyclds) (InstD noExtField) group_ ++
560-
mkDecls (typesigs . hs_valds) (SigD noExtField) group_ ++
561-
mkDecls (valbinds . hs_valds) (ValD noExtField) group_
562-
where
563-
typesigs (XValBindsLR (NValBinds _ sigs)) = filter isUserLSig sigs
564-
typesigs _ = error "expected ValBindsOut"
565-
566-
valbinds (XValBindsLR (NValBinds binds _)) = concatMap bagToList . snd . unzip $ binds
567-
valbinds _ = error "expected ValBindsOut"
568-
569-
570-
-- | Take a field of declarations from a data structure and create HsDecls
571-
-- using the given constructor
572-
mkDecls :: (a -> [Located b]) -> (b -> c) -> a -> [Located c]
573-
mkDecls field con struct = [ L loc (con decl) | L loc decl <- field struct ]
574-
575-
--------------------------------------------------------------------------------
576-
-- Filtering of declarations
577-
--
578-
-- We filter out declarations that we don't intend to handle later.
579-
--------------------------------------------------------------------------------
580-
581-
582-
-- | Filter out declarations that we don't handle in Haddock
583-
filterDecls :: [(LHsDecl a, doc)] -> [(LHsDecl a, doc)]
584-
filterDecls = filter (isHandled . unL . fst)
585-
where
586-
isHandled (ForD _ (ForeignImport {})) = True
587-
isHandled (TyClD {}) = True
588-
isHandled (InstD {}) = True
589-
isHandled (DerivD {}) = True
590-
isHandled (SigD _ d) = isUserLSig (reL d)
591-
isHandled (ValD {}) = True
592-
-- we keep doc declarations to be able to get at named docs
593-
isHandled (DocD {}) = True
594-
isHandled _ = False
595-
596-
-- | Go through all class declarations and filter their sub-declarations
597-
filterClasses :: [(LHsDecl a, doc)] -> [(LHsDecl a, doc)]
598-
filterClasses decls = [ if isClassD d then (L loc (filterClass d), doc) else x
599-
| x@(L loc d, doc) <- decls ]
600-
where
601-
filterClass (TyClD x c) =
602-
TyClD x $ c { tcdSigs = filter (liftA2 (||) isUserLSig isMinimalLSig) $ tcdSigs c }
603-
filterClass _ = error "expected TyClD"
604-
605-
606-
--------------------------------------------------------------------------------
607-
-- Collect docs
608-
--
609-
-- To be able to attach the right Haddock comment to the right declaration,
610-
-- we sort the declarations by their SrcLoc and "collect" the docs for each
611-
-- declaration.
612-
--------------------------------------------------------------------------------
613-
614-
615-
-- | Collect docs and attach them to the right declarations.
616-
collectDocs :: [LHsDecl a] -> [(LHsDecl a, [HsDocString])]
617-
collectDocs = go Nothing []
618-
where
619-
go Nothing _ [] = []
620-
go (Just prev) docs [] = finished prev docs []
621-
go prev docs (L _ (DocD _ (DocCommentNext str)) : ds)
622-
| Nothing <- prev = go Nothing (str:docs) ds
623-
| Just decl <- prev = finished decl docs (go Nothing [str] ds)
624-
go prev docs (L _ (DocD _ (DocCommentPrev str)) : ds) = go prev (str:docs) ds
625-
go Nothing docs (d:ds) = go (Just d) docs ds
626-
go (Just prev) docs (d:ds) = finished prev docs (go (Just d) [] ds)
627-
628-
finished decl docs rest = (decl, reverse docs) : rest
629-
630-
631449
-- | Build the list of items that will become the documentation, from the
632450
-- export list. At this point, the list of ExportItems is in terms of
633451
-- original names.

haddock-api/src/Haddock/Interface/Rename.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import Control.Monad hiding (mapM)
3131
import Data.List
3232
import qualified Data.Map as Map hiding ( Map )
3333
import Prelude hiding (mapM)
34+
import GHC.HsToCore.Docs
3435

3536
renameInterface :: DynFlags -> LinkEnv -> Bool -> Interface -> ErrMsgM Interface
3637
renameInterface dflags renamingEnv warnings iface =

0 commit comments

Comments
 (0)