@@ -69,6 +69,7 @@ import Development.IDE.Types.Location
69
69
import Development.IDE.Types.Options
70
70
import GHC.Check
71
71
import qualified HIE.Bios as HieBios
72
+ import qualified HIE.Bios.Cradle as HieBios
72
73
import HIE.Bios.Environment hiding (getCacheDir )
73
74
import HIE.Bios.Types hiding (Log )
74
75
import qualified HIE.Bios.Types as HieBios
@@ -79,6 +80,8 @@ import Ide.Logger (Pretty (pretty),
79
80
nest ,
80
81
toCologActionWithPrio ,
81
82
vcat , viaShow , (<+>) )
83
+ import Ide.Types (SessionLoadingConfig (.. ),
84
+ sessionLoading )
82
85
import Language.LSP.Protocol.Message
83
86
import Language.LSP.Server
84
87
import System.Directory
@@ -127,6 +130,7 @@ import GHC.Unit.State
127
130
#endif
128
131
129
132
import GHC.ResponseFile
133
+ import qualified Control.Monad.Extra as Extra
130
134
131
135
data Log
132
136
= LogSettingInitialDynFlags
@@ -147,6 +151,7 @@ data Log
147
151
| LogNoneCradleFound FilePath
148
152
| LogNewComponentCache ! (([FileDiagnostic ], Maybe HscEnvEq ), DependencyInfo )
149
153
| LogHieBios HieBios. Log
154
+ | LogSessionLoadingChanged
150
155
deriving instance Show Log
151
156
152
157
instance Pretty Log where
@@ -217,6 +222,8 @@ instance Pretty Log where
217
222
LogNewComponentCache componentCache ->
218
223
" New component cache HscEnvEq:" <+> viaShow componentCache
219
224
LogHieBios msg -> pretty msg
225
+ LogSessionLoadingChanged ->
226
+ " Session Loading Config change, reload the full session."
220
227
221
228
-- | Bump this version number when making changes to the format of the data stored in hiedb
222
229
hiedbDataVersion :: String
@@ -447,6 +454,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
447
454
filesMap <- newVar HM. empty :: IO (Var FilesMap )
448
455
-- Version of the mappings above
449
456
version <- newVar 0
457
+ biosSessionLoadingVar <- newVar Nothing :: IO (Var (Maybe SessionLoadingConfig ))
450
458
let returnWithVersion fun = IdeGhcSession fun <$> liftIO (readVar version)
451
459
-- This caches the mapping from Mod.hs -> hie.yaml
452
460
cradleLoc <- liftIO $ memoIO $ \ v -> do
@@ -461,6 +469,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
461
469
runningCradle <- newVar dummyAs :: IO (Var (Async (IdeResult HscEnvEq ,[FilePath ])))
462
470
463
471
return $ do
472
+ clientConfig <- getClientConfigAction
464
473
extras@ ShakeExtras {restartShakeSession, ideNc, knownTargetsVar, lspEnv
465
474
} <- getShakeExtras
466
475
let invalidateShakeCache :: IO ()
@@ -651,7 +660,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
651
660
withTrace " Load cradle" $ \ addTag -> do
652
661
addTag " file" lfp
653
662
old_files <- readIORef cradle_files
654
- res <- cradleToOptsAndLibDir recorder cradle cfp old_files
663
+ res <- cradleToOptsAndLibDir recorder (sessionLoading clientConfig) cradle cfp old_files
655
664
addTag " result" (show res)
656
665
return res
657
666
@@ -679,11 +688,38 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
679
688
void $ modifyVar' filesMap $ HM. insert ncfp hieYaml
680
689
return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)
681
690
691
+ let
692
+ -- | We allow users to specify a loading strategy.
693
+ -- Check whether this config was changed since the last time we have loaded
694
+ -- a session.
695
+ --
696
+ -- If the loading configuration changed, we likely should restart the session
697
+ -- in its entirety.
698
+ didSessionLoadingConfigChange :: IO Bool
699
+ didSessionLoadingConfigChange = do
700
+ mLoadingConfig <- readVar biosSessionLoadingVar
701
+ case mLoadingConfig of
702
+ Nothing -> do
703
+ writeVar biosSessionLoadingVar (Just (sessionLoading clientConfig))
704
+ pure False
705
+ Just loadingConfig -> do
706
+ writeVar biosSessionLoadingVar (Just (sessionLoading clientConfig))
707
+ pure (loadingConfig /= sessionLoading clientConfig)
708
+
682
709
-- This caches the mapping from hie.yaml + Mod.hs -> [String]
683
710
-- Returns the Ghc session and the cradle dependencies
684
711
let sessionOpts :: (Maybe FilePath , FilePath )
685
712
-> IO (IdeResult HscEnvEq , [FilePath ])
686
713
sessionOpts (hieYaml, file) = do
714
+ Extra. whenM didSessionLoadingConfigChange $ do
715
+ logWith recorder Info LogSessionLoadingChanged
716
+ -- If the dependencies are out of date then clear both caches and start
717
+ -- again.
718
+ modifyVar_ fileToFlags (const (return Map. empty))
719
+ modifyVar_ filesMap (const (return HM. empty))
720
+ -- Don't even keep the name cache, we start from scratch here!
721
+ modifyVar_ hscEnvs (const (return Map. empty))
722
+
687
723
v <- Map. findWithDefault HM. empty hieYaml <$> readVar fileToFlags
688
724
cfp <- makeAbsolute file
689
725
case HM. lookup (toNormalizedFilePath' cfp) v of
@@ -694,6 +730,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
694
730
-- If the dependencies are out of date then clear both caches and start
695
731
-- again.
696
732
modifyVar_ fileToFlags (const (return Map. empty))
733
+ modifyVar_ filesMap (const (return HM. empty))
697
734
-- Keep the same name cache
698
735
modifyVar_ hscEnvs (return . Map. adjust (const [] ) hieYaml )
699
736
consultCradle hieYaml cfp
@@ -713,7 +750,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
713
750
return (([renderPackageSetupException file e], Nothing ), maybe [] pure hieYaml)
714
751
715
752
returnWithVersion $ \ file -> do
716
- opts <- liftIO $ join $ mask_ $ modifyVar runningCradle $ \ as -> do
753
+ opts <- join $ mask_ $ modifyVar runningCradle $ \ as -> do
717
754
-- If the cradle is not finished, then wait for it to finish.
718
755
void $ wait as
719
756
asyncRes <- async $ getOptions file
@@ -723,14 +760,14 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
723
760
-- | Run the specific cradle on a specific FilePath via hie-bios.
724
761
-- This then builds dependencies or whatever based on the cradle, gets the
725
762
-- GHC options/dynflags needed for the session and the GHC library directory
726
- cradleToOptsAndLibDir :: Recorder (WithPriority Log ) -> Cradle Void -> FilePath -> [FilePath ]
763
+ cradleToOptsAndLibDir :: Recorder (WithPriority Log ) -> SessionLoadingConfig -> Cradle Void -> FilePath -> [FilePath ]
727
764
-> IO (Either [CradleError ] (ComponentOptions , FilePath ))
728
- cradleToOptsAndLibDir recorder cradle file old_files = do
765
+ cradleToOptsAndLibDir recorder loadConfig cradle file old_fps = do
729
766
-- let noneCradleFoundMessage :: FilePath -> T.Text
730
767
-- noneCradleFoundMessage f = T.pack $ "none cradle found for " <> f <> ", ignoring the file"
731
768
-- Start off by getting the session options
732
769
logWith recorder Debug $ LogCradle cradle
733
- cradleRes <- HieBios. getCompilerOptions file old_files cradle
770
+ cradleRes <- HieBios. getCompilerOptions file loadStyle cradle
734
771
case cradleRes of
735
772
CradleSuccess r -> do
736
773
-- Now get the GHC lib dir
@@ -748,6 +785,11 @@ cradleToOptsAndLibDir recorder cradle file old_files = do
748
785
logWith recorder Info $ LogNoneCradleFound file
749
786
return (Left [] )
750
787
788
+ where
789
+ loadStyle = case loadConfig of
790
+ SessionLoadSingleComponent -> LoadFile
791
+ SessionLoadMultipleComponents -> LoadWithContext old_fps
792
+
751
793
#if MIN_VERSION_ghc(9,3,0)
752
794
emptyHscEnv :: NameCache -> FilePath -> IO HscEnv
753
795
#else
0 commit comments