@@ -14,7 +14,6 @@ module Development.IDE.Core.FileStore(
1414 VFSHandle ,
1515 makeVFSHandle ,
1616 makeLSPVFSHandle ,
17- isFileOfInterestRule ,
1817 resetFileStore ,
1918 resetInterfaceStore ,
2019 getModificationTimeImpl ,
@@ -40,8 +39,7 @@ import qualified Data.Rope.UTF16 as Rope
4039import qualified Data.Text as T
4140import Data.Time
4241import Data.Time.Clock.POSIX
43- import Development.IDE.Core.OfInterest (OfInterestVar (.. ),
44- getFilesOfInterest )
42+ import Development.IDE.Core.OfInterest (OfInterestVar (.. ))
4543import Development.IDE.Core.RuleTypes
4644import Development.IDE.Core.Shake
4745import Development.IDE.GHC.Orphans ()
@@ -50,6 +48,7 @@ import Development.IDE.Import.DependencyInformation
5048import Development.IDE.Types.Diagnostics
5149import Development.IDE.Types.Location
5250import Development.IDE.Types.Options
51+ import Development.IDE.Types.Shake (SomeShakeValue )
5352import HieDb.Create (deleteMissingRealFiles )
5453import Ide.Plugin.Config (CheckParents (.. ),
5554 Config )
@@ -66,6 +65,9 @@ import qualified Development.IDE.Types.Logger as L
6665
6766import qualified Data.Binary as B
6867import qualified Data.ByteString.Lazy as LBS
68+ import qualified Data.HashSet as HSet
69+ import Data.IORef.Extra (atomicModifyIORef_ )
70+ import Data.List (foldl' )
6971import qualified Data.Text as Text
7072import Development.IDE.Core.IdeConfiguration (isWorkspaceFile )
7173import Language.LSP.Server hiding
@@ -117,19 +119,6 @@ addWatchedFileRule isWatched = defineNoDiagnostics $ \AddWatchedFile f -> do
117119 registerFileWatches [fromNormalizedFilePath f]
118120 Nothing -> pure $ Just False
119121
120- isFileOfInterestRule :: Rules ()
121- isFileOfInterestRule = defineEarlyCutoff $ RuleNoDiagnostics $ \ IsFileOfInterest f -> do
122- filesOfInterest <- getFilesOfInterest
123- let foi = maybe NotFOI IsFOI $ f `HM.lookup` filesOfInterest
124- fp = summarize foi
125- res = (Just fp, Just foi)
126- return res
127- where
128- summarize NotFOI = BS. singleton 0
129- summarize (IsFOI OnDisk ) = BS. singleton 1
130- summarize (IsFOI (Modified False )) = BS. singleton 2
131- summarize (IsFOI (Modified True )) = BS. singleton 3
132-
133122
134123getModificationTimeRule :: VFSHandle -> Rules ()
135124getModificationTimeRule vfs = defineEarlyCutoff $ Rule $ \ (GetModificationTime_ missingFileDiags) file ->
@@ -183,20 +172,21 @@ resetInterfaceStore state f = do
183172
184173-- | Reset the GetModificationTime state of watched files
185174resetFileStore :: IdeState -> [FileEvent ] -> IO ()
186- resetFileStore ideState changes = mask $ \ _ ->
187- forM_ changes $ \ (FileEvent uri c) ->
175+ resetFileStore ideState changes = mask $ \ _ -> do
176+ -- we record FOIs document versions in all the stored values
177+ -- so NEVER reset FOIs to avoid losing their versions
178+ OfInterestVar foisVar <- getIdeGlobalExtras (shakeExtras ideState)
179+ fois <- readVar foisVar
180+ forM_ changes $ \ (FileEvent uri c) -> do
188181 case c of
189182 FcChanged
190183 | Just f <- uriToFilePath uri
191- -> do
192- -- we record FOIs document versions in all the stored values
193- -- so NEVER reset FOIs to avoid losing their versions
194- OfInterestVar foisVar <- getIdeGlobalExtras (shakeExtras ideState)
195- fois <- readVar foisVar
196- unless (HM. member (toNormalizedFilePath f) fois) $ do
197- deleteValue (shakeExtras ideState) GetModificationTime (toNormalizedFilePath' f)
184+ , nfp <- toNormalizedFilePath f
185+ , not $ HM. member nfp fois
186+ -> deleteValue (shakeExtras ideState) GetModificationTime nfp
198187 _ -> pure ()
199188
189+
200190-- Dir.getModificationTime is surprisingly slow since it performs
201191-- a ton of conversions. Since we do not actually care about
202192-- the format of the time, we can get away with something cheaper.
@@ -262,7 +252,6 @@ fileStoreRules vfs isWatched = do
262252 addIdeGlobal vfs
263253 getModificationTimeRule vfs
264254 getFileContentsRule vfs
265- isFileOfInterestRule
266255 addWatchedFileRule isWatched
267256
268257-- | Note that some buffer for a specific file has been modified but not
@@ -281,7 +270,8 @@ setFileModified state saved nfp = do
281270 VFSHandle {.. } <- getIdeGlobalState state
282271 when (isJust setVirtualFileContents) $
283272 fail " setFileModified can't be called on this type of VFSHandle"
284- shakeRestart state []
273+ recordDirtyKeys (shakeExtras state) GetModificationTime [nfp]
274+ restartShakeSession (shakeExtras state) []
285275 when checkParents $
286276 typecheckParents state nfp
287277
@@ -301,17 +291,19 @@ typecheckParentsAction nfp = do
301291 `catch` \ (e :: SomeException ) -> log (show e)
302292 () <$ uses GetModIface rs
303293
304- -- | Note that some buffer somewhere has been modified, but don't say what.
294+ -- | Note that some keys have been modified and restart the session
305295-- Only valid if the virtual file system was initialised by LSP, as that
306296-- independently tracks which files are modified.
307- setSomethingModified :: IdeState -> IO ()
308- setSomethingModified state = do
297+ setSomethingModified :: IdeState -> [ SomeShakeValue ] -> IO ()
298+ setSomethingModified state keys = do
309299 VFSHandle {.. } <- getIdeGlobalState state
310300 when (isJust setVirtualFileContents) $
311301 fail " setSomethingModified can't be called on this type of VFSHandle"
312302 -- Update database to remove any files that might have been renamed/deleted
313303 atomically $ writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) deleteMissingRealFiles
314- void $ shakeRestart state []
304+ atomicModifyIORef_ (dirtyKeys $ shakeExtras state) $ \ x ->
305+ foldl' (flip HSet. insert) x keys
306+ void $ restartShakeSession (shakeExtras state) []
315307
316308registerFileWatches :: [String ] -> LSP. LspT Config IO Bool
317309registerFileWatches globs = do
@@ -338,7 +330,7 @@ registerFileWatches globs = do
338330 -- support that: https://github.com/bubba/lsp-test/issues/77
339331 watchers = [ watcher (Text. pack glob) | glob <- globs ]
340332
341- void $ LSP. sendRequest LSP. SClientRegisterCapability regParams (const $ pure () )
333+ void $ LSP. sendRequest LSP. SClientRegisterCapability regParams (const $ pure () ) -- TODO handle response
342334 return True
343335 else return False
344336
0 commit comments