@@ -14,7 +14,6 @@ module Development.IDE.Core.FileStore(
1414 VFSHandle ,
1515 makeVFSHandle ,
1616 makeLSPVFSHandle ,
17- isFileOfInterestRule ,
1817 resetFileStore ,
1918 resetInterfaceStore ,
2019 getModificationTimeImpl ,
@@ -38,8 +37,7 @@ import qualified Data.Rope.UTF16 as Rope
3837import qualified Data.Text as T
3938import Data.Time
4039import Data.Time.Clock.POSIX
41- import Development.IDE.Core.OfInterest (OfInterestVar (.. ),
42- getFilesOfInterest )
40+ import Development.IDE.Core.OfInterest (OfInterestVar (.. ))
4341import Development.IDE.Core.RuleTypes
4442import Development.IDE.Core.Shake
4543import Development.IDE.GHC.Orphans ()
@@ -48,6 +46,7 @@ import Development.IDE.Import.DependencyInformation
4846import Development.IDE.Types.Diagnostics
4947import Development.IDE.Types.Location
5048import Development.IDE.Types.Options
49+ import Development.IDE.Types.Shake (SomeShakeValue )
5150import HieDb.Create (deleteMissingRealFiles )
5251import Ide.Plugin.Config (CheckParents (.. ))
5352import System.IO.Error
@@ -63,6 +62,9 @@ import qualified Development.IDE.Types.Logger as L
6362
6463import qualified Data.Binary as B
6564import qualified Data.ByteString.Lazy as LBS
65+ import qualified Data.HashSet as HSet
66+ import Data.IORef.Extra (atomicModifyIORef_ )
67+ import Data.List (foldl' )
6668import Language.LSP.Server hiding
6769 (getVirtualFile )
6870import qualified Language.LSP.Server as LSP
@@ -95,20 +97,6 @@ makeLSPVFSHandle lspEnv = VFSHandle
9597 }
9698
9799
98- isFileOfInterestRule :: Rules ()
99- isFileOfInterestRule = defineEarlyCutoff $ RuleNoDiagnostics $ \ IsFileOfInterest f -> do
100- filesOfInterest <- getFilesOfInterest
101- let foi = maybe NotFOI IsFOI $ f `HM.lookup` filesOfInterest
102- fp = summarize foi
103- res = (Just fp, Just foi)
104- return res
105- where
106- summarize NotFOI = BS. singleton 0
107- summarize (IsFOI OnDisk ) = BS. singleton 1
108- summarize (IsFOI (Modified False )) = BS. singleton 2
109- summarize (IsFOI (Modified True )) = BS. singleton 3
110-
111-
112100getModificationTimeRule :: VFSHandle -> (NormalizedFilePath -> Action Bool ) -> Rules ()
113101getModificationTimeRule vfs isWatched = defineEarlyCutoff $ Rule $ \ (GetModificationTime_ missingFileDiags) file ->
114102 getModificationTimeImpl vfs isWatched missingFileDiags file
@@ -162,20 +150,21 @@ resetInterfaceStore state f = do
162150
163151-- | Reset the GetModificationTime state of watched files
164152resetFileStore :: IdeState -> [FileEvent ] -> IO ()
165- resetFileStore ideState changes = mask $ \ _ ->
166- forM_ changes $ \ (FileEvent uri c) ->
153+ resetFileStore ideState changes = mask $ \ _ -> do
154+ -- we record FOIs document versions in all the stored values
155+ -- so NEVER reset FOIs to avoid losing their versions
156+ OfInterestVar foisVar <- getIdeGlobalExtras (shakeExtras ideState)
157+ fois <- readVar foisVar
158+ forM_ changes $ \ (FileEvent uri c) -> do
167159 case c of
168160 FcChanged
169161 | Just f <- uriToFilePath uri
170- -> do
171- -- we record FOIs document versions in all the stored values
172- -- so NEVER reset FOIs to avoid losing their versions
173- OfInterestVar foisVar <- getIdeGlobalExtras (shakeExtras ideState)
174- fois <- readVar foisVar
175- unless (HM. member (toNormalizedFilePath f) fois) $ do
176- deleteValue (shakeExtras ideState) GetModificationTime (toNormalizedFilePath' f)
162+ , nfp <- toNormalizedFilePath f
163+ , not $ HM. member nfp fois
164+ -> deleteValue (shakeExtras ideState) GetModificationTime nfp
177165 _ -> pure ()
178166
167+
179168-- Dir.getModificationTime is surprisingly slow since it performs
180169-- a ton of conversions. Since we do not actually care about
181170-- the format of the time, we can get away with something cheaper.
@@ -241,7 +230,6 @@ fileStoreRules vfs isWatched = do
241230 addIdeGlobal vfs
242231 getModificationTimeRule vfs isWatched
243232 getFileContentsRule vfs
244- isFileOfInterestRule
245233
246234-- | Note that some buffer for a specific file has been modified but not
247235-- with what changes.
@@ -259,7 +247,8 @@ setFileModified state saved nfp = do
259247 VFSHandle {.. } <- getIdeGlobalState state
260248 when (isJust setVirtualFileContents) $
261249 fail " setFileModified can't be called on this type of VFSHandle"
262- shakeRestart state []
250+ recordDirtyKeys (shakeExtras state) GetModificationTime [nfp]
251+ restartShakeSession (shakeExtras state) []
263252 when checkParents $
264253 typecheckParents state nfp
265254
@@ -279,14 +268,17 @@ typecheckParentsAction nfp = do
279268 `catch` \ (e :: SomeException ) -> log (show e)
280269 () <$ uses GetModIface rs
281270
282- -- | Note that some buffer somewhere has been modified, but don't say what.
271+ -- | Note that some keys have been modified and restart the session
283272-- Only valid if the virtual file system was initialised by LSP, as that
284273-- independently tracks which files are modified.
285- setSomethingModified :: IdeState -> IO ()
286- setSomethingModified state = do
274+ setSomethingModified :: IdeState -> [ SomeShakeValue ] -> IO ()
275+ setSomethingModified state keys = do
287276 VFSHandle {.. } <- getIdeGlobalState state
288277 when (isJust setVirtualFileContents) $
289278 fail " setSomethingModified can't be called on this type of VFSHandle"
290279 -- Update database to remove any files that might have been renamed/deleted
291280 atomically $ writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) deleteMissingRealFiles
292- void $ shakeRestart state []
281+
282+ atomicModifyIORef_ (dirtyKeys $ shakeExtras state) $ \ x ->
283+ foldl' (flip HSet. insert) x keys
284+ void $ restartShakeSession (shakeExtras state) []
0 commit comments