1- {-# LANGUAGE CPP, TupleSections, BangPatterns, LambdaCase #-}
1+ {-# LANGUAGE CPP, TupleSections, BangPatterns, LambdaCase, NamedFieldPuns #-}
22{-# LANGUAGE TypeFamilies #-}
33{-# LANGUAGE ViewPatterns #-}
44{-# OPTIONS_GHC -Wwarn #-}
1818-- which creates a Haddock 'Interface' from the typechecking
1919-- results 'TypecheckedModule' from GHC.
2020-----------------------------------------------------------------------------
21- module Haddock.Interface.Create (createInterface ) where
21+ module Haddock.Interface.Create (createInterface , createInterface1 ) where
2222
2323import Documentation.Haddock.Doc (metaDocAppend )
2424import Haddock.Types
@@ -28,6 +28,7 @@ import Haddock.Utils
2828import Haddock.Convert
2929import Haddock.Interface.LexParseRn
3030
31+ import Control.Monad.IO.Class
3132import Data.Bifunctor
3233import Data.Bitraversable
3334import qualified Data.Map as M
@@ -39,6 +40,7 @@ import Control.Monad
3940import Data.Traversable
4041import GHC.Stack (HasCallStack )
4142
43+ import GHC.Tc.Utils.Monad (finalSafeMode )
4244import GHC.Types.Avail hiding (avail )
4345import qualified GHC.Types.Avail as Avail
4446import qualified GHC.Unit.Module as Module
@@ -62,6 +64,190 @@ mkExceptionContext :: TypecheckedModule -> String
6264mkExceptionContext =
6365 (" creating Haddock interface for " ++ ) . moduleNameString . ms_mod_name . pm_mod_summary . tm_parsed_module
6466
67+ createInterface1
68+ :: [Flag ]
69+ -> ModSummary
70+ -> TcGblEnv
71+ -> IfaceMap
72+ -> InstIfaceMap
73+ -> ErrMsgGhc Interface
74+ createInterface1 flags mod_sum tc_gbl_env ifaces inst_ifaces = do
75+
76+ let
77+ ModSummary
78+ {
79+ -- Cached flags from OPTIONS, INCLUDE and LANGUAGE
80+ -- pragmas in the modules source code. Used to infer
81+ -- safety of module.
82+ ms_hspp_opts
83+ , ms_location = ModLocation
84+ {
85+ ml_hie_file
86+ }
87+ } = mod_sum
88+
89+ TcGblEnv
90+ {
91+ tcg_mod
92+ , tcg_src
93+ , tcg_semantic_mod
94+ , tcg_rdr_env
95+ , tcg_exports
96+ , tcg_insts
97+ , tcg_fam_insts
98+ , tcg_warns
99+
100+ -- Renamed source
101+ , tcg_rn_imports
102+ , tcg_rn_exports
103+ , tcg_rn_decls
104+
105+ , tcg_doc_hdr
106+ } = tc_gbl_env
107+
108+ dflags = ms_hspp_opts
109+
110+ is_sig = tcg_src == HsigFile
111+
112+ (pkg_name_fs, _) =
113+ modulePackageInfo dflags flags (Just tcg_mod)
114+
115+ pkg_name :: Maybe Package
116+ pkg_name =
117+ let
118+ unpack (PackageName name) = unpackFS name
119+ in
120+ fmap unpack pkg_name_fs
121+
122+ fixities :: FixMap
123+ fixities = case tcg_rn_decls of
124+ Nothing -> mempty
125+ Just dx -> mkFixMap dx
126+
127+ -- Locations of all the TH splices
128+ loc_splices :: [SrcSpan ]
129+ loc_splices = case tcg_rn_decls of
130+ Nothing -> []
131+ Just HsGroup { hs_splcds } -> [ loc | L loc _ <- hs_splcds ]
132+
133+ decls <- case tcg_rn_decls of
134+ Nothing -> do
135+ liftErrMsg $ tell [ " Warning: Renamed source is not available" ]
136+ pure []
137+ Just dx ->
138+ pure (topDecls dx)
139+
140+ -- Derive final options to use for haddocking this module
141+ doc_opts <- liftErrMsg $ mkDocOpts (haddockOptions ms_hspp_opts) flags tcg_mod
142+
143+ let
144+ -- All elements of an explicit export list, if present
145+ export_list :: Maybe [(IE GhcRn , Avails )]
146+ export_list
147+ | OptIgnoreExports `elem` doc_opts =
148+ Nothing
149+ | Just rn_exports <- tcg_rn_exports =
150+ Just [ (ie, avail) | (L _ ie, avail) <- rn_exports ]
151+ | otherwise =
152+ Nothing
153+
154+ -- All the exported Names of this module.
155+ exported_names :: [Name ]
156+ exported_names =
157+ concatMap availNamesWithSelectors tcg_exports
158+
159+ -- Module imports of the form `import X`. Note that there is
160+ -- a) no qualification and
161+ -- b) no import list
162+ imported_modules :: Map ModuleName [ModuleName ]
163+ imported_modules
164+ | Just {} <- export_list =
165+ unrestrictedModuleImports (map unLoc tcg_rn_imports)
166+ | otherwise =
167+ M. empty
168+
169+ -- TyThings that have instances defined in this module
170+ local_instances :: [Name ]
171+ local_instances =
172+ [ name
173+ | name <- map getName tcg_insts ++ map getName tcg_fam_insts
174+ , nameIsLocalOrFrom tcg_semantic_mod name
175+ ]
176+
177+ -- Infer module safety
178+ safety <- liftIO (finalSafeMode ms_hspp_opts tc_gbl_env)
179+
180+ -- Process the top-level module header documentation.
181+ (! info, header_doc) <- liftErrMsg $ processModuleHeader dflags pkg_name
182+ tcg_rdr_env safety tcg_doc_hdr
183+
184+ -- Warnings on declarations in this module
185+ decl_warnings <- liftErrMsg (mkWarningMap dflags tcg_warns tcg_rdr_env exported_names)
186+
187+ -- Warning on the module header
188+ mod_warning <- liftErrMsg (moduleWarning dflags tcg_rdr_env tcg_warns)
189+
190+ let
191+ -- Warnings in this module and transitive warnings from dependend modules
192+ warnings :: Map Name (Doc Name )
193+ warnings = M. unions (decl_warnings : map ifaceWarningMap (M. elems ifaces))
194+
195+ maps@ (! docs, ! arg_docs, ! decl_map, _) <-
196+ liftErrMsg (mkMaps dflags pkg_name tcg_rdr_env local_instances decls)
197+
198+ export_items <- mkExportItems is_sig ifaces pkg_name tcg_mod tcg_semantic_mod
199+ warnings tcg_rdr_env exported_names (map fst decls) maps fixities
200+ imported_modules loc_splices export_list tcg_exports inst_ifaces dflags
201+
202+ let
203+ visible_names :: [Name ]
204+ visible_names = mkVisibleNames maps export_items doc_opts
205+
206+ -- Measure haddock documentation coverage.
207+ pruned_export_items :: [ExportItem GhcRn ]
208+ pruned_export_items = pruneExportItems export_items
209+
210+ ! haddockable = 1 + length export_items -- module + exports
211+ ! haddocked = (if isJust tcg_doc_hdr then 1 else 0 ) + length pruned_export_items
212+
213+ coverage :: (Int , Int )
214+ ! coverage = (haddockable, haddocked)
215+
216+ aliases :: Map Module ModuleName
217+ aliases = mkAliasMap (unitState dflags) tcg_rn_imports
218+
219+ return $! Interface
220+ {
221+ ifaceMod = tcg_mod
222+ , ifaceIsSig = is_sig
223+ , ifaceOrigFilename = msHsFilePath mod_sum
224+ , ifaceHieFile = Just ml_hie_file
225+ , ifaceInfo = info
226+ , ifaceDoc = Documentation header_doc mod_warning
227+ , ifaceRnDoc = Documentation Nothing Nothing
228+ , ifaceOptions = doc_opts
229+ , ifaceDocMap = docs
230+ , ifaceArgMap = arg_docs
231+ , ifaceRnDocMap = M. empty
232+ , ifaceRnArgMap = M. empty
233+ , ifaceExportItems = if OptPrune `elem` doc_opts then
234+ pruned_export_items else export_items
235+ , ifaceRnExportItems = []
236+ , ifaceExports = exported_names
237+ , ifaceVisibleExports = visible_names
238+ , ifaceDeclMap = decl_map
239+ , ifaceFixMap = fixities
240+ , ifaceModuleAliases = aliases
241+ , ifaceInstances = tcg_insts
242+ , ifaceFamInstances = tcg_fam_insts
243+ , ifaceOrphanInstances = [] -- Filled in attachInstances
244+ , ifaceRnOrphanInstances = [] -- Filled in attachInstances
245+ , ifaceHaddockCoverage = coverage
246+ , ifaceWarningMap = warnings
247+ , ifaceDynFlags = dflags
248+ }
249+
250+
65251-- | Use a 'TypecheckedModule' to produce an 'Interface'.
66252-- To do this, we need access to already processed modules in the topological
67253-- sort. That's what's in the 'IfaceMap'.
@@ -167,8 +353,7 @@ createInterface tm flags modMap instIfaceMap =
167353 ! prunedExportItems = seqList prunedExportItems' `seq` prunedExportItems'
168354
169355 let ! aliases =
170- mkAliasMap (unitState dflags) $ tm_renamed_source tm
171-
356+ mkAliasMap (unitState dflags) imports
172357 modWarn <- liftErrMsg (moduleWarning dflags gre warnings)
173358
174359 -- Prune the docstring 'Map's to keep only docstrings that are not private.
@@ -217,35 +402,32 @@ createInterface tm flags modMap instIfaceMap =
217402-- create a mapping from the module identity of M, to an alias N
218403-- (if there are multiple aliases, we pick the last one.) This
219404-- will go in 'ifaceModuleAliases'.
220- mkAliasMap :: UnitState -> Maybe RenamedSource -> M. Map Module ModuleName
221- mkAliasMap state mRenamedSource =
222- case mRenamedSource of
223- Nothing -> M. empty
224- Just (_,impDecls,_,_) ->
225- M. fromList $
226- mapMaybe (\ (SrcLoc. L _ impDecl) -> do
227- SrcLoc. L _ alias <- ideclAs impDecl
228- return $
229- (lookupModuleDyn state
230- -- TODO: This is supremely dodgy, because in general the
231- -- UnitId isn't going to look anything like the package
232- -- qualifier (even with old versions of GHC, the
233- -- IPID would be p-0.1, but a package qualifier never
234- -- has a version number it. (Is it possible that in
235- -- Haddock-land, the UnitIds never have version numbers?
236- -- I, ezyang, have not quite understand Haddock's package
237- -- identifier model.)
238- --
239- -- Additionally, this is simulating some logic GHC already
240- -- has for deciding how to qualify names when it outputs
241- -- them to the user. We should reuse that information;
242- -- or at least reuse the renamed imports, which know what
243- -- they import!
244- (fmap Module. fsToUnit $
245- fmap sl_fs $ ideclPkgQual impDecl)
246- (case ideclName impDecl of SrcLoc. L _ name -> name),
247- alias))
248- impDecls
405+ mkAliasMap :: UnitState -> [LImportDecl GhcRn ] -> M. Map Module ModuleName
406+ mkAliasMap state impDecls =
407+ M. fromList $
408+ mapMaybe (\ (SrcLoc. L _ impDecl) -> do
409+ SrcLoc. L _ alias <- ideclAs impDecl
410+ return $
411+ (lookupModuleDyn state
412+ -- TODO: This is supremely dodgy, because in general the
413+ -- UnitId isn't going to look anything like the package
414+ -- qualifier (even with old versions of GHC, the
415+ -- IPID would be p-0.1, but a package qualifier never
416+ -- has a version number it. (Is it possible that in
417+ -- Haddock-land, the UnitIds never have version numbers?
418+ -- I, ezyang, have not quite understand Haddock's package
419+ -- identifier model.)
420+ --
421+ -- Additionally, this is simulating some logic GHC already
422+ -- has for deciding how to qualify names when it outputs
423+ -- them to the user. We should reuse that information;
424+ -- or at least reuse the renamed imports, which know what
425+ -- they import!
426+ (fmap Module. fsToUnit $
427+ fmap sl_fs $ ideclPkgQual impDecl)
428+ (case ideclName impDecl of SrcLoc. L _ name -> name),
429+ alias))
430+ impDecls
249431
250432-- We want to know which modules are imported without any qualification. This
251433-- way we can display module reexports more compactly. This mapping also looks
0 commit comments