@@ -28,7 +28,7 @@ import Control.Monad
2828import Control.Monad.Extra as Extra
2929import Control.Monad.IO.Class
3030import qualified Crypto.Hash.SHA1 as H
31- import Data.Aeson hiding (Error )
31+ -- import Data.Aeson hiding (Error)
3232import Data.Bifunctor
3333import qualified Data.ByteString.Base16 as B16
3434import qualified Data.ByteString.Char8 as B
@@ -108,7 +108,8 @@ import qualified Data.HashSet as Set
108108import Database.SQLite.Simple
109109import Development.IDE.Core.Tracing (withTrace )
110110import Development.IDE.Session.Diagnostics (renderCradleError )
111- import Development.IDE.Types.Shake (WithHieDb , toNoFileKey )
111+ import Development.IDE.Types.Shake (Key , WithHieDb ,
112+ toNoFileKey )
112113import HieDb.Create
113114import HieDb.Types
114115import HieDb.Utils
@@ -134,6 +135,7 @@ import GHC.Unit.State
134135import Language.LSP.Protocol.Types (NormalizedUri (NormalizedUri ),
135136 toNormalizedFilePath )
136137#endif
138+ import Data.Aeson (ToJSON (toJSON ))
137139import Development.IDE (RuleResult )
138140import qualified Development.IDE.Core.Shake as SHake
139141
@@ -449,7 +451,7 @@ getHieDbLoc dir = do
449451loadSession :: Recorder (WithPriority Log ) -> FilePath -> IO (Rules () , Action IdeGhcSession )
450452loadSession recorder = loadSessionWithOptions recorder def
451453
452- type instance RuleResult HieYaml = (IdeResult HscEnvEq , [FilePath ])
454+ type instance RuleResult HieYaml = (IdeResult HscEnvEq , [FilePath ], [ NormalizedFilePath ], [ Key ] )
453455
454456loadSessionWithOptions :: Recorder (WithPriority Log ) -> SessionLoadingOptions -> FilePath -> IO (Rules () , Action IdeGhcSession )
455457loadSessionWithOptions recorder SessionLoadingOptions {.. } rootDir = do
@@ -470,6 +472,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
470472
471473 -- version of the whole rebuild
472474 cacheVersion <- newVar 0
475+ lastRestartVersion <- newVar 0
473476 cradleLock <- newMVar ()
474477-- putMVar cradleLock ()
475478 biosSessionLoadingVar <- newVar Nothing :: IO (Var (Maybe SessionLoadingPreferenceConfig ))
@@ -502,11 +505,20 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
502505 liftIO $ writeVar biosSessionLoadingVar (Just (sessionLoading clientConfig))
503506 pure (loadingConfig /= sessionLoading clientConfig)
504507
508+ let typecheckAll cfps' =
509+ mkDelayedAction " InitialLoad" Debug $ void $ do
510+ mmt <- uses GetModificationTime cfps'
511+ let cs_exist = catMaybes (zipWith (<$) cfps' mmt)
512+ modIfaces <- uses GetModIface cs_exist
513+ -- update exports map
514+ shakeExtras <- getShakeExtras
515+ let ! exportsMap' = createExportsMap $ mapMaybe (fmap hirModIface) modIfaces
516+ liftIO $ atomically $ modifyTVar' (exportsMap shakeExtras) (exportsMap' <> )
505517
506- let session :: (Maybe FilePath , NormalizedFilePath , ComponentOptions , FilePath )
507- -> Action (IdeResult HscEnvEq ,[FilePath ])
508- session args@ (hieYaml, _cfp, _opts, _libDir) = do
509- ShakeExtras {restartShakeSession, ideNc} <- getShakeExtras
518+ -- let session :: (Maybe FilePath, NormalizedFilePath, ComponentOptions, FilePath)
519+ -- -> Action (IdeResult HscEnvEq,[FilePath])
520+ let session args@ (hieYaml, _cfp, _opts, _libDir) = do
521+ ShakeExtras {ideNc} <- getShakeExtras
510522 IdeOptions { optCheckProject = getCheckProject , optExtensions } <- getIdeOptions
511523 (new_deps, old_deps) <- packageSetup args
512524
@@ -542,24 +554,9 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
542554 keys1 <- extendKnownTargets all_targets
543555
544556 -- Typecheck all files in the project on startup
545- checkProject <- liftIO getCheckProject
546557 cfps' <- liftIO $ filterM (IO. doesFileExist . fromNormalizedFilePath) (concatMap targetLocations all_targets)
547- let typeCheckAll = if null new_deps || not checkProject
548- then []
549- else return $
550- mkDelayedAction " InitialLoad" Debug $ void $ do
551- mmt <- uses GetModificationTime cfps'
552- let cs_exist = catMaybes (zipWith (<$) cfps' mmt)
553- modIfaces <- uses GetModIface cs_exist
554- -- update exports map
555- shakeExtras <- getShakeExtras
556- let ! exportsMap' = createExportsMap $ mapMaybe (fmap hirModIface) modIfaces
557- liftIO $ atomically $ modifyTVar' (exportsMap shakeExtras) (exportsMap' <> )
558- -- todo this should be moving out of the session function
559- restart <- liftIO $ async $ do
560- restartShakeSession VFSUnmodified " new component" typeCheckAll $ pure [keys1, keys2]
561- UnliftIO. wait restart
562- return $ second Map. keys this_options
558+ let (x, y) = this_options
559+ return $ (x, Map. keys y, cfps', [keys1, keys2])
563560
564561 -- Create a new HscEnv from a hieYaml root and a set of options
565562 packageSetup :: (Maybe FilePath , NormalizedFilePath , ComponentOptions , FilePath )
@@ -664,7 +661,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
664661
665662 -- -- This caches the mapping from hie.yaml + Mod.hs -> [String]
666663 -- -- Returns the Ghc session and the cradle dependencies
667- consultCradle :: NormalizedFilePath -> Action (IdeResult HscEnvEq , [FilePath ])
664+ -- consultCradle :: NormalizedFilePath -> Action (IdeResult HscEnvEq, [FilePath])
668665 consultCradle cfp = do
669666 clientConfig <- getClientConfigAction
670667 ShakeExtras {lspEnv } <- getShakeExtras
@@ -701,7 +698,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
701698 InstallationNotFound {.. } ->
702699 error $ " GHC installation not found in libdir: " <> libdir
703700 InstallationMismatch {.. } ->
704- return (([renderPackageSetupException cfp GhcVersionMismatch {.. }], Nothing ),[] )
701+ return (([renderPackageSetupException cfp GhcVersionMismatch {.. }], Nothing ),[] , [] , [] )
705702 InstallationChecked _compileTime _ghcLibCheck -> do
706703 liftIO $ atomicModifyIORef' cradle_files (\ xs -> (fromNormalizedFilePath cfp: xs,() ))
707704 session (hieYaml, cfp, opts, libDir)
@@ -712,7 +709,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
712709 liftIO $ void $ modifyVar' fileToFlags $
713710 Map. insertWith HM. union hieYaml (HM. singleton cfp (res, dep_info))
714711 liftIO $ void $ modifyVar' filesMap $ HM. insert cfp hieYaml
715- return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)
712+ return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err, [] , [] )
716713
717714 sessionCacheVersionRule :: Rules ()
718715 sessionCacheVersionRule = defineNoFile (cmapWithPrio LogShake recorder) $ \ SessionCacheVersion -> do
@@ -737,7 +734,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
737734 -- install cache version check to avoid recompilation
738735 _ <- useNoFile_ SessionCacheVersion
739736 catchError file hieYaml $ do
740- result@ (_, deps) <- consultCradle file
737+ result@ (_, deps, _, _ ) <- consultCradle file
741738 -- add the deps to the Shake graph
742739 mapM_ addDependency deps
743740 return $ Just result
@@ -746,7 +743,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
746743 f `Safe.catch` \ e -> do
747744 -- install dep so it can be recorvered
748745 mapM_ addDependency hieYaml
749- return $ Just (([renderPackageSetupException file e], Nothing ), maybe [] pure hieYaml)
746+ return $ Just (([renderPackageSetupException file e], Nothing ), maybe [] pure hieYaml, [] , [] )
750747 addDependency fp = do
751748 -- VSCode uses absolute paths in its filewatch notifications
752749 let nfp = toNormalizedFilePath' fp
@@ -770,9 +767,20 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
770767 -- at a time. Therefore the IORef contains the currently running cradle, if we try
771768 -- to get some more options then we wait for the currently running action to finish
772769 -- before attempting to do so.
770+ ShakeExtras {restartShakeSession } <- getShakeExtras
771+ IdeOptions { optCheckProject = getCheckProject} <- getIdeOptions
773772 returnWithVersion $ \ file -> do
774- opts <- use_ HieYaml file
775- pure $ (fmap . fmap ) toAbsolutePath opts)
773+ _opts@ (a, b, files, keys) <- use_ HieYaml file
774+ -- wait for the restart
775+ lastRestartVersion' <- liftIO $ readVar lastRestartVersion
776+ cacheVersion' <- liftIO $ readVar cacheVersion
777+ liftIO $ when ((notNull files || notNull keys) && lastRestartVersion' /= cacheVersion') $ do
778+ liftIO $ writeVar lastRestartVersion cacheVersion'
779+ checkProject <- getCheckProject
780+ -- think of not to restart a second time
781+ async <- UnliftIO. async $ restartShakeSession VFSUnmodified " new component" (if checkProject then return (typecheckAll files) else mempty ) $ pure keys
782+ UnliftIO. wait async
783+ pure $ (fmap . fmap ) toAbsolutePath (a, b))
776784
777785
778786-- | Run the specific cradle on a specific FilePath via hie-bios.
0 commit comments