@@ -25,7 +25,7 @@ import Control.Concurrent.Async
25
25
import Control.Concurrent.Strict
26
26
import Control.Exception.Safe as Safe
27
27
import Control.Monad
28
- import Control.Monad.Extra
28
+ import Control.Monad.Extra as Extra
29
29
import Control.Monad.IO.Class
30
30
import qualified Crypto.Hash.SHA1 as H
31
31
import Data.Aeson hiding (Error )
@@ -52,13 +52,13 @@ import Development.IDE.Core.RuleTypes
52
52
import Development.IDE.Core.Shake hiding (Log , Priority ,
53
53
knownTargets , withHieDb )
54
54
import qualified Development.IDE.GHC.Compat as Compat
55
- import qualified Development.IDE.GHC.Compat.Util as Compat
56
55
import Development.IDE.GHC.Compat.Core hiding (Target ,
57
56
TargetFile , TargetModule ,
58
57
Var , Warning , getOptions )
59
58
import qualified Development.IDE.GHC.Compat.Core as GHC
60
59
import Development.IDE.GHC.Compat.Env hiding (Logger )
61
60
import Development.IDE.GHC.Compat.Units (UnitId )
61
+ import qualified Development.IDE.GHC.Compat.Util as Compat
62
62
import Development.IDE.GHC.Util
63
63
import Development.IDE.Graph (Action )
64
64
import Development.IDE.Session.VersionCheck
@@ -70,6 +70,7 @@ import Development.IDE.Types.Location
70
70
import Development.IDE.Types.Options
71
71
import GHC.Check
72
72
import qualified HIE.Bios as HieBios
73
+ import qualified HIE.Bios.Cradle as HieBios
73
74
import HIE.Bios.Environment hiding (getCacheDir )
74
75
import HIE.Bios.Types hiding (Log )
75
76
import qualified HIE.Bios.Types as HieBios
@@ -80,6 +81,8 @@ import Ide.Logger (Pretty (pretty),
80
81
nest ,
81
82
toCologActionWithPrio ,
82
83
vcat , viaShow , (<+>) )
84
+ import Ide.Types (SessionLoadingPreferenceConfig (.. ),
85
+ sessionLoading )
83
86
import Language.LSP.Protocol.Message
84
87
import Language.LSP.Server
85
88
import System.Directory
@@ -123,7 +126,8 @@ import GHC.Data.Bag
123
126
import GHC.Driver.Env (hsc_all_home_unit_ids )
124
127
import GHC.Driver.Errors.Types
125
128
import GHC.Driver.Make (checkHomeUnitsClosed )
126
- import GHC.Types.Error (errMsgDiagnostic , singleMessage )
129
+ import GHC.Types.Error (errMsgDiagnostic ,
130
+ singleMessage )
127
131
import GHC.Unit.State
128
132
#endif
129
133
@@ -149,6 +153,7 @@ data Log
149
153
| LogNoneCradleFound FilePath
150
154
| LogNewComponentCache ! (([FileDiagnostic ], Maybe HscEnvEq ), DependencyInfo )
151
155
| LogHieBios HieBios. Log
156
+ | LogSessionLoadingChanged
152
157
deriving instance Show Log
153
158
154
159
instance Pretty Log where
@@ -219,6 +224,8 @@ instance Pretty Log where
219
224
LogNewComponentCache componentCache ->
220
225
" New component cache HscEnvEq:" <+> viaShow componentCache
221
226
LogHieBios msg -> pretty msg
227
+ LogSessionLoadingChanged ->
228
+ " Session Loading config changed, reloading the full session."
222
229
223
230
-- | Bump this version number when making changes to the format of the data stored in hiedb
224
231
hiedbDataVersion :: String
@@ -449,6 +456,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
449
456
filesMap <- newVar HM. empty :: IO (Var FilesMap )
450
457
-- Version of the mappings above
451
458
version <- newVar 0
459
+ biosSessionLoadingVar <- newVar Nothing :: IO (Var (Maybe SessionLoadingPreferenceConfig ))
452
460
let returnWithVersion fun = IdeGhcSession fun <$> liftIO (readVar version)
453
461
-- This caches the mapping from Mod.hs -> hie.yaml
454
462
cradleLoc <- liftIO $ memoIO $ \ v -> do
@@ -463,6 +471,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
463
471
runningCradle <- newVar dummyAs :: IO (Var (Async (IdeResult HscEnvEq ,[FilePath ])))
464
472
465
473
return $ do
474
+ clientConfig <- getClientConfigAction
466
475
extras@ ShakeExtras {restartShakeSession, ideNc, knownTargetsVar, lspEnv
467
476
} <- getShakeExtras
468
477
let invalidateShakeCache :: IO ()
@@ -653,7 +662,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
653
662
withTrace " Load cradle" $ \ addTag -> do
654
663
addTag " file" lfp
655
664
old_files <- readIORef cradle_files
656
- res <- cradleToOptsAndLibDir recorder cradle cfp old_files
665
+ res <- cradleToOptsAndLibDir recorder (sessionLoading clientConfig) cradle cfp old_files
657
666
addTag " result" (show res)
658
667
return res
659
668
@@ -681,11 +690,38 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
681
690
void $ modifyVar' filesMap $ HM. insert ncfp hieYaml
682
691
return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)
683
692
693
+ let
694
+ -- | We allow users to specify a loading strategy.
695
+ -- Check whether this config was changed since the last time we have loaded
696
+ -- a session.
697
+ --
698
+ -- If the loading configuration changed, we likely should restart the session
699
+ -- in its entirety.
700
+ didSessionLoadingPreferenceConfigChange :: IO Bool
701
+ didSessionLoadingPreferenceConfigChange = do
702
+ mLoadingConfig <- readVar biosSessionLoadingVar
703
+ case mLoadingConfig of
704
+ Nothing -> do
705
+ writeVar biosSessionLoadingVar (Just (sessionLoading clientConfig))
706
+ pure False
707
+ Just loadingConfig -> do
708
+ writeVar biosSessionLoadingVar (Just (sessionLoading clientConfig))
709
+ pure (loadingConfig /= sessionLoading clientConfig)
710
+
684
711
-- This caches the mapping from hie.yaml + Mod.hs -> [String]
685
712
-- Returns the Ghc session and the cradle dependencies
686
713
let sessionOpts :: (Maybe FilePath , FilePath )
687
714
-> IO (IdeResult HscEnvEq , [FilePath ])
688
715
sessionOpts (hieYaml, file) = do
716
+ Extra. whenM didSessionLoadingPreferenceConfigChange $ do
717
+ logWith recorder Info LogSessionLoadingChanged
718
+ -- If the dependencies are out of date then clear both caches and start
719
+ -- again.
720
+ modifyVar_ fileToFlags (const (return Map. empty))
721
+ modifyVar_ filesMap (const (return HM. empty))
722
+ -- Don't even keep the name cache, we start from scratch here!
723
+ modifyVar_ hscEnvs (const (return Map. empty))
724
+
689
725
v <- Map. findWithDefault HM. empty hieYaml <$> readVar fileToFlags
690
726
cfp <- makeAbsolute file
691
727
case HM. lookup (toNormalizedFilePath' cfp) v of
@@ -696,6 +732,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
696
732
-- If the dependencies are out of date then clear both caches and start
697
733
-- again.
698
734
modifyVar_ fileToFlags (const (return Map. empty))
735
+ modifyVar_ filesMap (const (return HM. empty))
699
736
-- Keep the same name cache
700
737
modifyVar_ hscEnvs (return . Map. adjust (const [] ) hieYaml )
701
738
consultCradle hieYaml cfp
@@ -715,7 +752,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
715
752
return (([renderPackageSetupException file e], Nothing ), maybe [] pure hieYaml)
716
753
717
754
returnWithVersion $ \ file -> do
718
- opts <- liftIO $ join $ mask_ $ modifyVar runningCradle $ \ as -> do
755
+ opts <- join $ mask_ $ modifyVar runningCradle $ \ as -> do
719
756
-- If the cradle is not finished, then wait for it to finish.
720
757
void $ wait as
721
758
asyncRes <- async $ getOptions file
@@ -725,14 +762,14 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
725
762
-- | Run the specific cradle on a specific FilePath via hie-bios.
726
763
-- This then builds dependencies or whatever based on the cradle, gets the
727
764
-- GHC options/dynflags needed for the session and the GHC library directory
728
- cradleToOptsAndLibDir :: Recorder (WithPriority Log ) -> Cradle Void -> FilePath -> [FilePath ]
765
+ cradleToOptsAndLibDir :: Recorder (WithPriority Log ) -> SessionLoadingPreferenceConfig -> Cradle Void -> FilePath -> [FilePath ]
729
766
-> IO (Either [CradleError ] (ComponentOptions , FilePath ))
730
- cradleToOptsAndLibDir recorder cradle file old_files = do
767
+ cradleToOptsAndLibDir recorder loadConfig cradle file old_fps = do
731
768
-- let noneCradleFoundMessage :: FilePath -> T.Text
732
769
-- noneCradleFoundMessage f = T.pack $ "none cradle found for " <> f <> ", ignoring the file"
733
770
-- Start off by getting the session options
734
771
logWith recorder Debug $ LogCradle cradle
735
- cradleRes <- HieBios. getCompilerOptions file old_files cradle
772
+ cradleRes <- HieBios. getCompilerOptions file loadStyle cradle
736
773
case cradleRes of
737
774
CradleSuccess r -> do
738
775
-- Now get the GHC lib dir
@@ -750,6 +787,11 @@ cradleToOptsAndLibDir recorder cradle file old_files = do
750
787
logWith recorder Info $ LogNoneCradleFound file
751
788
return (Left [] )
752
789
790
+ where
791
+ loadStyle = case loadConfig of
792
+ PreferSingleComponentLoading -> LoadFile
793
+ PreferMultiComponentLoading -> LoadWithContext old_fps
794
+
753
795
#if MIN_VERSION_ghc(9,3,0)
754
796
emptyHscEnv :: NameCache -> FilePath -> IO HscEnv
755
797
#else
@@ -1150,7 +1192,7 @@ setOptions cfp (ComponentOptions theOpts compRoot _) dflags = do
1150
1192
-- component to be created. In case the cradle doesn't list all the targets for
1151
1193
-- the component, in which case things will be horribly broken anyway.
1152
1194
--
1153
- -- When we have a single component that is caused to be loaded due to a
1195
+ -- When we have a singleComponent that is caused to be loaded due to a
1154
1196
-- file, we assume the file is part of that component. This is useful
1155
1197
-- for bare GHC sessions, such as many of the ones used in the testsuite
1156
1198
--
0 commit comments