Skip to content

Commit b2ae93a

Browse files
committed
Restore ability to run source plugins
Since ghc 9.0, plugins are stored in the HscEnv, not in the DynFlags. This caused HLS not to run source plugins anymore. This commit fixes that. Fixes #3299 and #2779.
1 parent a913f47 commit b2ae93a

File tree

4 files changed

+35
-30
lines changed

4 files changed

+35
-30
lines changed

ghcide/src/Development/IDE/Core/Compile.hs

+6-9
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,11 @@ typecheckModule :: IdeDefer
172172
typecheckModule (IdeDefer defer) hsc tc_helpers pm = do
173173
let modSummary = pm_mod_summary pm
174174
dflags = ms_hspp_opts modSummary
175-
mmodSummary' <- catchSrcErrors (hsc_dflags hsc) "typecheck (initialize plugins)"
175+
initialized <- catchSrcErrors (hsc_dflags hsc) "typecheck (initialize plugins)"
176176
(initPlugins hsc modSummary)
177-
case mmodSummary' of
177+
case initialized of
178178
Left errs -> return (errs, Nothing)
179-
Right modSummary' -> do
179+
Right (modSummary', hsc) -> do
180180
(warnings, etcm) <- withWarnings "typecheck" $ \tweak ->
181181
let
182182
session = tweak (hscSetFlags dflags hsc)
@@ -569,11 +569,6 @@ mkHiFileResultCompile se session' tcm simplified_guts = catchErrs $ do
569569
. (("Error during " ++ T.unpack source) ++) . show @SomeException
570570
]
571571

572-
initPlugins :: HscEnv -> ModSummary -> IO ModSummary
573-
initPlugins session modSummary = do
574-
session1 <- liftIO $ initializePlugins (hscSetFlags (ms_hspp_opts modSummary) session)
575-
return modSummary{ms_hspp_opts = hsc_dflags session1}
576-
577572
-- | Whether we should run the -O0 simplifier when generating core.
578573
--
579574
-- This is required for template Haskell to work but we disable this in DAML.
@@ -1101,7 +1096,9 @@ getModSummaryFromImports
11011096
-> Maybe Util.StringBuffer
11021097
-> ExceptT [FileDiagnostic] IO ModSummaryResult
11031098
getModSummaryFromImports env fp modTime contents = do
1104-
(contents, opts, dflags) <- preprocessor env fp contents
1099+
(contents, opts, env) <- preprocessor env fp contents
1100+
1101+
let dflags = hsc_dflags env
11051102

11061103
-- The warns will hopefully be reported when we actually parse the module
11071104
(_warns, L main_loc hsmod) <- parseHeader dflags fp contents

ghcide/src/Development/IDE/Core/Preprocessor.hs

+19-19
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,30 @@ import GHC.Utils.Outputable (renderWithContext)
3636

3737
-- | Given a file and some contents, apply any necessary preprocessors,
3838
-- e.g. unlit/cpp. Return the resulting buffer and the DynFlags it implies.
39-
preprocessor :: HscEnv -> FilePath -> Maybe Util.StringBuffer -> ExceptT [FileDiagnostic] IO (Util.StringBuffer, [String], DynFlags)
40-
preprocessor env0 filename mbContents = do
39+
preprocessor :: HscEnv -> FilePath -> Maybe Util.StringBuffer -> ExceptT [FileDiagnostic] IO (Util.StringBuffer, [String], HscEnv)
40+
preprocessor env filename mbContents = do
4141
-- Perform unlit
4242
(isOnDisk, contents) <-
4343
if isLiterate filename then do
44-
newcontent <- liftIO $ runLhs env0 filename mbContents
44+
newcontent <- liftIO $ runLhs env filename mbContents
4545
return (False, newcontent)
4646
else do
4747
contents <- liftIO $ maybe (Util.hGetStringBuffer filename) return mbContents
4848
let isOnDisk = isNothing mbContents
4949
return (isOnDisk, contents)
5050

5151
-- Perform cpp
52-
(opts, dflags) <- ExceptT $ parsePragmasIntoDynFlags env0 filename contents
53-
let env1 = hscSetFlags dflags env0
54-
let logger = hsc_logger env1
55-
(isOnDisk, contents, opts, dflags) <-
52+
(opts, env) <- ExceptT $ parsePragmasIntoHscEnv env filename contents
53+
let dflags = hsc_dflags env
54+
let logger = hsc_logger env
55+
(isOnDisk, contents, opts, env) <-
5656
if not $ xopt LangExt.Cpp dflags then
57-
return (isOnDisk, contents, opts, dflags)
57+
return (isOnDisk, contents, opts, env)
5858
else do
5959
cppLogs <- liftIO $ newIORef []
6060
let newLogger = pushLogHook (const (logActionCompat $ logAction cppLogs)) logger
6161
contents <- ExceptT
62-
$ (Right <$> (runCpp (putLogHook newLogger env1) filename
62+
$ (Right <$> (runCpp (putLogHook newLogger env) filename
6363
$ if isOnDisk then Nothing else Just contents))
6464
`catch`
6565
( \(e :: Util.GhcException) -> do
@@ -68,16 +68,16 @@ preprocessor env0 filename mbContents = do
6868
[] -> throw e
6969
diags -> return $ Left diags
7070
)
71-
(opts, dflags) <- ExceptT $ parsePragmasIntoDynFlags env1 filename contents
72-
return (False, contents, opts, dflags)
71+
(opts, env) <- ExceptT $ parsePragmasIntoHscEnv env filename contents
72+
return (False, contents, opts, env)
7373

7474
-- Perform preprocessor
7575
if not $ gopt Opt_Pp dflags then
76-
return (contents, opts, dflags)
76+
return (contents, opts, env)
7777
else do
78-
contents <- liftIO $ runPreprocessor env1 filename $ if isOnDisk then Nothing else Just contents
79-
(opts, dflags) <- ExceptT $ parsePragmasIntoDynFlags env1 filename contents
80-
return (contents, opts, dflags)
78+
contents <- liftIO $ runPreprocessor env filename $ if isOnDisk then Nothing else Just contents
79+
(opts, env) <- ExceptT $ parsePragmasIntoHscEnv env filename contents
80+
return (contents, opts, env)
8181
where
8282
logAction :: IORef [CPPLog] -> LogActionCompat
8383
logAction cppLogs dflags _reason severity srcSpan _style msg = do
@@ -137,12 +137,12 @@ isLiterate x = takeExtension x `elem` [".lhs",".lhs-boot"]
137137

138138

139139
-- | This reads the pragma information directly from the provided buffer.
140-
parsePragmasIntoDynFlags
140+
parsePragmasIntoHscEnv
141141
:: HscEnv
142142
-> FilePath
143143
-> Util.StringBuffer
144-
-> IO (Either [FileDiagnostic] ([String], DynFlags))
145-
parsePragmasIntoDynFlags env fp contents = catchSrcErrors dflags0 "pragmas" $ do
144+
-> IO (Either [FileDiagnostic] ([String], HscEnv))
145+
parsePragmasIntoHscEnv env fp contents = catchSrcErrors dflags0 "pragmas" $ do
146146
#if MIN_VERSION_ghc(9,3,0)
147147
let (_warns,opts) = getOptions (initParserOpts dflags0) contents fp
148148
#else
@@ -154,7 +154,7 @@ parsePragmasIntoDynFlags env fp contents = catchSrcErrors dflags0 "pragmas" $ do
154154

155155
(dflags, _, _) <- parseDynamicFilePragma dflags0 opts
156156
hsc_env' <- initializePlugins (hscSetFlags dflags env)
157-
return (map unLoc opts, disableWarningsAsErrors (hsc_dflags hsc_env'))
157+
return (map unLoc opts, hscSetFlags (disableWarningsAsErrors $ hsc_dflags hsc_env') hsc_env')
158158
where dflags0 = hsc_dflags env
159159

160160
-- | Run (unlit) literate haskell preprocessor on a file, or buffer if set

ghcide/src/Development/IDE/Core/Rules.hs

+3-2
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ getParsedModuleRule recorder =
255255
define (cmapWithPrio LogShake recorder) $ \GetParsedModule file -> do
256256
ModSummaryResult{msrModSummary = ms'} <- use_ GetModSummary file
257257
sess <- use_ GhcSession file
258-
let hsc = hscEnv sess
258+
(ms', hsc) <- liftIO $ initPlugins (hscEnv sess) ms'
259259
opt <- getIdeOptions
260260
modify_dflags <- getModifyDynFlags dynFlagsModifyParser
261261
let ms = ms' { ms_hspp_opts = modify_dflags $ ms_hspp_opts ms' }
@@ -329,14 +329,15 @@ getParsedModuleWithCommentsRule recorder =
329329
defineNoDiagnostics (cmapWithPrio LogShake recorder) $ \GetParsedModuleWithComments file -> do
330330
ModSummaryResult{msrModSummary = ms} <- use_ GetModSummary file
331331
sess <- use_ GhcSession file
332+
(ms, hsc) <- liftIO $ initPlugins (hscEnv sess) ms
332333
opt <- getIdeOptions
333334

334335
let ms' = withoutOption Opt_Haddock $ withOption Opt_KeepRawTokenStream ms
335336
modify_dflags <- getModifyDynFlags dynFlagsModifyParser
336337
let ms = ms' { ms_hspp_opts = modify_dflags $ ms_hspp_opts ms' }
337338
reset_ms pm = pm { pm_mod_summary = ms' }
338339

339-
liftIO $ fmap (fmap reset_ms) $ snd <$> getParsedModuleDefinition (hscEnv sess) opt file ms
340+
liftIO $ fmap (fmap reset_ms) $ snd <$> getParsedModuleDefinition hsc opt file ms
340341

341342
getModifyDynFlags :: (DynFlagsModifications -> a) -> Action a
342343
getModifyDynFlags f = do

ghcide/src/Development/IDE/GHC/Compat/Plugins.hs

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module Development.IDE.GHC.Compat.Plugins (
77
PluginWithArgs(..),
88
applyPluginsParsedResultAction,
99
initializePlugins,
10+
initPlugins,
1011

1112
-- * Static plugins
1213
StaticPlugin(..),
@@ -67,6 +68,12 @@ initializePlugins env = do
6768
pure $ hscSetFlags newDf env
6869
#endif
6970

71+
-- Plugins aren't stored in ModSummary anymore since GHC 9.0, but this
72+
-- function still returns it for compatibility with 8.10
73+
initPlugins :: HscEnv -> ModSummary -> IO (ModSummary, HscEnv)
74+
initPlugins session modSummary = do
75+
session1 <- initializePlugins (hscSetFlags (ms_hspp_opts modSummary) session)
76+
return (modSummary{ms_hspp_opts = hsc_dflags session1}, session1)
7077

7178
hsc_static_plugins :: HscEnv -> [StaticPlugin]
7279
#if MIN_VERSION_ghc(9,3,0)

0 commit comments

Comments
 (0)