Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit d50a1b0

Browse files
committed
Apply progress reporting to setTypecheckedModule in its new home
It moved from the ghc-mod plugin to hie-plugin-api
1 parent eb77dc1 commit d50a1b0

File tree

3 files changed

+7
-154
lines changed

3 files changed

+7
-154
lines changed

hie-plugin-api/Haskell/Ide/Engine/Ghc.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import qualified GhcMod.Utils as GM
3535
import Haskell.Ide.Engine.MonadFunctions
3636
import Haskell.Ide.Engine.MonadTypes
3737
import Haskell.Ide.Engine.PluginUtils
38+
import System.FilePath
3839

3940
import DynFlags
4041
import GHC
@@ -164,14 +165,16 @@ setTypecheckedModule uri =
164165
rfm <- GM.mkRevRedirMapFunc
165166
let
166167
ghcErrRes msg = ((Map.empty, [T.pack msg]),Nothing,Nothing)
168+
progTitle = "Typechecking " <> T.pack (takeFileName fp)
167169
debugm "setTypecheckedModule: before ghc-mod"
168170
-- TODO:AZ: loading this one module may/should trigger loads of any
169171
-- other modules which currently have a VFS entry. Need to make
170172
-- sure that their diagnostics are reported, and their module
171173
-- cache entries are updated.
172-
((diags', errs), mtm, mpm) <- GM.gcatches
173-
(GM.getModulesGhc' (myWrapper rfm) fp)
174-
(errorHandlers ghcErrRes (return . ghcErrRes . show))
174+
-- TODO: Are there any hooks we can use to report back on the progress?
175+
((diags', errs), mtm, mpm) <- withIndefiniteProgress progTitle NotCancellable $ GM.gcatches
176+
(GM.getModulesGhc' (myWrapper rfm) fp)
177+
(errorHandlers ghcErrRes (return . ghcErrRes . show))
175178
debugm "setTypecheckedModule: after ghc-mod"
176179

177180
canonUri <- canonicalizeUri uri

hie-plugin-api/Haskell/Ide/Engine/PluginApi.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ module Haskell.Ide.Engine.PluginApi
4242
, HIE.IdeM
4343
, HIE.runIdeM
4444
, HIE.IdeDeferM
45-
, HIE.MonadIde(..)
45+
, HIE.MonadIde
4646
, HIE.iterT
4747
, HIE.LiftsToGhc(..)
4848
, HIE.HasGhcModuleCache(..)

src/Haskell/Ide/Engine/Plugin/GhcMod.hs

Lines changed: 0 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ import Data.List
3535
import Data.Maybe
3636
import Data.Monoid ((<>))
3737
import qualified Data.Text as T
38-
import System.FilePath
39-
import ErrUtils
4038
import Name
4139
import GHC.Generics
4240
import qualified GhcMod as GM
@@ -88,154 +86,6 @@ checkCmd = CmdSync setTypecheckedModule
8886

8987
-- ---------------------------------------------------------------------
9088

91-
lspSev :: Severity -> DiagnosticSeverity
92-
lspSev SevWarning = DsWarning
93-
lspSev SevError = DsError
94-
lspSev SevFatal = DsError
95-
lspSev SevInfo = DsInfo
96-
lspSev _ = DsInfo
97-
98-
-- type LogAction = DynFlags -> WarnReason -> Severity -> SrcSpan -> PprStyle -> MsgDoc -> IO ()
99-
logDiag :: (FilePath -> FilePath) -> IORef AdditionalErrs -> IORef Diagnostics -> LogAction
100-
logDiag rfm eref dref df _reason sev spn style msg = do
101-
eloc <- srcSpan2Loc rfm spn
102-
let msgTxt = T.pack $ renderWithStyle df msg style
103-
case eloc of
104-
Right (Location uri range) -> do
105-
let update = Map.insertWith Set.union uri l
106-
where l = Set.singleton diag
107-
diag = Diagnostic range (Just $ lspSev sev) Nothing (Just "ghcmod") msgTxt Nothing
108-
modifyIORef' dref update
109-
Left _ -> do
110-
modifyIORef' eref (msgTxt:)
111-
return ()
112-
113-
unhelpfulSrcSpanErr :: T.Text -> IdeError
114-
unhelpfulSrcSpanErr err =
115-
IdeError PluginError
116-
("Unhelpful SrcSpan" <> ": \"" <> err <> "\"")
117-
Null
118-
119-
srcErrToDiag :: MonadIO m
120-
=> DynFlags
121-
-> (FilePath -> FilePath)
122-
-> SourceError -> m (Diagnostics, AdditionalErrs)
123-
srcErrToDiag df rfm se = do
124-
debugm "in srcErrToDiag"
125-
let errMsgs = bagToList $ srcErrorMessages se
126-
processMsg err = do
127-
let sev = Just DsError
128-
unqual = errMsgContext err
129-
st = GM.mkErrStyle' df unqual
130-
msgTxt = T.pack $ renderWithStyle df (pprLocErrMsg err) st
131-
eloc <- srcSpan2Loc rfm $ errMsgSpan err
132-
case eloc of
133-
Right (Location uri range) ->
134-
return $ Right (uri, Diagnostic range sev Nothing (Just "ghcmod") msgTxt Nothing)
135-
Left _ -> return $ Left msgTxt
136-
processMsgs [] = return (Map.empty,[])
137-
processMsgs (x:xs) = do
138-
res <- processMsg x
139-
(m,es) <- processMsgs xs
140-
case res of
141-
Right (uri, diag) ->
142-
return (Map.insertWith Set.union uri (Set.singleton diag) m, es)
143-
Left e -> return (m, e:es)
144-
processMsgs errMsgs
145-
146-
myWrapper :: GM.IOish m
147-
=> (FilePath -> FilePath)
148-
-> GM.GmlT m ()
149-
-> GM.GmlT m (Diagnostics, AdditionalErrs)
150-
myWrapper rfm action = do
151-
env <- getSession
152-
diagRef <- liftIO $ newIORef Map.empty
153-
errRef <- liftIO $ newIORef []
154-
let setLogger df = df { log_action = logDiag rfm errRef diagRef }
155-
setDeferTypedHoles = setGeneralFlag' Opt_DeferTypedHoles
156-
ghcErrRes msg = (Map.empty, [T.pack msg])
157-
handlers = errorHandlers ghcErrRes (srcErrToDiag (hsc_dflags env) rfm )
158-
action' = do
159-
GM.withDynFlags (setLogger . setDeferTypedHoles) action
160-
diags <- liftIO $ readIORef diagRef
161-
errs <- liftIO $ readIORef errRef
162-
return (diags,errs)
163-
GM.gcatches action' handlers
164-
165-
errorHandlers :: (Monad m) => (String -> a) -> (SourceError -> m a) -> [GM.GHandler m a]
166-
errorHandlers ghcErrRes renderSourceError = handlers
167-
where
168-
-- ghc throws GhcException, SourceError, GhcApiError and
169-
-- IOEnvFailure. ghc-mod-core throws GhcModError.
170-
handlers =
171-
[ GM.GHandler $ \(ex :: GM.GhcModError) ->
172-
return $ ghcErrRes (show ex)
173-
, GM.GHandler $ \(ex :: IOEnvFailure) ->
174-
return $ ghcErrRes (show ex)
175-
, GM.GHandler $ \(ex :: GhcApiError) ->
176-
return $ ghcErrRes (show ex)
177-
, GM.GHandler $ \(ex :: SourceError) ->
178-
renderSourceError ex
179-
, GM.GHandler $ \(ex :: GhcException) ->
180-
return $ ghcErrRes $ GM.renderGm $ GM.ghcExceptionDoc ex
181-
, GM.GHandler $ \(ex :: IOError) ->
182-
return $ ghcErrRes (show ex)
183-
-- , GM.GHandler $ \(ex :: GM.SomeException) ->
184-
-- return $ ghcErrRes (show ex)
185-
]
186-
187-
setTypecheckedModule :: Uri -> IdeGhcM (IdeResult (Diagnostics, AdditionalErrs))
188-
setTypecheckedModule uri =
189-
pluginGetFile "setTypecheckedModule: " uri $ \fp -> do
190-
fileMap <- GM.getMMappedFiles
191-
debugm $ "setTypecheckedModule: file mapping state is: " ++ show fileMap
192-
rfm <- GM.mkRevRedirMapFunc
193-
let
194-
ghcErrRes msg = ((Map.empty, [T.pack msg]),Nothing,Nothing)
195-
progTitle = "Typechecking " <> T.pack (takeFileName fp)
196-
debugm "setTypecheckedModule: before ghc-mod"
197-
-- TODO: Are there any hooks we can use to report back on the progress?
198-
((diags', errs), mtm, mpm) <- withIndefiniteProgress progTitle NotCancellable $ GM.gcatches
199-
(GM.getModulesGhc' (myWrapper rfm) fp)
200-
(errorHandlers ghcErrRes (return . ghcErrRes . show))
201-
debugm "setTypecheckedModule: after ghc-mod"
202-
203-
canonUri <- canonicalizeUri uri
204-
let diags = Map.insertWith Set.union canonUri Set.empty diags'
205-
diags2 <- case (mpm,mtm) of
206-
(Just pm, Nothing) -> do
207-
debugm $ "setTypecheckedModule: Did get parsed module for: " ++ show fp
208-
cacheModule fp (Left pm)
209-
debugm "setTypecheckedModule: done"
210-
return diags
211-
212-
(_, Just tm) -> do
213-
debugm $ "setTypecheckedModule: Did get typechecked module for: " ++ show fp
214-
sess <- fmap GM.gmgsSession . GM.gmGhcSession <$> GM.gmsGet
215-
216-
-- set the session before we cache the module, so that deferred
217-
-- responses triggered by cacheModule can access it
218-
modifyMTS (\s -> s {ghcSession = sess})
219-
cacheModule fp (Right tm)
220-
debugm "setTypecheckedModule: done"
221-
return diags
222-
223-
_ -> do
224-
debugm $ "setTypecheckedModule: Didn't get typechecked or parsed module for: " ++ show fp
225-
debugm $ "setTypecheckedModule: errs: " ++ show errs
226-
227-
failModule fp
228-
229-
let sev = Just DsError
230-
range = Range (Position 0 0) (Position 1 0)
231-
msgTxt = T.unlines errs
232-
let d = Diagnostic range sev Nothing (Just "ghcmod") msgTxt Nothing
233-
return $ Map.insertWith Set.union canonUri (Set.singleton d) diags
234-
235-
return $ IdeResultOk (diags2,errs)
236-
237-
-- ---------------------------------------------------------------------
238-
23989
lintCmd :: CommandFunc Uri T.Text
24090
lintCmd = CmdSync lintCmd'
24191

0 commit comments

Comments
 (0)