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 |