@@ -991,33 +991,88 @@ mkDetailsFromIface session iface linkable = do
991
991
initIfaceLoad hsc' (typecheckIface iface)
992
992
return (HomeModInfo iface details linkable)
993
993
994
+
994
995
-- | Non-interactive, batch version of 'InteractiveEval.getDocs'.
995
996
-- The interactive paths create problems in ghc-lib builds
996
997
--- and leads to fun errors like "Cannot continue after interface file error".
997
998
getDocsBatch
998
999
:: HscEnv
999
1000
-> Module -- ^ a moudle where the names are in scope
1000
1001
-> [Name ]
1001
- -> IO [Either String (Maybe HsDocString , Map. Map Int HsDocString )]
1002
+ -- 2021-11-19: NOTE: Don't forget these 'Map' currently lazy.
1003
+ -- 2021-11-18: NOTE: Map Int would become IntMap if next GHCs.
1004
+ -> IO (Either ErrorMessages (Map. Map Name (Either GetDocsFailure (Maybe HsDocString , Maybe (Map. Map Int HsDocString )))))
1005
+ -- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs)
1002
1006
getDocsBatch hsc_env _mod _names = do
1003
- ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ forM _names $ \ name ->
1004
- case nameModule_maybe name of
1005
- Nothing -> return (Left $ NameHasNoModule name)
1006
- Just mod -> do
1007
- ModIface { mi_doc_hdr = mb_doc_hdr
1008
- , mi_decl_docs = DeclDocMap dmap
1009
- , mi_arg_docs = ArgDocMap amap
1010
- } <- loadModuleInterface " getModuleInterface" mod
1011
- if isNothing mb_doc_hdr && Map. null dmap && Map. null amap
1012
- then pure (Left (NoDocsInIface mod $ compiled name))
1013
- else pure (Right ( Map. lookup name dmap
1014
- , Map. findWithDefault Map. empty name amap))
1015
- case res of
1016
- Just x -> return $ map (first $ T. unpack . showGhc) x
1017
- Nothing -> throwErrors errs
1018
- where
1019
- throwErrors = liftIO . throwIO . mkSrcErr
1020
- compiled n =
1007
+ ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map. fromList <$> traverse undefined undefined
1008
+ pure $ maybeToEither errs res
1009
+ where
1010
+ mapOfRequestedDocs :: IOEnv (Env TcGblEnv TcLclEnv ) (Map Name (Maybe HsDocString , Maybe (Map Int HsDocString )))
1011
+ mapOfRequestedDocs = Map. fromList . foldMap getAskedIfaceDocs <$> loadIfaces
1012
+
1013
+ getAskedIfaceDocs :: ((Map Name HsDocString , Map Name (Map Int HsDocString )), [Name ]) -> [(Name , (Maybe HsDocString , Maybe (Map Int HsDocString )))]
1014
+ getAskedIfaceDocs a = lookupDocs <$> snd a
1015
+ where
1016
+ lookupDocs :: Name -> (Name , (Maybe HsDocString , Maybe (Map Int HsDocString )))
1017
+ lookupDocs n = (n, bimap (Map. lookup n) (Map. lookup n) $ fst a)
1018
+
1019
+ loadIfaces :: IOEnv (Env TcGblEnv TcLclEnv ) [((Map Name HsDocString , Map Name (Map Int HsDocString )), [Name ])]
1020
+ loadIfaces = mkOneEnv (fmap (first getIfaceGenNArgDocMaps) loadModules)
1021
+ where
1022
+ mkOneEnv :: Applicative env => [(env ms , ns )] -> env [(ms , ns )]
1023
+ mkOneEnv a = traverse (fmap swap . sequenceA . swap) a
1024
+
1025
+ getIfaceGenNArgDocMaps :: TcRn ModIface -> IOEnv (Env TcGblEnv TcLclEnv ) (Map Name HsDocString , Map Name (Map Int HsDocString ))
1026
+ getIfaceGenNArgDocMaps mi = do
1027
+ ModIface
1028
+ { mi_doc_hdr = mb_doc_hdr
1029
+ , mi_decl_docs = DeclDocMap dmap
1030
+ , mi_arg_docs = ArgDocMap amap
1031
+ }
1032
+ <- mi
1033
+ pure $
1034
+ if isNothing mb_doc_hdr && Map. null dmap && Map. null amap
1035
+ then error " Instead of 'error' here handle 'NoDocsInIface mod $ isCompiled name' case"
1036
+ else (dmap, amap)
1037
+
1038
+ loadModules :: [(TcRn ModIface , [Name ])]
1039
+ loadModules = fmap loadAvailableModules namesGroupedByModule
1040
+ where
1041
+ loadAvailableModules :: (Module , [Name ]) -> (TcRn ModIface , [Name ])
1042
+ loadAvailableModules = first loadModuleInterfaceOnce
1043
+
1044
+
1045
+ loadModuleInterfaceOnce :: Module -> TcRn ModIface
1046
+ loadModuleInterfaceOnce =
1047
+ loadModuleInterface " getModuleInterface"
1048
+
1049
+ namesGroupedByModule :: [(Module , [Name ])]
1050
+ namesGroupedByModule =
1051
+ groupSort $ fmap (first (fromMaybe (error " Instead of 'error' handle here 'NameHasNoModule' case" ) . nameModule_maybe) . dupe) _names
1052
+
1053
+ -- modulesPartitionedOnAvalability :: [(Either (Name -> GetDocsFailure) Module, [Name])]
1054
+ -- modulesPartitionedOnAvalability = fmap partitionOnModuleAvalibility namesGroupedByModule
1055
+
1056
+ -- partitionOnModuleAvalibility :: (Maybe Module, [Name]) -> (Either (Name -> GetDocsFailure) Module, [Name])
1057
+ -- partitionOnModuleAvalibility =
1058
+ -- first (maybeToEither NameHasNoModule)
1059
+
1060
+
1061
+ -- 2021-11-18: NOTE: This code initially was taken from: https://hackage.haskell.org/package/ghc-9.2.1/docs/src/GHC.Runtime.Eval.html#getDocs
1062
+ findNameInfo :: Maybe Module -> Name -> IOEnv (Env TcGblEnv TcLclEnv ) (Name , Either GetDocsFailure (Maybe HsDocString , Maybe (Map. Map Int HsDocString )))
1063
+ findNameInfo Nothing name = return (name, Left $ NameHasNoModule name)
1064
+ findNameInfo (Just mod ) name = do
1065
+ ModIface
1066
+ { mi_doc_hdr = mb_doc_hdr
1067
+ , mi_decl_docs = DeclDocMap dmap
1068
+ , mi_arg_docs = ArgDocMap amap
1069
+ }
1070
+ <- loadModuleInterface " getModuleInterface" mod
1071
+ pure . (name,) $
1072
+ if isNothing mb_doc_hdr && Map. null dmap && Map. null amap
1073
+ then Left $ NoDocsInIface mod $ isCompiled name
1074
+ else Right (Map. lookup name dmap, Map. lookup name amap)
1075
+ isCompiled n =
1021
1076
-- TODO: Find a more direct indicator.
1022
1077
case nameSrcLoc n of
1023
1078
RealSrcLoc {} -> False
0 commit comments