@@ -14,7 +14,6 @@ module Development.IDE.Core.FileStore(
14
14
VFSHandle ,
15
15
makeVFSHandle ,
16
16
makeLSPVFSHandle ,
17
- isFileOfInterestRule ,
18
17
resetFileStore ,
19
18
resetInterfaceStore ,
20
19
getModificationTimeImpl ,
@@ -38,8 +37,7 @@ import qualified Data.Rope.UTF16 as Rope
38
37
import qualified Data.Text as T
39
38
import Data.Time
40
39
import Data.Time.Clock.POSIX
41
- import Development.IDE.Core.OfInterest (OfInterestVar (.. ),
42
- getFilesOfInterest )
40
+ import Development.IDE.Core.OfInterest (OfInterestVar (.. ))
43
41
import Development.IDE.Core.RuleTypes
44
42
import Development.IDE.Core.Shake
45
43
import Development.IDE.GHC.Orphans ()
@@ -48,6 +46,7 @@ import Development.IDE.Import.DependencyInformation
48
46
import Development.IDE.Types.Diagnostics
49
47
import Development.IDE.Types.Location
50
48
import Development.IDE.Types.Options
49
+ import Development.IDE.Types.Shake (SomeShakeValue )
51
50
import HieDb.Create (deleteMissingRealFiles )
52
51
import Ide.Plugin.Config (CheckParents (.. ))
53
52
import System.IO.Error
@@ -63,6 +62,9 @@ import qualified Development.IDE.Types.Logger as L
63
62
64
63
import qualified Data.Binary as B
65
64
import qualified Data.ByteString.Lazy as LBS
65
+ import qualified Data.HashSet as HSet
66
+ import Data.IORef.Extra (atomicModifyIORef_ )
67
+ import Data.List (foldl' )
66
68
import Language.LSP.Server hiding
67
69
(getVirtualFile )
68
70
import qualified Language.LSP.Server as LSP
@@ -95,20 +97,6 @@ makeLSPVFSHandle lspEnv = VFSHandle
95
97
}
96
98
97
99
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
-
112
100
getModificationTimeRule :: VFSHandle -> (NormalizedFilePath -> Action Bool ) -> Rules ()
113
101
getModificationTimeRule vfs isWatched = defineEarlyCutoff $ Rule $ \ (GetModificationTime_ missingFileDiags) file ->
114
102
getModificationTimeImpl vfs isWatched missingFileDiags file
@@ -162,20 +150,21 @@ resetInterfaceStore state f = do
162
150
163
151
-- | Reset the GetModificationTime state of watched files
164
152
resetFileStore :: 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
167
159
case c of
168
160
FcChanged
169
161
| 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
177
165
_ -> pure ()
178
166
167
+
179
168
-- Dir.getModificationTime is surprisingly slow since it performs
180
169
-- a ton of conversions. Since we do not actually care about
181
170
-- the format of the time, we can get away with something cheaper.
@@ -241,7 +230,6 @@ fileStoreRules vfs isWatched = do
241
230
addIdeGlobal vfs
242
231
getModificationTimeRule vfs isWatched
243
232
getFileContentsRule vfs
244
- isFileOfInterestRule
245
233
246
234
-- | Note that some buffer for a specific file has been modified but not
247
235
-- with what changes.
@@ -259,7 +247,8 @@ setFileModified state saved nfp = do
259
247
VFSHandle {.. } <- getIdeGlobalState state
260
248
when (isJust setVirtualFileContents) $
261
249
fail " setFileModified can't be called on this type of VFSHandle"
262
- shakeRestart state []
250
+ recordDirtyKeys (shakeExtras state) GetModificationTime [nfp]
251
+ restartShakeSession (shakeExtras state) []
263
252
when checkParents $
264
253
typecheckParents state nfp
265
254
@@ -279,14 +268,17 @@ typecheckParentsAction nfp = do
279
268
`catch` \ (e :: SomeException ) -> log (show e)
280
269
() <$ uses GetModIface rs
281
270
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
283
272
-- Only valid if the virtual file system was initialised by LSP, as that
284
273
-- independently tracks which files are modified.
285
- setSomethingModified :: IdeState -> IO ()
286
- setSomethingModified state = do
274
+ setSomethingModified :: IdeState -> [ SomeShakeValue ] -> IO ()
275
+ setSomethingModified state keys = do
287
276
VFSHandle {.. } <- getIdeGlobalState state
288
277
when (isJust setVirtualFileContents) $
289
278
fail " setSomethingModified can't be called on this type of VFSHandle"
290
279
-- Update database to remove any files that might have been renamed/deleted
291
280
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