Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
fd5b5177
by Ryan Hendrickson at 2025-06-18T22:30:06-04:00
17 changed files:
- utils/haddock/CHANGES.md
- utils/haddock/doc/cheatsheet/haddocks.md
- utils/haddock/doc/markup.rst
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
- utils/haddock/haddock-api/src/Haddock/Interface.hs
- utils/haddock/haddock-api/src/Haddock/Interface/AttachInstances.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Create.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/InterfaceFile.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- + utils/haddock/html-test/ref/RedactTypeSynonyms.html
- + utils/haddock/html-test/src/RedactTypeSynonyms.hs
- + utils/haddock/latex-test/ref/RedactTypeSynonyms/RedactTypeSynonyms.tex
- + utils/haddock/latex-test/src/RedactTypeSynonyms/RedactTypeSynonyms.hs
Changes:
| ... | ... | @@ -11,6 +11,10 @@ |
| 11 | 11 | |
| 12 | 12 | * Include `package_info` with haddock's `--show-interface` option.
|
| 13 | 13 | |
| 14 | + * `{-# OPTIONS_HADDOCK redact-type-synonyms #-}` pragma will hide the RHS of
|
|
| 15 | + type synonyms, and display the result kind instead, if the RHS contains any
|
|
| 16 | + unexported types.
|
|
| 17 | + |
|
| 14 | 18 | ## Changes in 2.28.0
|
| 15 | 19 | * `hi-haddock` is integrated, which means docstrings are no longer extracted
|
| 16 | 20 | through typchecked module results. Instead, docstrings are taken from Haskell
|
| ... | ... | @@ -116,6 +116,8 @@ definitions with "[thing]" |
| 116 | 116 | Show all enabled LANGUAGE extensions
|
| 117 | 117 | {-# OPTIONS_HADDOCK print-explicit-runtime-reps #-}
|
| 118 | 118 | Show all `RuntimeRep` type variables
|
| 119 | +{-# OPTIONS_HADDOCK redact-type-synonyms #-}
|
|
| 120 | + Hide the RHS of type synonyms that use unexported types
|
|
| 119 | 121 | ```
|
| 120 | 122 | |
| 121 | 123 | # Grid tables
|
| ... | ... | @@ -201,6 +201,21 @@ Individual arguments to a function may be documented like this: :: |
| 201 | 201 | Pattern synonyms, GADT-style data constructors, and class methods also
|
| 202 | 202 | support this style of documentation.
|
| 203 | 203 | |
| 204 | +.. _instance-documentation:
|
|
| 205 | + |
|
| 206 | +Instance Documentation
|
|
| 207 | +~~~~~~~~~~~~~~~~~~~~~~
|
|
| 208 | + |
|
| 209 | +As instances are not exported, their documentation appears as part of the
|
|
| 210 | +documentation for the corresponding class and the data types that appear in the
|
|
| 211 | +instance head. This may result in the documentation appearing in multiple
|
|
| 212 | +modules.
|
|
| 213 | + |
|
| 214 | +If the class is *hidden* (meaning defined in this package but not exported by
|
|
| 215 | +any exposed module), or if any of the data types that appear in the instance
|
|
| 216 | +head are hidden (ditto), then no documentation for the instance is produced,
|
|
| 217 | +even if the instance has an associated documentation comment.
|
|
| 218 | + |
|
| 204 | 219 | .. _module-description:
|
| 205 | 220 | |
| 206 | 221 | The Module Description
|
| ... | ... | @@ -785,6 +800,12 @@ The following attributes are currently understood by Haddock: |
| 785 | 800 | underlying levity polymorphism. This flag is analogous to GHC's
|
| 786 | 801 | ``-fprint-explicit-runtime-reps`` flag.
|
| 787 | 802 | |
| 803 | +``redact-type-synonyms``
|
|
| 804 | + Hide the RHS of type synonyms, and display the result kind instead, if the
|
|
| 805 | + RHS contains any hidden types. ("Hidden" here means the same as in the
|
|
| 806 | + feature that hides class instances if those instances contain any hidden
|
|
| 807 | + types; see :ref:`instance-documentation`.)
|
|
| 808 | + |
|
| 788 | 809 | .. _markup:
|
| 789 | 810 | |
| 790 | 811 | Markup
|
| ... | ... | @@ -478,7 +478,11 @@ ppTySyn |
| 478 | 478 | : ppDocBinder name
|
| 479 | 479 | : map ppWcSymName (tyvarNames ltyvars)
|
| 480 | 480 | )
|
| 481 | - full = hdr <+> char '=' <+> ppLType unicode ltype
|
|
| 481 | + full = hdr <+> def
|
|
| 482 | + def = case unLoc ltype of
|
|
| 483 | + XHsType (HsRedacted k) ->
|
|
| 484 | + dcolon unicode <+> ppType unicode k
|
|
| 485 | + _ -> equals <+> ppLType unicode ltype
|
|
| 482 | 486 | ppTySyn _ _ _ = error "declaration not supported by ppTySyn"
|
| 483 | 487 | |
| 484 | 488 | -------------------------------------------------------------------------------
|
| ... | ... | @@ -1360,6 +1364,7 @@ ppr_mono_ty (HsDocTy _ ty _) unicode = |
| 1360 | 1364 | ppr_mono_ty (HsWildCardTy _) _ = char '_'
|
| 1361 | 1365 | ppr_mono_ty (HsTyLit _ t) u = ppr_tylit t u
|
| 1362 | 1366 | ppr_mono_ty (HsStarTy _ isUni) unicode = starSymbol (isUni || unicode)
|
| 1367 | +ppr_mono_ty (XHsType HsRedacted{}) _ = error "ppr_mono_ty: HsRedacted can't be used here"
|
|
| 1363 | 1368 | |
| 1364 | 1369 | ppr_tylit :: HsTyLit DocNameI -> Bool -> LaTeX
|
| 1365 | 1370 | ppr_tylit (HsNumTy _ n) _ = integer n
|
| ... | ... | @@ -469,7 +469,11 @@ ppTySyn |
| 469 | 469 | ( [keyword "type", ppBinder summary occ]
|
| 470 | 470 | ++ ppTyVars unicode qual (hsQTvExplicit ltyvars)
|
| 471 | 471 | )
|
| 472 | - full = hdr <+> equals <+> ppPatSigType unicode qual (noLocA sig_type)
|
|
| 472 | + full = hdr <+> def
|
|
| 473 | + def = case unLoc ltype of
|
|
| 474 | + XHsType (HsRedacted k) ->
|
|
| 475 | + dcolon unicode <+> ppType unicode qual HideEmptyContexts k
|
|
| 476 | + _ -> equals <+> ppPatSigType unicode qual (noLocA sig_type)
|
|
| 473 | 477 | occ = nameOccName . getName $ name
|
| 474 | 478 | fixs
|
| 475 | 479 | | summary = noHtml
|
| ... | ... | @@ -1874,6 +1878,7 @@ ppr_mono_ty (HsDocTy _ ty _) unicode qual emptyCtxts = |
| 1874 | 1878 | ppr_mono_lty ty unicode qual emptyCtxts
|
| 1875 | 1879 | ppr_mono_ty (HsWildCardTy _) _ _ _ = char '_'
|
| 1876 | 1880 | ppr_mono_ty (HsTyLit _ n) _ _ _ = ppr_tylit n
|
| 1881 | +ppr_mono_ty (XHsType HsRedacted{}) _ _ _ = error "ppr_mono_ty: HsRedacted can't be used here"
|
|
| 1877 | 1882 | |
| 1878 | 1883 | ppr_tylit :: HsTyLit DocNameI -> Html
|
| 1879 | 1884 | ppr_tylit (HsNumTy _ n) = toHtml (show n)
|
| ... | ... | @@ -23,6 +23,7 @@ module Haddock.Convert |
| 23 | 23 | ( tyThingToLHsDecl
|
| 24 | 24 | , synifyInstHead
|
| 25 | 25 | , synifyFamInst
|
| 26 | + , synifyKindSig
|
|
| 26 | 27 | , PrintRuntimeReps (..)
|
| 27 | 28 | ) where
|
| 28 | 29 |
| ... | ... | @@ -66,7 +66,7 @@ import GHC.Utils.Outputable (Outputable, SDocContext, ppr) |
| 66 | 66 | import qualified GHC.Utils.Outputable as Outputable
|
| 67 | 67 | import GHC.Utils.Panic (panic)
|
| 68 | 68 | |
| 69 | -import Haddock.Types (DocName, DocNameI, XRecCond, HsTypeDocNameIExt(..))
|
|
| 69 | +import Haddock.Types (DocName, DocNameI, ExportInfo, XRecCond, HsTypeDocNameIExt(..))
|
|
| 70 | 70 | |
| 71 | 71 | moduleString :: Module -> String
|
| 72 | 72 | moduleString = moduleNameString . moduleName
|
| ... | ... | @@ -771,6 +771,26 @@ typeNames ty = go ty Set.empty |
| 771 | 771 | CastTy t' _ -> go t' acc
|
| 772 | 772 | CoercionTy{} -> acc
|
| 773 | 773 | |
| 774 | + |
|
| 775 | +-- | A class or data type is hidden iff
|
|
| 776 | +--
|
|
| 777 | +-- * it is defined in one of the modules that are being processed
|
|
| 778 | +--
|
|
| 779 | +-- * and it is not exported by any non-hidden module
|
|
| 780 | +isNameHidden :: ExportInfo -> Name -> Bool
|
|
| 781 | +isNameHidden (names, modules) name =
|
|
| 782 | + nameModule name `Set.member` modules
|
|
| 783 | + && not (name `Set.member` names)
|
|
| 784 | + |
|
| 785 | +isTypeHidden :: ExportInfo -> Type -> Bool
|
|
| 786 | +isTypeHidden expInfo = typeHidden
|
|
| 787 | + where
|
|
| 788 | + typeHidden :: Type -> Bool
|
|
| 789 | + typeHidden t = any nameHidden $ typeNames t
|
|
| 790 | + |
|
| 791 | + nameHidden :: Name -> Bool
|
|
| 792 | + nameHidden = isNameHidden expInfo
|
|
| 793 | + |
|
| 774 | 794 | -------------------------------------------------------------------------------
|
| 775 | 795 | |
| 776 | 796 | -- * Free variables of a 'Type'
|
| ... | ... | @@ -102,7 +102,6 @@ processModules |
| 102 | 102 | -- environment
|
| 103 | 103 | processModules verbosity modules flags extIfaces = do
|
| 104 | 104 | liftIO Compat.setEncoding
|
| 105 | - dflags <- getDynFlags
|
|
| 106 | 105 | |
| 107 | 106 | -- Map from a module to a corresponding installed interface
|
| 108 | 107 | let instIfaceMap :: InstIfaceMap
|
| ... | ... | @@ -122,10 +121,11 @@ processModules verbosity modules flags extIfaces = do |
| 122 | 121 | Set.unions $ map (Set.fromList . ifaceExports) $
|
| 123 | 122 | filter (\i -> not $ OptHide `elem` ifaceOptions i) interfaces
|
| 124 | 123 | mods = Set.fromList $ map ifaceMod interfaces
|
| 124 | + expInfo = (exportedNames, mods)
|
|
| 125 | 125 | |
| 126 | 126 | interfaces' <- {-# SCC attachInstances #-}
|
| 127 | 127 | withTimingM "attachInstances" (const ()) $ do
|
| 128 | - attachInstances (exportedNames, mods) interfaces instIfaceMap (isJust oneShotHiFile)
|
|
| 128 | + attachInstances expInfo interfaces instIfaceMap (isJust oneShotHiFile)
|
|
| 129 | 129 | |
| 130 | 130 | -- Combine the link envs of the external packages into one
|
| 131 | 131 | let extLinks = Map.unions (map ifLinkEnv extIfaces)
|
| ... | ... | @@ -140,7 +140,7 @@ processModules verbosity modules flags extIfaces = do |
| 140 | 140 | withTimingM "renameAllInterfaces" (const ()) $
|
| 141 | 141 | for interfaces' $ \i -> do
|
| 142 | 142 | withTimingM ("renameInterface: " <+> pprModuleName (moduleName (ifaceMod i))) (const ()) $
|
| 143 | - renameInterface dflags ignoredSymbolSet links warnings (Flag_Hoogle `elem` flags) i
|
|
| 143 | + renameInterface ignoredSymbolSet links expInfo warnings (Flag_Hoogle `elem` flags) i
|
|
| 144 | 144 | |
| 145 | 145 | return (interfaces'', homeLinks)
|
| 146 | 146 |
| ... | ... | @@ -31,7 +31,6 @@ import qualified Data.Map.Strict as Map |
| 31 | 31 | import Data.Maybe (fromMaybe, mapMaybe, maybeToList)
|
| 32 | 32 | import Data.Ord (comparing)
|
| 33 | 33 | import qualified Data.Sequence as Seq
|
| 34 | -import qualified Data.Set as Set
|
|
| 35 | 34 | import GHC
|
| 36 | 35 | import GHC.Builtin.Types (unrestrictedFunTyConName)
|
| 37 | 36 | import GHC.Core (isOrphan)
|
| ... | ... | @@ -62,13 +61,9 @@ import GHC.Unit.State |
| 62 | 61 | import GHC.Utils.Outputable (sep, text, (<+>))
|
| 63 | 62 | |
| 64 | 63 | import Haddock.Convert
|
| 65 | -import Haddock.GhcUtils (typeNames)
|
|
| 64 | +import Haddock.GhcUtils (isNameHidden, isTypeHidden)
|
|
| 66 | 65 | import Haddock.Types
|
| 67 | 66 | |
| 68 | -type ExportedNames = Set.Set Name
|
|
| 69 | -type Modules = Set.Set Module
|
|
| 70 | -type ExportInfo = (ExportedNames, Modules)
|
|
| 71 | - |
|
| 72 | 67 | -- Also attaches fixities
|
| 73 | 68 | attachInstances :: ExportInfo -> [Interface] -> InstIfaceMap -> Bool -> Ghc [Interface]
|
| 74 | 69 | attachInstances expInfo ifaces instIfaceMap isOneShot = do
|
| ... | ... | @@ -389,16 +384,6 @@ instFam FamInst{fi_fam = n, fi_tys = ts, fi_rhs = t} = |
| 389 | 384 | -- Filtering hidden instances
|
| 390 | 385 | --------------------------------------------------------------------------------
|
| 391 | 386 | |
| 392 | --- | A class or data type is hidden iff
|
|
| 393 | ---
|
|
| 394 | --- * it is defined in one of the modules that are being processed
|
|
| 395 | ---
|
|
| 396 | --- * and it is not exported by any non-hidden module
|
|
| 397 | -isNameHidden :: ExportInfo -> Name -> Bool
|
|
| 398 | -isNameHidden (names, modules) name =
|
|
| 399 | - nameModule name `Set.member` modules
|
|
| 400 | - && not (name `Set.member` names)
|
|
| 401 | - |
|
| 402 | 387 | -- | We say that an instance is «hidden» iff its class or any (part)
|
| 403 | 388 | -- of its type(s) is hidden.
|
| 404 | 389 | isInstanceHidden :: ExportInfo -> Name -> [Type] -> Bool
|
| ... | ... | @@ -410,12 +395,3 @@ isInstanceHidden expInfo cls tyNames = |
| 410 | 395 | |
| 411 | 396 | instTypeHidden :: Bool
|
| 412 | 397 | instTypeHidden = any (isTypeHidden expInfo) tyNames |
| 413 | - |
|
| 414 | -isTypeHidden :: ExportInfo -> Type -> Bool
|
|
| 415 | -isTypeHidden expInfo = typeHidden
|
|
| 416 | - where
|
|
| 417 | - typeHidden :: Type -> Bool
|
|
| 418 | - typeHidden t = any nameHidden $ typeNames t
|
|
| 419 | - |
|
| 420 | - nameHidden :: Name -> Bool
|
|
| 421 | - nameHidden = isNameHidden expInfo |
| ... | ... | @@ -395,6 +395,7 @@ parseOption "prune" = return (Just OptPrune) |
| 395 | 395 | parseOption "not-home" = return (Just OptNotHome)
|
| 396 | 396 | parseOption "show-extensions" = return (Just OptShowExtensions)
|
| 397 | 397 | parseOption "print-explicit-runtime-reps" = return (Just OptPrintRuntimeRep)
|
| 398 | +parseOption "redact-type-synonyms" = return (Just OptRedactTypeSyns)
|
|
| 398 | 399 | parseOption other = warn ("Unrecognised option: " ++ other) >> return Nothing
|
| 399 | 400 | |
| 400 | 401 | --------------------------------------------------------------------------------
|
| ... | ... | @@ -25,7 +25,9 @@ import Control.Applicative () |
| 25 | 25 | import Control.DeepSeq (force)
|
| 26 | 26 | import Control.Monad hiding (mapM)
|
| 27 | 27 | import Control.Monad.Reader
|
| 28 | -import Control.Monad.Writer.CPS
|
|
| 28 | +import Control.Monad.Trans.Maybe (MaybeT (..), hoistMaybe)
|
|
| 29 | +import Control.Monad.Trans.Writer.CPS (WriterT, runWriterT)
|
|
| 30 | +import Control.Monad.Writer.Class
|
|
| 29 | 31 | import Data.Foldable (traverse_)
|
| 30 | 32 | import qualified Data.Map.Strict as Map
|
| 31 | 33 | import qualified Data.Set as Set
|
| ... | ... | @@ -33,12 +35,15 @@ import Data.Traversable (mapM) |
| 33 | 35 | |
| 34 | 36 | import GHC hiding (NoLink, HsTypeGhcPsExt (..))
|
| 35 | 37 | import GHC.Builtin.Types (eqTyCon_RDR, tupleDataConName, tupleTyConName)
|
| 38 | +import GHC.Core.TyCon (tyConResKind)
|
|
| 39 | +import GHC.Driver.DynFlags (getDynFlags)
|
|
| 36 | 40 | import GHC.Types.Basic (Boxity (..), TopLevelFlag (..), TupleSort (..))
|
| 37 | 41 | import GHC.Types.Name
|
| 38 | 42 | import GHC.Types.Name.Reader (RdrName (Exact))
|
| 39 | 43 | import Language.Haskell.Syntax.BooleanFormula(BooleanFormula(..))
|
| 40 | 44 | |
| 41 | 45 | import Haddock.Backends.Hoogle (ppExportD)
|
| 46 | +import Haddock.Convert (synifyKindSig)
|
|
| 42 | 47 | import Haddock.GhcUtils
|
| 43 | 48 | import Haddock.Types
|
| 44 | 49 | |
| ... | ... | @@ -51,9 +56,7 @@ import Haddock.Types |
| 51 | 56 | -- The renamed output gets written into fields in the Haddock interface record
|
| 52 | 57 | -- that were previously left empty.
|
| 53 | 58 | renameInterface
|
| 54 | - :: DynFlags
|
|
| 55 | - -- ^ GHC session dyn flags
|
|
| 56 | - -> Map.Map (Maybe String) (Set.Set String)
|
|
| 59 | + :: Map.Map (Maybe String) (Set.Set String)
|
|
| 57 | 60 | -- ^ Ignored symbols. A map from module names to unqualified names. Module
|
| 58 | 61 | -- 'Just M' mapping to name 'f' means that link warnings should not be
|
| 59 | 62 | -- generated for occurances of specifically 'M.f'. Module 'Nothing' mapping to
|
| ... | ... | @@ -61,6 +64,7 @@ renameInterface |
| 61 | 64 | -> LinkEnv
|
| 62 | 65 | -- ^ Link environment. A map from 'Name' to 'Module', where name 'n' maps to
|
| 63 | 66 | -- module 'M' if 'M' is the preferred link destination for name 'n'.
|
| 67 | + -> ExportInfo
|
|
| 64 | 68 | -> Bool
|
| 65 | 69 | -- ^ Are warnings enabled?
|
| 66 | 70 | -> Bool
|
| ... | ... | @@ -68,18 +72,17 @@ renameInterface |
| 68 | 72 | -> Interface
|
| 69 | 73 | -- ^ The interface we are renaming.
|
| 70 | 74 | -> Ghc Interface
|
| 71 | - -- ^ The renamed interface. Note that there is nothing really special about
|
|
| 72 | - -- this being in the 'Ghc' monad. This could very easily be any 'MonadIO' or
|
|
| 73 | - -- even pure, depending on the link warnings are reported.
|
|
| 74 | -renameInterface dflags ignoreSet renamingEnv warnings hoogle iface = do
|
|
| 75 | - let (iface', warnedNames) =
|
|
| 76 | - runRnM
|
|
| 77 | - dflags
|
|
| 78 | - mdl
|
|
| 79 | - localLinkEnv
|
|
| 80 | - warnName
|
|
| 81 | - (hoogle && not (OptHide `elem` ifaceOptions iface))
|
|
| 82 | - (renameInterfaceRn iface)
|
|
| 75 | + -- ^ The renamed interface. The 'Ghc' monad is used to look up type
|
|
| 76 | + -- information and to get dynamic flags.
|
|
| 77 | +renameInterface ignoreSet renamingEnv expInfo warnings hoogle iface = do
|
|
| 78 | + (iface', warnedNames) <-
|
|
| 79 | + runRnM
|
|
| 80 | + mdl
|
|
| 81 | + localLinkEnv
|
|
| 82 | + (expInfo <$ guard (OptRedactTypeSyns `elem` ifaceOptions iface))
|
|
| 83 | + warnName
|
|
| 84 | + (hoogle && not (OptHide `elem` ifaceOptions iface))
|
|
| 85 | + (renameInterfaceRn iface)
|
|
| 83 | 86 | reportMissingLinks mdl warnedNames
|
| 84 | 87 | return iface'
|
| 85 | 88 | where
|
| ... | ... | @@ -144,14 +147,20 @@ reportMissingLinks mdl names |
| 144 | 147 | -- | A renaming monad which provides 'MonadReader' access to a renaming
|
| 145 | 148 | -- environment, and 'MonadWriter' access to a 'Set' of names for which link
|
| 146 | 149 | -- warnings should be generated, based on the renaming environment.
|
| 147 | -newtype RnM a = RnM {unRnM :: ReaderT RnMEnv (Writer (Set.Set Name)) a}
|
|
| 150 | +newtype RnM a = RnM {unRnM :: ReaderT RnMEnv (WriterT (Set.Set Name) Ghc) a}
|
|
| 148 | 151 | deriving newtype (Functor, Applicative, Monad, MonadReader RnMEnv, MonadWriter (Set.Set Name))
|
| 149 | 152 | |
| 153 | +liftGhc :: Ghc a -> RnM a
|
|
| 154 | +liftGhc = RnM . lift . lift
|
|
| 155 | + |
|
| 150 | 156 | -- | The renaming monad environment. Stores the linking environment (mapping
|
| 151 | 157 | -- names to modules), the link warning predicate, and the current module.
|
| 152 | 158 | data RnMEnv = RnMEnv
|
| 153 | 159 | { rnLinkEnv :: LinkEnv
|
| 154 | 160 | -- ^ The linking environment (map from names to modules)
|
| 161 | + , rnExportInfo :: Maybe ExportInfo
|
|
| 162 | + -- ^ Information about exported names and modules, only if
|
|
| 163 | + -- redact-type-synonyms is enabled
|
|
| 155 | 164 | , rnWarnName :: (Name -> Bool)
|
| 156 | 165 | -- ^ Link warning predicate (whether failing to find a link destination
|
| 157 | 166 | -- for a given name should result in a warning)
|
| ... | ... | @@ -159,26 +168,24 @@ data RnMEnv = RnMEnv |
| 159 | 168 | -- ^ The current module
|
| 160 | 169 | , rnHoogleOutput :: Bool
|
| 161 | 170 | -- ^ Should Hoogle output be generated for this module?
|
| 162 | - , rnDynFlags :: DynFlags
|
|
| 163 | - -- ^ GHC Session DynFlags, necessary for Hoogle output generation
|
|
| 164 | 171 | }
|
| 165 | 172 | |
| 166 | 173 | -- | Run the renamer action in a renaming environment built using the given
|
| 167 | 174 | -- module, link env, and link warning predicate. Returns the renamed value along
|
| 168 | 175 | -- with a set of 'Name's that were not renamed and should be warned for (i.e.
|
| 169 | 176 | -- they satisfied the link warning predicate).
|
| 170 | -runRnM :: DynFlags -> Module -> LinkEnv -> (Name -> Bool) -> Bool -> RnM a -> (a, Set.Set Name)
|
|
| 171 | -runRnM dflags mdl linkEnv warnName hoogleOutput rn =
|
|
| 172 | - runWriter $ runReaderT (unRnM rn) rnEnv
|
|
| 177 | +runRnM :: Module -> LinkEnv -> Maybe ExportInfo -> (Name -> Bool) -> Bool -> RnM a -> Ghc (a, Set.Set Name)
|
|
| 178 | +runRnM mdl linkEnv mbExpInfo warnName hoogleOutput rn =
|
|
| 179 | + runWriterT $ runReaderT (unRnM rn) rnEnv
|
|
| 173 | 180 | where
|
| 174 | 181 | rnEnv :: RnMEnv
|
| 175 | 182 | rnEnv =
|
| 176 | 183 | RnMEnv
|
| 177 | 184 | { rnLinkEnv = linkEnv
|
| 185 | + , rnExportInfo = mbExpInfo
|
|
| 178 | 186 | , rnWarnName = warnName
|
| 179 | 187 | , rnModuleString = moduleString mdl
|
| 180 | 188 | , rnHoogleOutput = hoogleOutput
|
| 181 | - , rnDynFlags = dflags
|
|
| 182 | 189 | }
|
| 183 | 190 | |
| 184 | 191 | --------------------------------------------------------------------------------
|
| ... | ... | @@ -243,12 +250,13 @@ renameExportItem item = case item of |
| 243 | 250 | ExportDecl ed@(ExportD decl pats doc subs instances fixities splice) -> do
|
| 244 | 251 | -- If Hoogle output should be generated, generate it
|
| 245 | 252 | RnMEnv{..} <- ask
|
| 253 | + dflags0 <- liftGhc getDynFlags
|
|
| 246 | 254 | let !hoogleOut =
|
| 247 | 255 | force $
|
| 248 | 256 | if rnHoogleOutput
|
| 249 | 257 | then
|
| 250 | 258 | -- Since Hoogle is line based, we want to avoid breaking long lines.
|
| 251 | - let dflags = rnDynFlags{pprCols = maxBound}
|
|
| 259 | + let dflags = dflags0{pprCols = maxBound}
|
|
| 252 | 260 | in ppExportD dflags ed
|
| 253 | 261 | else []
|
| 254 | 262 | |
| ... | ... | @@ -536,7 +544,16 @@ renameTyClD d = case d of |
| 536 | 544 | SynDecl{tcdLName = lname, tcdTyVars = tyvars, tcdFixity = fixity, tcdRhs = rhs} -> do
|
| 537 | 545 | lname' <- renameNameL lname
|
| 538 | 546 | tyvars' <- renameLHsQTyVars tyvars
|
| 539 | - rhs' <- renameLType rhs
|
|
| 547 | + rhs' <- maybe (renameLType rhs) pure <=< runMaybeT $ do
|
|
| 548 | + expInfo <- MaybeT $ asks rnExportInfo
|
|
| 549 | + -- Given that we have matched on a 'SynDecl', this lookup /really should/
|
|
| 550 | + -- be 'ATyCon', and the 'synTyConRhs_maybe' result /really should/ be
|
|
| 551 | + -- 'Just', but out of an abundance of caution, failing either expectation
|
|
| 552 | + -- gracefully exits the monad instead of erroring.
|
|
| 553 | + ATyCon tc <- MaybeT $ liftGhc $ GHC.lookupName $ getName lname
|
|
| 554 | + guard . isTypeHidden expInfo <=< hoistMaybe $ synTyConRhs_maybe tc
|
|
| 555 | + let hsKind = synifyKindSig $ tyConResKind tc
|
|
| 556 | + lift $ fmap (XHsType . HsRedacted) <$> renameLType hsKind
|
|
| 540 | 557 | return
|
| 541 | 558 | ( SynDecl
|
| 542 | 559 | { tcdSExt = noExtField
|
| ... | ... | @@ -423,6 +423,8 @@ instance Binary DocOption where |
| 423 | 423 | putByte bh 4
|
| 424 | 424 | put_ bh OptPrintRuntimeRep = do
|
| 425 | 425 | putByte bh 5
|
| 426 | + put_ bh OptRedactTypeSyns = do
|
|
| 427 | + putByte bh 6
|
|
| 426 | 428 | get bh = do
|
| 427 | 429 | h <- getByte bh
|
| 428 | 430 | case h of
|
| ... | ... | @@ -438,6 +440,8 @@ instance Binary DocOption where |
| 438 | 440 | return OptShowExtensions
|
| 439 | 441 | 5 -> do
|
| 440 | 442 | return OptPrintRuntimeRep
|
| 443 | + 6 -> do
|
|
| 444 | + return OptRedactTypeSyns
|
|
| 441 | 445 | n -> fail $ "invalid binary data found: " <> show n
|
| 442 | 446 | |
| 443 | 447 | instance Binary Example where
|
| ... | ... | @@ -87,6 +87,9 @@ data DocPaths = DocPaths |
| 87 | 87 | -- ^ path to hyperlinked sources
|
| 88 | 88 | }
|
| 89 | 89 | type WarningMap = Map Name (Doc Name)
|
| 90 | +type ExportedNames = Set.Set Name
|
|
| 91 | +type Modules = Set.Set Module
|
|
| 92 | +type ExportInfo = (ExportedNames, Modules)
|
|
| 90 | 93 | |
| 91 | 94 | -----------------------------------------------------------------------------
|
| 92 | 95 | |
| ... | ... | @@ -697,6 +700,9 @@ data DocOption |
| 697 | 700 | | -- | Render runtime reps for this module (see
|
| 698 | 701 | -- the GHC @-fprint-explicit-runtime-reps@ flag)
|
| 699 | 702 | OptPrintRuntimeRep
|
| 703 | + | -- | Hide the RHS of type synonyms in this module
|
|
| 704 | + -- that use unexported types.
|
|
| 705 | + OptRedactTypeSyns
|
|
| 700 | 706 | deriving (Eq, Show)
|
| 701 | 707 | |
| 702 | 708 | -- | Option controlling how to qualify names
|
| ... | ... | @@ -874,6 +880,8 @@ data HsTypeDocNameIExt |
| 874 | 880 | |
| 875 | 881 | | HsRecTy [LHsConDeclRecField DocNameI]
|
| 876 | 882 | |
| 883 | + | HsRedacted (HsType DocNameI) -- ^ contains the kind of the redacted type
|
|
| 884 | + |
|
| 877 | 885 | type instance XNumTy DocNameI = NoExtField
|
| 878 | 886 | type instance XStrTy DocNameI = NoExtField
|
| 879 | 887 | type instance XCharTy DocNameI = NoExtField
|
| 1 | +<html xmlns="http://www.w3.org/1999/xhtml"
|
|
| 2 | +><head
|
|
| 3 | + ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
|
|
| 4 | + /><meta name="viewport" content="width=device-width, initial-scale=1"
|
|
| 5 | + /><title
|
|
| 6 | + >RedactTypeSynonyms</title
|
|
| 7 | + ><link href="#" rel="stylesheet" type="text/css" title="Linuwial"
|
|
| 8 | + /><link rel="stylesheet" type="text/css" href="#"
|
|
| 9 | + /><link rel="stylesheet" type="text/css" href="#"
|
|
| 10 | + /><script src="haddock-bundle.min.js" async="async" type="text/javascript"
|
|
| 11 | + ></script
|
|
| 12 | + ><script type="text/x-mathjax-config"
|
|
| 13 | + >MathJax.Hub.Config({ tex2jax: { processClass: "mathjax", ignoreClass: ".*" } });</script
|
|
| 14 | + ><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"
|
|
| 15 | + ></script
|
|
| 16 | + ></head
|
|
| 17 | + ><body
|
|
| 18 | + ><div id="package-header"
|
|
| 19 | + ><span class="caption empty"
|
|
| 20 | + > </span
|
|
| 21 | + ><ul class="links" id="page-menu"
|
|
| 22 | + ><li
|
|
| 23 | + ><a href="#"
|
|
| 24 | + >Contents</a
|
|
| 25 | + ></li
|
|
| 26 | + ><li
|
|
| 27 | + ><a href="#"
|
|
| 28 | + >Index</a
|
|
| 29 | + ></li
|
|
| 30 | + ></ul
|
|
| 31 | + ></div
|
|
| 32 | + ><div id="content"
|
|
| 33 | + ><div id="module-header"
|
|
| 34 | + ><table class="info"
|
|
| 35 | + ><tr
|
|
| 36 | + ><th
|
|
| 37 | + >Safe Haskell</th
|
|
| 38 | + ><td
|
|
| 39 | + >None</td
|
|
| 40 | + ></tr
|
|
| 41 | + ></table
|
|
| 42 | + ><p class="caption"
|
|
| 43 | + >RedactTypeSynonyms</p
|
|
| 44 | + ></div
|
|
| 45 | + ><div id="synopsis"
|
|
| 46 | + ><details id="syn"
|
|
| 47 | + ><summary
|
|
| 48 | + >Synopsis</summary
|
|
| 49 | + ><ul class="details-toggle" data-details-id="syn"
|
|
| 50 | + ><li class="src short"
|
|
| 51 | + ><span class="keyword"
|
|
| 52 | + >type</span
|
|
| 53 | + > <a href="#"
|
|
| 54 | + >ExportedType1</a
|
|
| 55 | + > :: <a href="#" title="Data.Kind"
|
|
| 56 | + >Type</a
|
|
| 57 | + ></li
|
|
| 58 | + ><li class="src short"
|
|
| 59 | + ><span class="keyword"
|
|
| 60 | + >type</span
|
|
| 61 | + > <a href="#"
|
|
| 62 | + >ExportedType2</a
|
|
| 63 | + > a :: <a href="#" title="Data.Kind"
|
|
| 64 | + >Type</a
|
|
| 65 | + ></li
|
|
| 66 | + ><li class="src short"
|
|
| 67 | + ><span class="keyword"
|
|
| 68 | + >type</span
|
|
| 69 | + > <a href="#"
|
|
| 70 | + >ExportedType3</a
|
|
| 71 | + > :: <a href="#" title="Data.Kind"
|
|
| 72 | + >Constraint</a
|
|
| 73 | + ></li
|
|
| 74 | + ><li class="src short"
|
|
| 75 | + ><span class="keyword"
|
|
| 76 | + >type</span
|
|
| 77 | + > <a href="#"
|
|
| 78 | + >ExportedType4</a
|
|
| 79 | + > a = (a, <a href="#" title="RedactTypeSynonyms"
|
|
| 80 | + >ExportedType2</a
|
|
| 81 | + > a)</li
|
|
| 82 | + ><li class="src short"
|
|
| 83 | + ><span class="keyword"
|
|
| 84 | + >type</span
|
|
| 85 | + > <a href="#"
|
|
| 86 | + >ExportedType5</a
|
|
| 87 | + > (f :: k1 -> k2) (a :: k1) :: (k1, k2, <a href="#" title="Data.Kind"
|
|
| 88 | + >Type</a
|
|
| 89 | + >)</li
|
|
| 90 | + ><li class="src short"
|
|
| 91 | + ><a href="#"
|
|
| 92 | + >exportedFn</a
|
|
| 93 | + > :: <a href="#" title="Data.Bool"
|
|
| 94 | + >Bool</a
|
|
| 95 | + > -> AlsoHidden</li
|
|
| 96 | + ></ul
|
|
| 97 | + ></details
|
|
| 98 | + ></div
|
|
| 99 | + ><div id="interface"
|
|
| 100 | + ><h1
|
|
| 101 | + >Documentation</h1
|
|
| 102 | + ><div class="top"
|
|
| 103 | + ><p class="src"
|
|
| 104 | + ><span class="keyword"
|
|
| 105 | + >type</span
|
|
| 106 | + > <a id="t:ExportedType1" class="def"
|
|
| 107 | + >ExportedType1</a
|
|
| 108 | + > :: <a href="#" title="Data.Kind"
|
|
| 109 | + >Type</a
|
|
| 110 | + > <a href="#" class="selflink"
|
|
| 111 | + >#</a
|
|
| 112 | + ></p
|
|
| 113 | + ><div class="doc"
|
|
| 114 | + ><p
|
|
| 115 | + >A type that should be redacted.</p
|
|
| 116 | + ></div
|
|
| 117 | + ></div
|
|
| 118 | + ><div class="top"
|
|
| 119 | + ><p class="src"
|
|
| 120 | + ><span class="keyword"
|
|
| 121 | + >type</span
|
|
| 122 | + > <a id="t:ExportedType2" class="def"
|
|
| 123 | + >ExportedType2</a
|
|
| 124 | + > a :: <a href="#" title="Data.Kind"
|
|
| 125 | + >Type</a
|
|
| 126 | + > <a href="#" class="selflink"
|
|
| 127 | + >#</a
|
|
| 128 | + ></p
|
|
| 129 | + ><div class="doc"
|
|
| 130 | + ><p
|
|
| 131 | + >Another type that should be redacted, but that shouldn't suppress the
|
|
| 132 | + warning about AlsoHidden, because it's also visible in <code
|
|
| 133 | + ><a href="#" title="RedactTypeSynonyms"
|
|
| 134 | + >exportedFn</a
|
|
| 135 | + ></code
|
|
| 136 | + >.</p
|
|
| 137 | + ></div
|
|
| 138 | + ></div
|
|
| 139 | + ><div class="top"
|
|
| 140 | + ><p class="src"
|
|
| 141 | + ><span class="keyword"
|
|
| 142 | + >type</span
|
|
| 143 | + > <a id="t:ExportedType3" class="def"
|
|
| 144 | + >ExportedType3</a
|
|
| 145 | + > :: <a href="#" title="Data.Kind"
|
|
| 146 | + >Constraint</a
|
|
| 147 | + > <a href="#" class="selflink"
|
|
| 148 | + >#</a
|
|
| 149 | + ></p
|
|
| 150 | + ><div class="doc"
|
|
| 151 | + ><p
|
|
| 152 | + >For a little kind variety.</p
|
|
| 153 | + ></div
|
|
| 154 | + ></div
|
|
| 155 | + ><div class="top"
|
|
| 156 | + ><p class="src"
|
|
| 157 | + ><span class="keyword"
|
|
| 158 | + >type</span
|
|
| 159 | + > <a id="t:ExportedType4" class="def"
|
|
| 160 | + >ExportedType4</a
|
|
| 161 | + > a = (a, <a href="#" title="RedactTypeSynonyms"
|
|
| 162 | + >ExportedType2</a
|
|
| 163 | + > a) <a href="#" class="selflink"
|
|
| 164 | + >#</a
|
|
| 165 | + ></p
|
|
| 166 | + ><div class="doc"
|
|
| 167 | + ><p
|
|
| 168 | + >This type does not need to be redacted.</p
|
|
| 169 | + ></div
|
|
| 170 | + ></div
|
|
| 171 | + ><div class="top"
|
|
| 172 | + ><p class="src"
|
|
| 173 | + ><span class="keyword"
|
|
| 174 | + >type</span
|
|
| 175 | + > <a id="t:ExportedType5" class="def"
|
|
| 176 | + >ExportedType5</a
|
|
| 177 | + > (f :: k1 -> k2) (a :: k1) :: (k1, k2, <a href="#" title="Data.Kind"
|
|
| 178 | + >Type</a
|
|
| 179 | + >) <a href="#" class="selflink"
|
|
| 180 | + >#</a
|
|
| 181 | + ></p
|
|
| 182 | + ><div class="doc"
|
|
| 183 | + ><p
|
|
| 184 | + >This type has parameters in the result kind.</p
|
|
| 185 | + ></div
|
|
| 186 | + ></div
|
|
| 187 | + ><div class="top"
|
|
| 188 | + ><p class="src"
|
|
| 189 | + ><a id="v:exportedFn" class="def"
|
|
| 190 | + >exportedFn</a
|
|
| 191 | + > :: <a href="#" title="Data.Bool"
|
|
| 192 | + >Bool</a
|
|
| 193 | + > -> AlsoHidden <a href="#" class="selflink"
|
|
| 194 | + >#</a
|
|
| 195 | + ></p
|
|
| 196 | + ><div class="doc"
|
|
| 197 | + ><p
|
|
| 198 | + >A function.</p
|
|
| 199 | + ></div
|
|
| 200 | + ></div
|
|
| 201 | + ></div
|
|
| 202 | + ></div
|
|
| 203 | + ></body
|
|
| 204 | + ></html
|
|
| 205 | +> |
| 1 | +{-# LANGUAGE DataKinds #-}
|
|
| 2 | +{-# LANGUAGE StandaloneKindSignatures #-}
|
|
| 3 | +{-# OPTIONS_HADDOCK redact-type-synonyms #-}
|
|
| 4 | +module RedactTypeSynonyms (
|
|
| 5 | + ExportedType1,
|
|
| 6 | + ExportedType2,
|
|
| 7 | + ExportedType3,
|
|
| 8 | + ExportedType4,
|
|
| 9 | + ExportedType5,
|
|
| 10 | + exportedFn,
|
|
| 11 | +) where
|
|
| 12 | + |
|
| 13 | +import Data.Kind (Type)
|
|
| 14 | + |
|
| 15 | +-- We don't want to see a warning about this being undocumented, because it is
|
|
| 16 | +-- only used in 'ExportedType', which is redacted.
|
|
| 17 | +--
|
|
| 18 | +-- (Warnings aren't currently tested, but this module would be a good case for
|
|
| 19 | +-- it.)
|
|
| 20 | +data Hidden
|
|
| 21 | + |
|
| 22 | +-- We do want to see a warning here, though.
|
|
| 23 | +data AlsoHidden
|
|
| 24 | + |
|
| 25 | +class ThisIsHiddenToo where
|
|
| 26 | + |
|
| 27 | +-- | A type that should be redacted.
|
|
| 28 | +type ExportedType1 = (Bool, Hidden)
|
|
| 29 | + |
|
| 30 | +-- | Another type that should be redacted, but that shouldn't suppress the
|
|
| 31 | +-- warning about AlsoHidden, because it's also visible in 'exportedFn'.
|
|
| 32 | +type ExportedType2 a = (a, AlsoHidden)
|
|
| 33 | + |
|
| 34 | +-- | For a little kind variety.
|
|
| 35 | +type ExportedType3 = ThisIsHiddenToo
|
|
| 36 | + |
|
| 37 | +-- | This type does not need to be redacted.
|
|
| 38 | +type ExportedType4 a = (a, ExportedType2 a)
|
|
| 39 | + |
|
| 40 | +-- | This type has parameters in the result kind.
|
|
| 41 | +type ExportedType5 :: forall k1 k2. (k1 -> k2) -> k1 -> (k1, k2, Type)
|
|
| 42 | +type ExportedType5 f a = '(a, f a, Hidden)
|
|
| 43 | + |
|
| 44 | +-- | A function.
|
|
| 45 | +exportedFn :: Bool -> AlsoHidden
|
|
| 46 | +exportedFn = undefined |
| 1 | +\haddockmoduleheading{RedactTypeSynonyms}
|
|
| 2 | +\label{module:RedactTypeSynonyms}
|
|
| 3 | +\haddockbeginheader
|
|
| 4 | +{\haddockverb\begin{verbatim}
|
|
| 5 | +module RedactTypeSynonyms (
|
|
| 6 | + ExportedType1, ExportedType2, ExportedType3, ExportedType4, ExportedType5,
|
|
| 7 | + exportedFn
|
|
| 8 | + ) where\end{verbatim}}
|
|
| 9 | +\haddockendheader
|
|
| 10 | + |
|
| 11 | +\begin{haddockdesc}
|
|
| 12 | +\item[\begin{tabular}{@{}l}
|
|
| 13 | +type ExportedType1 :: Type
|
|
| 14 | +\end{tabular}]
|
|
| 15 | +{\haddockbegindoc
|
|
| 16 | +A type that should be redacted.\par}
|
|
| 17 | +\end{haddockdesc}
|
|
| 18 | +\begin{haddockdesc}
|
|
| 19 | +\item[\begin{tabular}{@{}l}
|
|
| 20 | +type ExportedType2 a :: Type
|
|
| 21 | +\end{tabular}]
|
|
| 22 | +{\haddockbegindoc
|
|
| 23 | +Another type that should be redacted, but that shouldn't suppress the
|
|
| 24 | + warning about AlsoHidden, because it's also visible in \haddockid{exportedFn}.\par}
|
|
| 25 | +\end{haddockdesc}
|
|
| 26 | +\begin{haddockdesc}
|
|
| 27 | +\item[\begin{tabular}{@{}l}
|
|
| 28 | +type ExportedType3 :: Constraint
|
|
| 29 | +\end{tabular}]
|
|
| 30 | +{\haddockbegindoc
|
|
| 31 | +For a little kind variety.\par}
|
|
| 32 | +\end{haddockdesc}
|
|
| 33 | +\begin{haddockdesc}
|
|
| 34 | +\item[\begin{tabular}{@{}l}
|
|
| 35 | +type ExportedType4 a = (a, ExportedType2 a)
|
|
| 36 | +\end{tabular}]
|
|
| 37 | +{\haddockbegindoc
|
|
| 38 | +This type does not need to be redacted.\par}
|
|
| 39 | +\end{haddockdesc}
|
|
| 40 | +\begin{haddockdesc}
|
|
| 41 | +\item[\begin{tabular}{@{}l}
|
|
| 42 | +type ExportedType5 f a :: (k1, k2, Type)
|
|
| 43 | +\end{tabular}]
|
|
| 44 | +{\haddockbegindoc
|
|
| 45 | +This type has parameters in the result kind.\par}
|
|
| 46 | +\end{haddockdesc}
|
|
| 47 | +\begin{haddockdesc}
|
|
| 48 | +\item[\begin{tabular}{@{}l}
|
|
| 49 | +exportedFn :: Bool -> AlsoHidden
|
|
| 50 | +\end{tabular}]
|
|
| 51 | +{\haddockbegindoc
|
|
| 52 | +A function.\par}
|
|
| 53 | +\end{haddockdesc} |
|
| \ No newline at end of file |
| 1 | +{-# LANGUAGE DataKinds #-}
|
|
| 2 | +{-# LANGUAGE StandaloneKindSignatures #-}
|
|
| 3 | +{-# OPTIONS_HADDOCK redact-type-synonyms #-}
|
|
| 4 | +module RedactTypeSynonyms (
|
|
| 5 | + ExportedType1,
|
|
| 6 | + ExportedType2,
|
|
| 7 | + ExportedType3,
|
|
| 8 | + ExportedType4,
|
|
| 9 | + ExportedType5,
|
|
| 10 | + exportedFn,
|
|
| 11 | +) where
|
|
| 12 | + |
|
| 13 | +import Data.Kind (Type)
|
|
| 14 | + |
|
| 15 | +-- We don't want to see a warning about this being undocumented, because it is
|
|
| 16 | +-- only used in 'ExportedType', which is redacted.
|
|
| 17 | +--
|
|
| 18 | +-- (Warnings aren't currently tested, but this module would be a good case for
|
|
| 19 | +-- it.)
|
|
| 20 | +data Hidden
|
|
| 21 | + |
|
| 22 | +-- We do want to see a warning here, though.
|
|
| 23 | +data AlsoHidden
|
|
| 24 | + |
|
| 25 | +class ThisIsHiddenToo where
|
|
| 26 | + |
|
| 27 | +-- | A type that should be redacted.
|
|
| 28 | +type ExportedType1 = (Bool, Hidden)
|
|
| 29 | + |
|
| 30 | +-- | Another type that should be redacted, but that shouldn't suppress the
|
|
| 31 | +-- warning about AlsoHidden, because it's also visible in 'exportedFn'.
|
|
| 32 | +type ExportedType2 a = (a, AlsoHidden)
|
|
| 33 | + |
|
| 34 | +-- | For a little kind variety.
|
|
| 35 | +type ExportedType3 = ThisIsHiddenToo
|
|
| 36 | + |
|
| 37 | +-- | This type does not need to be redacted.
|
|
| 38 | +type ExportedType4 a = (a, ExportedType2 a)
|
|
| 39 | + |
|
| 40 | +-- | This type has parameters in the result kind.
|
|
| 41 | +type ExportedType5 :: forall k1 k2. (k1 -> k2) -> k1 -> (k1, k2, Type)
|
|
| 42 | +type ExportedType5 f a = '(a, f a, Hidden)
|
|
| 43 | + |
|
| 44 | +-- | A function.
|
|
| 45 | +exportedFn :: Bool -> AlsoHidden
|
|
| 46 | +exportedFn = undefined |