@@ -28,7 +28,7 @@ import Control.Monad
28
28
import Control.Monad.Extra as Extra
29
29
import Control.Monad.IO.Class
30
30
import qualified Crypto.Hash.SHA1 as H
31
- import Data.Aeson hiding (Error )
31
+ -- import Data.Aeson hiding (Error)
32
32
import Data.Bifunctor
33
33
import qualified Data.ByteString.Base16 as B16
34
34
import qualified Data.ByteString.Char8 as B
@@ -108,7 +108,8 @@ import qualified Data.HashSet as Set
108
108
import Database.SQLite.Simple
109
109
import Development.IDE.Core.Tracing (withTrace )
110
110
import Development.IDE.Session.Diagnostics (renderCradleError )
111
- import Development.IDE.Types.Shake (WithHieDb , toNoFileKey )
111
+ import Development.IDE.Types.Shake (Key , WithHieDb ,
112
+ toNoFileKey )
112
113
import HieDb.Create
113
114
import HieDb.Types
114
115
import HieDb.Utils
@@ -134,6 +135,7 @@ import GHC.Unit.State
134
135
import Language.LSP.Protocol.Types (NormalizedUri (NormalizedUri ),
135
136
toNormalizedFilePath )
136
137
#endif
138
+ import Data.Aeson (ToJSON (toJSON ))
137
139
import Development.IDE (RuleResult )
138
140
import qualified Development.IDE.Core.Shake as SHake
139
141
@@ -449,7 +451,7 @@ getHieDbLoc dir = do
449
451
loadSession :: Recorder (WithPriority Log ) -> FilePath -> IO (Rules () , Action IdeGhcSession )
450
452
loadSession recorder = loadSessionWithOptions recorder def
451
453
452
- type instance RuleResult HieYaml = (IdeResult HscEnvEq , [FilePath ])
454
+ type instance RuleResult HieYaml = (IdeResult HscEnvEq , [FilePath ], [ NormalizedFilePath ], [ Key ] )
453
455
454
456
loadSessionWithOptions :: Recorder (WithPriority Log ) -> SessionLoadingOptions -> FilePath -> IO (Rules () , Action IdeGhcSession )
455
457
loadSessionWithOptions recorder SessionLoadingOptions {.. } rootDir = do
@@ -470,6 +472,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
470
472
471
473
-- version of the whole rebuild
472
474
cacheVersion <- newVar 0
475
+ lastRestartVersion <- newVar 0
473
476
cradleLock <- newMVar ()
474
477
-- putMVar cradleLock ()
475
478
biosSessionLoadingVar <- newVar Nothing :: IO (Var (Maybe SessionLoadingPreferenceConfig ))
@@ -502,11 +505,20 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
502
505
liftIO $ writeVar biosSessionLoadingVar (Just (sessionLoading clientConfig))
503
506
pure (loadingConfig /= sessionLoading clientConfig)
504
507
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' <> )
505
517
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
510
522
IdeOptions { optCheckProject = getCheckProject , optExtensions } <- getIdeOptions
511
523
(new_deps, old_deps) <- packageSetup args
512
524
@@ -542,24 +554,9 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
542
554
keys1 <- extendKnownTargets all_targets
543
555
544
556
-- Typecheck all files in the project on startup
545
- checkProject <- liftIO getCheckProject
546
557
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])
563
560
564
561
-- Create a new HscEnv from a hieYaml root and a set of options
565
562
packageSetup :: (Maybe FilePath , NormalizedFilePath , ComponentOptions , FilePath )
@@ -664,7 +661,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
664
661
665
662
-- -- This caches the mapping from hie.yaml + Mod.hs -> [String]
666
663
-- -- Returns the Ghc session and the cradle dependencies
667
- consultCradle :: NormalizedFilePath -> Action (IdeResult HscEnvEq , [FilePath ])
664
+ -- consultCradle :: NormalizedFilePath -> Action (IdeResult HscEnvEq, [FilePath])
668
665
consultCradle cfp = do
669
666
clientConfig <- getClientConfigAction
670
667
ShakeExtras {lspEnv } <- getShakeExtras
@@ -701,7 +698,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
701
698
InstallationNotFound {.. } ->
702
699
error $ " GHC installation not found in libdir: " <> libdir
703
700
InstallationMismatch {.. } ->
704
- return (([renderPackageSetupException cfp GhcVersionMismatch {.. }], Nothing ),[] )
701
+ return (([renderPackageSetupException cfp GhcVersionMismatch {.. }], Nothing ),[] , [] , [] )
705
702
InstallationChecked _compileTime _ghcLibCheck -> do
706
703
liftIO $ atomicModifyIORef' cradle_files (\ xs -> (fromNormalizedFilePath cfp: xs,() ))
707
704
session (hieYaml, cfp, opts, libDir)
@@ -712,7 +709,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
712
709
liftIO $ void $ modifyVar' fileToFlags $
713
710
Map. insertWith HM. union hieYaml (HM. singleton cfp (res, dep_info))
714
711
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, [] , [] )
716
713
717
714
sessionCacheVersionRule :: Rules ()
718
715
sessionCacheVersionRule = defineNoFile (cmapWithPrio LogShake recorder) $ \ SessionCacheVersion -> do
@@ -737,7 +734,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
737
734
-- install cache version check to avoid recompilation
738
735
_ <- useNoFile_ SessionCacheVersion
739
736
catchError file hieYaml $ do
740
- result@ (_, deps) <- consultCradle file
737
+ result@ (_, deps, _, _ ) <- consultCradle file
741
738
-- add the deps to the Shake graph
742
739
mapM_ addDependency deps
743
740
return $ Just result
@@ -746,7 +743,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
746
743
f `Safe.catch` \ e -> do
747
744
-- install dep so it can be recorvered
748
745
mapM_ addDependency hieYaml
749
- return $ Just (([renderPackageSetupException file e], Nothing ), maybe [] pure hieYaml)
746
+ return $ Just (([renderPackageSetupException file e], Nothing ), maybe [] pure hieYaml, [] , [] )
750
747
addDependency fp = do
751
748
-- VSCode uses absolute paths in its filewatch notifications
752
749
let nfp = toNormalizedFilePath' fp
@@ -770,9 +767,20 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
770
767
-- at a time. Therefore the IORef contains the currently running cradle, if we try
771
768
-- to get some more options then we wait for the currently running action to finish
772
769
-- before attempting to do so.
770
+ ShakeExtras {restartShakeSession } <- getShakeExtras
771
+ IdeOptions { optCheckProject = getCheckProject} <- getIdeOptions
773
772
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))
776
784
777
785
778
786
-- | Run the specific cradle on a specific FilePath via hie-bios.
0 commit comments