@@ -110,6 +110,8 @@ import Development.IDE.GHC.Compat.Util (emptyUDFM, plusUDFM)
110110import qualified Language.LSP.Server as LSP
111111import qualified Language.LSP.Types as LSP
112112import Unsafe.Coerce
113+ import Data.Tuple.Extra (first )
114+ import Data.Tuple (swap )
113115
114116-- | Given a string buffer, return the string (after preprocessing) and the 'ParsedModule'.
115117parseModule
@@ -992,26 +994,80 @@ getDocsBatch
992994 :: HscEnv
993995 -> Module -- ^ a moudle where the names are in scope
994996 -> [Name ]
997+ -- 2021-11-19: NOTE: Don't forget these 'Map' currently lazy.
995998 -- 2021-11-18: NOTE: Map Int would become IntMap if next GHCs.
996999 -> IO (Either ErrorMessages (Map. Map Name (Either GetDocsFailure (Maybe HsDocString , Maybe (Map. Map Int HsDocString )))))
9971000 -- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs)
9981001getDocsBatch hsc_env _mod _names = do
999- ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map. fromList <$> traverse findNameInfo _names
1002+ ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map. fromList <$> traverse undefined undefined
10001003 pure $ maybeToEither errs res
10011004 where
1002- findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv ) (Name , Either GetDocsFailure (Maybe HsDocString , Maybe (Map. Map Int HsDocString )))
1003- findNameInfo name =
1004- case nameModule_maybe name of
1005- Nothing -> return (name, Left $ NameHasNoModule name)
1006- Just mod -> do
1005+ -- fun1 :: (Map Name (IOEnv (Env TcGblEnv TcLclEnv) (Maybe HsDocString, Maybe (Map Int HsDocString))))
1006+ -- fun1 = Map.fromList fun
1007+
1008+ fun :: IOEnv (Env TcGblEnv TcLclEnv ) (Map Name (Maybe HsDocString , Maybe (Map Int HsDocString )))
1009+ fun = _ getAskedIfaceDocs loadIfaces
1010+
1011+ getAskedIfaceDocs :: ((Map Name HsDocString , Map Name (Map Int HsDocString )), [Name ]) -> Map Name (Maybe HsDocString , Maybe (Map Int HsDocString ))
1012+ getAskedIfaceDocs a = Map. fromList $
1013+ fun2 <$> snd a
1014+ where
1015+ fun2 :: Name -> (Name , (Maybe HsDocString , Maybe (Map Int HsDocString )))
1016+ fun2 n = (n, bimap (Map. lookup n) (Map. lookup n) $ fst a)
1017+
1018+ loadIfaces :: IOEnv (Env TcGblEnv TcLclEnv ) [((Map Name HsDocString , Map Name (Map Int HsDocString )), [Name ])]
1019+ loadIfaces = fun3 (fmap (first getIfaceGenNArgDocMaps) loadModules)
1020+ where
1021+ fun3 :: [(env ms , ns )] -> env [(ms , ns )]
1022+ fun3 a = (fmap . fmap ) swap $ sequenceA $ fmap swap a
1023+
1024+ getIfaceGenNArgDocMaps :: TcRn ModIface -> IOEnv (Env TcGblEnv TcLclEnv ) (Map Name HsDocString , Map Name (Map Int HsDocString ))
1025+ getIfaceGenNArgDocMaps mi = do
1026+ ModIface
1027+ { mi_doc_hdr = mb_doc_hdr
1028+ , mi_decl_docs = DeclDocMap dmap
1029+ , mi_arg_docs = ArgDocMap amap
1030+ }
1031+ <- mi
1032+ pure $
1033+ if isNothing mb_doc_hdr && Map. null dmap && Map. null amap
1034+ then error " Instead of 'error' here handle 'NoDocsInIface mod $ isCompiled name' case"
1035+ else (dmap, amap)
1036+
1037+ loadModules :: [(TcRn ModIface , [Name ])]
1038+ loadModules = fmap loadAvailableModules namesGroupedByModule
1039+ where
1040+ loadAvailableModules :: (Module , [Name ]) -> (TcRn ModIface , [Name ])
1041+ loadAvailableModules = first loadModuleInterfaceOnce
1042+
1043+
1044+ loadModuleInterfaceOnce :: Module -> TcRn ModIface
1045+ loadModuleInterfaceOnce =
1046+ loadModuleInterface " getModuleInterface"
1047+
1048+ namesGroupedByModule :: [(Module , [Name ])]
1049+ namesGroupedByModule =
1050+ groupSort $ fmap (first (fromMaybe (error " Instead of 'error' handle here 'NameHasNoModule' case" ) . nameModule_maybe) . dupe) _names
1051+
1052+ -- modulesPartitionedOnAvalability :: [(Either (Name -> GetDocsFailure) Module, [Name])]
1053+ -- modulesPartitionedOnAvalability = fmap partitionOnModuleAvalibility namesGroupedByModule
1054+
1055+ -- partitionOnModuleAvalibility :: (Maybe Module, [Name]) -> (Either (Name -> GetDocsFailure) Module, [Name])
1056+ -- partitionOnModuleAvalibility =
1057+ -- first (maybeToEither NameHasNoModule)
1058+
1059+
1060+ -- 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
1061+ findNameInfo :: Maybe Module -> Name -> IOEnv (Env TcGblEnv TcLclEnv ) (Name , Either GetDocsFailure (Maybe HsDocString , Maybe (Map. Map Int HsDocString )))
1062+ findNameInfo Nothing name = return (name, Left $ NameHasNoModule name)
1063+ findNameInfo (Just mod ) name = do
10071064 ModIface
10081065 { mi_doc_hdr = mb_doc_hdr
10091066 , mi_decl_docs = DeclDocMap dmap
10101067 , mi_arg_docs = ArgDocMap amap
10111068 }
10121069 <- loadModuleInterface " getModuleInterface" mod
10131070 pure . (name,) $
1014- -- 2021-11-17: NOTE: one does not simply check into Mordor (not 1 mode)
10151071 if isNothing mb_doc_hdr && Map. null dmap && Map. null amap
10161072 then Left $ NoDocsInIface mod $ isCompiled name
10171073 else Right (Map. lookup name dmap, Map. lookup name amap)
0 commit comments