Skip to content

Commit

Permalink
ghcide: Core.Compile: add getDocsNonInteractive{',}
Browse files Browse the repository at this point in the history
`getDocsBatch` cuurently (& before) used only for single name retrieval
function. Use of it is in `Documentation` module `getDocumentationTryGhc` where
it wraps arg into singleton & gives to `getDocsBatch` & then recieves a Map with
1 entry & unsafely "lookups" doc in it.

This work is to supply the proper single name retrieval-optimized version to
stop that `getDocsBatch` there.

& further ideally `getDocumentationTryGhc` uses single-retrieval &
`getDocumentationsTryGhc` uses a batch mode & batch mode gets optimized along
the lines of: haskell#2371
  • Loading branch information
Anton-Latukha committed Feb 1, 2022
1 parent 9c0660d commit 1798006
Showing 1 changed file with 27 additions and 12 deletions.
39 changes: 27 additions & 12 deletions ghcide/src/Development/IDE/Core/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module Development.IDE.Core.Compile
, loadHieFile
, loadInterface
, loadModulesHome
, getDocsNonInteractive
, getDocsBatch
, lookupName
,mergeEnvs) where
Expand Down Expand Up @@ -1016,12 +1017,20 @@ mkDetailsFromIface session iface linkable = do
initIfaceLoad hsc' (typecheckIface iface)
return (HomeModInfo iface details linkable)

fakeSpan :: RealSrcSpan
fakeSpan = realSrcLocSpan $ mkRealSrcLoc (Util.fsLit "<ghcide>") 1 1

-- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'.
-- The interactive paths create problems in ghc-lib builds
--- and lead to fun errors like "Cannot continue after interface file error".
getDocsNonInteractive :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString)))
getDocsNonInteractive name = do
initTypecheckEnv :: HscEnv -> Module -> TcRn r -> IO (Messages, Maybe r)
initTypecheckEnv hsc_env mod = initTc hsc_env HsSrcFile False mod fakeSpan

getDocsNonInteractive'
:: Name
-> IOEnv
(Env TcGblEnv TcLclEnv)
(Name,
Either
GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString)))
getDocsNonInteractive' name =
case nameModule_maybe name of
Nothing -> return (name, Left $ NameHasNoModule name)
Just mod -> do
Expand All @@ -1033,7 +1042,7 @@ getDocsNonInteractive name = do
<- loadModuleInterface "getModuleInterface" mod
let
isNameCompiled =
-- TODO: Find a more direct indicator.
-- comment from GHC: Find a more direct indicator.
case nameSrcLoc name of
RealSrcLoc {} -> False
UnhelpfulLoc {} -> True
Expand All @@ -1042,20 +1051,26 @@ getDocsNonInteractive name = do
then Left $ NoDocsInIface mod isNameCompiled
else Right (Map.lookup name dmap, Map.lookup name amap)

-- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'.
-- The interactive paths create problems in ghc-lib builds
--- and lead to fun errors like "Cannot continue after interface file error".
getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))
getDocsNonInteractive hsc_env mod name = do
((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ getDocsNonInteractive' name
pure $ maybeToEither errs res


-- | Non-interactive, batch version of 'GHC.Runtime.Eval.getDocs'.
getDocsBatch
:: HscEnv
-> Module -- ^ a moudle where the names are in scope
-> [Name]
-> IO (Either ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString)))))
-- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs)
getDocsBatch hsc_env _mod _names = do
((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse getDocsNonInteractive _names
getDocsBatch hsc_env mod names = do
((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ Map.fromList <$> traverse getDocsNonInteractive' names
pure $ maybeToEither errs res

fakeSpan :: RealSrcSpan
fakeSpan = realSrcLocSpan $ mkRealSrcLoc (Util.fsLit "<ghcide>") 1 1

-- | Non-interactive, batch version of 'InteractiveEval.lookupNames'.
-- The interactive paths create problems in ghc-lib builds
--- and leads to fun errors like "Cannot continue after interface file error".
Expand All @@ -1064,7 +1079,7 @@ lookupName :: HscEnv
-> Name
-> IO (Maybe TyThing)
lookupName hsc_env mod name = do
(_messages, res) <- initTc hsc_env HsSrcFile False mod fakeSpan $ do
(_messages, res) <- initTypecheckEnv hsc_env mod $ do
tcthing <- tcLookup name
case tcthing of
AGlobal thing -> return thing
Expand Down

0 comments on commit 1798006

Please sign in to comment.