@@ -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
@@ -163,21 +151,23 @@ resetInterfaceStore state f = do
163
151
164
152
-- | Reset the GetModificationTime state of watched files
165
153
resetFileStore :: IdeState -> [FileEvent ] -> IO ()
166
- resetFileStore ideState changes = mask $ \ _ ->
167
- forM_ changes $ \ (FileEvent uri c) ->
154
+ resetFileStore ideState changes = mask $ \ _ -> do
155
+ -- we record FOIs document versions in all the stored values
156
+ -- so NEVER reset FOIs to avoid losing their versions
157
+ OfInterestVar foisVar <- getIdeGlobalExtras (shakeExtras ideState)
158
+ fois <- readVar foisVar
159
+ forM_ changes $ \ (FileEvent uri c) -> do
168
160
case c of
169
161
FcChanged
170
162
| Just f <- uriToFilePath uri
163
+ , nfp <- toNormalizedFilePath f
164
+ , not $ HM. member nfp fois
171
165
-> do
172
- -- we record FOIs document versions in all the stored values
173
- -- so NEVER reset FOIs to avoid losing their versions
174
- OfInterestVar foisVar <- getIdeGlobalExtras (shakeExtras ideState)
175
- fois <- readVar foisVar
176
- unless (HM. member (toNormalizedFilePath f) fois) $ do
177
- deleteValue (shakeExtras ideState) (GetModificationTime_ True ) (toNormalizedFilePath' f)
178
- deleteValue (shakeExtras ideState) (GetModificationTime_ False ) (toNormalizedFilePath' f)
166
+ deleteValue (shakeExtras ideState) (GetModificationTime_ True ) nfp
167
+ deleteValue (shakeExtras ideState) (GetModificationTime_ False ) nfp
179
168
_ -> pure ()
180
169
170
+
181
171
-- Dir.getModificationTime is surprisingly slow since it performs
182
172
-- a ton of conversions. Since we do not actually care about
183
173
-- the format of the time, we can get away with something cheaper.
@@ -243,7 +233,6 @@ fileStoreRules vfs isWatched = do
243
233
addIdeGlobal vfs
244
234
getModificationTimeRule vfs isWatched
245
235
getFileContentsRule vfs
246
- isFileOfInterestRule
247
236
248
237
-- | Note that some buffer for a specific file has been modified but not
249
238
-- with what changes.
@@ -261,7 +250,8 @@ setFileModified state saved nfp = do
261
250
VFSHandle {.. } <- getIdeGlobalState state
262
251
when (isJust setVirtualFileContents) $
263
252
fail " setFileModified can't be called on this type of VFSHandle"
264
- shakeRestart state []
253
+ recordDirtyKeys (shakeExtras state) GetModificationTime [nfp]
254
+ restartShakeSession (shakeExtras state) []
265
255
when checkParents $
266
256
typecheckParents state nfp
267
257
@@ -281,14 +271,17 @@ typecheckParentsAction nfp = do
281
271
`catch` \ (e :: SomeException ) -> log (show e)
282
272
() <$ uses GetModIface rs
283
273
284
- -- | Note that some buffer somewhere has been modified, but don't say what.
274
+ -- | Note that some keys have been modified and restart the session
285
275
-- Only valid if the virtual file system was initialised by LSP, as that
286
276
-- independently tracks which files are modified.
287
- setSomethingModified :: IdeState -> IO ()
288
- setSomethingModified state = do
277
+ setSomethingModified :: IdeState -> [ SomeShakeValue ] -> IO ()
278
+ setSomethingModified state keys = do
289
279
VFSHandle {.. } <- getIdeGlobalState state
290
280
when (isJust setVirtualFileContents) $
291
281
fail " setSomethingModified can't be called on this type of VFSHandle"
292
282
-- Update database to remove any files that might have been renamed/deleted
293
283
atomically $ writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) deleteMissingRealFiles
294
- void $ shakeRestart state []
284
+
285
+ atomicModifyIORef_ (dirtyKeys $ shakeExtras state) $ \ x ->
286
+ foldl' (flip HSet. insert) x keys
287
+ void $ restartShakeSession (shakeExtras state) []
0 commit comments