5
5
6
6
module Development.IDE.Core.FileStore (
7
7
getFileContents ,
8
- getVirtualFile ,
9
8
setFileModified ,
10
9
setSomethingModified ,
11
10
fileStoreRules ,
12
11
modificationTime ,
13
12
typecheckParents ,
14
- VFSHandle ,
15
- makeVFSHandle ,
16
- makeLSPVFSHandle ,
17
13
resetFileStore ,
18
14
resetInterfaceStore ,
19
15
getModificationTimeImpl ,
@@ -27,20 +23,18 @@ module Development.IDE.Core.FileStore(
27
23
import Control.Concurrent.STM.Stats (STM , atomically ,
28
24
modifyTVar' )
29
25
import Control.Concurrent.STM.TQueue (writeTQueue )
30
- import Control.Concurrent.Strict
31
26
import Control.Exception
32
27
import Control.Monad.Extra
33
28
import Control.Monad.IO.Class
34
29
import qualified Data.ByteString as BS
35
30
import Data.Either.Extra
36
- import qualified Data.Map.Strict as Map
37
- import Data.Maybe
38
31
import qualified Data.Rope.UTF16 as Rope
39
32
import qualified Data.Text as T
40
33
import Data.Time
41
34
import Data.Time.Clock.POSIX
42
35
import Development.IDE.Core.RuleTypes
43
36
import Development.IDE.Core.Shake
37
+ import Development.IDE.Core.FileUtils
44
38
import Development.IDE.GHC.Orphans ()
45
39
import Development.IDE.Graph
46
40
import Development.IDE.Import.DependencyInformation
@@ -55,8 +49,6 @@ import System.IO.Error
55
49
#ifdef mingw32_HOST_OS
56
50
import qualified System.Directory as Dir
57
51
#else
58
- import System.Posix.Files (getFileStatus ,
59
- modificationTimeHiRes )
60
52
#endif
61
53
62
54
import qualified Development.IDE.Types.Logger as L
@@ -67,8 +59,6 @@ import qualified Data.HashSet as HSet
67
59
import Data.List (foldl' )
68
60
import qualified Data.Text as Text
69
61
import Development.IDE.Core.IdeConfiguration (isWorkspaceFile )
70
- import Language.LSP.Server hiding
71
- (getVirtualFile )
72
62
import qualified Language.LSP.Server as LSP
73
63
import Language.LSP.Types (DidChangeWatchedFilesRegistrationOptions (DidChangeWatchedFilesRegistrationOptions ),
74
64
FileChangeType (FcChanged ),
@@ -80,27 +70,6 @@ import qualified Language.LSP.Types.Capabilities as LSP
80
70
import Language.LSP.VFS
81
71
import System.FilePath
82
72
83
- makeVFSHandle :: IO VFSHandle
84
- makeVFSHandle = do
85
- vfsVar <- newVar (1 , Map. empty)
86
- pure VFSHandle
87
- { getVirtualFile = \ uri -> do
88
- (_nextVersion, vfs) <- readVar vfsVar
89
- pure $ Map. lookup uri vfs
90
- , setVirtualFileContents = Just $ \ uri content ->
91
- void $ modifyVar' vfsVar $ \ (nextVersion, vfs) -> (nextVersion + 1 , ) $
92
- case content of
93
- Nothing -> Map. delete uri vfs
94
- -- The second version number is only used in persistFileVFS which we do not use so we set it to 0.
95
- Just content -> Map. insert uri (VirtualFile nextVersion 0 (Rope. fromText content)) vfs
96
- }
97
-
98
- makeLSPVFSHandle :: LanguageContextEnv c -> VFSHandle
99
- makeLSPVFSHandle lspEnv = VFSHandle
100
- { getVirtualFile = runLspT lspEnv . LSP. getVirtualFile
101
- , setVirtualFileContents = Nothing
102
- }
103
-
104
73
addWatchedFileRule :: (NormalizedFilePath -> Action Bool ) -> Rules ()
105
74
addWatchedFileRule isWatched = defineNoDiagnostics $ \ AddWatchedFile f -> do
106
75
isAlreadyWatched <- isWatched f
@@ -114,20 +83,19 @@ addWatchedFileRule isWatched = defineNoDiagnostics $ \AddWatchedFile f -> do
114
83
Nothing -> pure $ Just False
115
84
116
85
117
- getModificationTimeRule :: VFSHandle -> Rules ()
118
- getModificationTimeRule vfs = defineEarlyCutoff $ Rule $ \ (GetModificationTime_ missingFileDiags) file ->
119
- getModificationTimeImpl vfs missingFileDiags file
86
+ getModificationTimeRule :: Rules ()
87
+ getModificationTimeRule = defineEarlyCutoff $ Rule $ \ (GetModificationTime_ missingFileDiags) file ->
88
+ getModificationTimeImpl missingFileDiags file
120
89
121
- getModificationTimeImpl :: VFSHandle
122
- -> Bool
123
- -> NormalizedFilePath
124
- -> Action
125
- (Maybe BS. ByteString , ([FileDiagnostic ], Maybe FileVersion ))
126
- getModificationTimeImpl vfs missingFileDiags file = do
90
+ getModificationTimeImpl
91
+ :: Bool
92
+ -> NormalizedFilePath
93
+ -> Action (Maybe BS. ByteString , ([FileDiagnostic ], Maybe FileVersion ))
94
+ getModificationTimeImpl missingFileDiags file = do
127
95
let file' = fromNormalizedFilePath file
128
96
let wrap time = (Just $ LBS. toStrict $ B. encode $ toRational time, ([] , Just $ ModificationTime time))
129
- mbVirtual <- liftIO $ getVirtualFile vfs $ filePathToUri' file
130
- case mbVirtual of
97
+ mbVf <- getVirtualFile file
98
+ case mbVf of
131
99
Just (virtualFileVersion -> ver) -> do
132
100
alwaysRerun
133
101
pure (Just $ LBS. toStrict $ B. encode ver, ([] , Just $ VFSVersion ver))
@@ -180,43 +148,23 @@ resetFileStore ideState changes = mask $ \_ -> do
180
148
_ -> pure ()
181
149
182
150
183
- -- Dir.getModificationTime is surprisingly slow since it performs
184
- -- a ton of conversions. Since we do not actually care about
185
- -- the format of the time, we can get away with something cheaper.
186
- -- For now, we only try to do this on Unix systems where it seems to get the
187
- -- time spent checking file modifications (which happens on every change)
188
- -- from > 0.5s to ~0.15s.
189
- -- We might also want to try speeding this up on Windows at some point.
190
- -- TODO leverage DidChangeWatchedFile lsp notifications on clients that
191
- -- support them, as done for GetFileExists
192
- getModTime :: FilePath -> IO POSIXTime
193
- getModTime f =
194
- #ifdef mingw32_HOST_OS
195
- utcTimeToPOSIXSeconds <$> Dir. getModificationTime f
196
- #else
197
- modificationTimeHiRes <$> getFileStatus f
198
- #endif
199
-
200
151
modificationTime :: FileVersion -> Maybe UTCTime
201
152
modificationTime VFSVersion {} = Nothing
202
153
modificationTime (ModificationTime posix) = Just $ posixSecondsToUTCTime posix
203
154
204
- getFileContentsRule :: VFSHandle -> Rules ()
205
- getFileContentsRule vfs = define $ \ GetFileContents file -> getFileContentsImpl vfs file
155
+ getFileContentsRule :: Rules ()
156
+ getFileContentsRule = define $ \ GetFileContents file -> getFileContentsImpl file
206
157
207
158
getFileContentsImpl
208
- :: VFSHandle
209
- -> NormalizedFilePath
159
+ :: NormalizedFilePath
210
160
-> Action ([FileDiagnostic ], Maybe (FileVersion , Maybe T. Text ))
211
- getFileContentsImpl vfs file = do
161
+ getFileContentsImpl file = do
212
162
-- need to depend on modification time to introduce a dependency with Cutoff
213
163
time <- use_ GetModificationTime file
214
- res <- liftIO $ ideTryIOException file $ do
215
- mbVirtual <- getVirtualFile vfs $ filePathToUri' file
164
+ res <- do
165
+ mbVirtual <- getVirtualFile file
216
166
pure $ Rope. toText . _text <$> mbVirtual
217
- case res of
218
- Left err -> return ([err], Nothing )
219
- Right contents -> return ([] , Just (time, contents))
167
+ pure ([] , Just (time, res))
220
168
221
169
ideTryIOException :: NormalizedFilePath -> IO a -> IO (Either FileDiagnostic a )
222
170
ideTryIOException fp act =
@@ -240,11 +188,10 @@ getFileContents f = do
240
188
pure $ posixSecondsToUTCTime posix
241
189
return (modTime, txt)
242
190
243
- fileStoreRules :: VFSHandle -> (NormalizedFilePath -> Action Bool ) -> Rules ()
244
- fileStoreRules vfs isWatched = do
245
- addIdeGlobal vfs
246
- getModificationTimeRule vfs
247
- getFileContentsRule vfs
191
+ fileStoreRules :: (NormalizedFilePath -> Action Bool ) -> Rules ()
192
+ fileStoreRules isWatched = do
193
+ getModificationTimeRule
194
+ getFileContentsRule
248
195
addWatchedFileRule isWatched
249
196
250
197
-- | Note that some buffer for a specific file has been modified but not
@@ -260,9 +207,6 @@ setFileModified state saved nfp = do
260
207
AlwaysCheck -> True
261
208
CheckOnSave -> saved
262
209
_ -> False
263
- VFSHandle {.. } <- getIdeGlobalState state
264
- when (isJust setVirtualFileContents) $
265
- fail " setFileModified can't be called on this type of VFSHandle"
266
210
join $ atomically $ recordDirtyKeys (shakeExtras state) GetModificationTime [nfp]
267
211
restartShakeSession (shakeExtras state) (fromNormalizedFilePath nfp ++ " (modified)" ) []
268
212
when checkParents $
@@ -289,9 +233,6 @@ typecheckParentsAction nfp = do
289
233
-- independently tracks which files are modified.
290
234
setSomethingModified :: IdeState -> [Key ] -> String -> IO ()
291
235
setSomethingModified state keys reason = do
292
- VFSHandle {.. } <- getIdeGlobalState state
293
- when (isJust setVirtualFileContents) $
294
- fail " setSomethingModified can't be called on this type of VFSHandle"
295
236
-- Update database to remove any files that might have been renamed/deleted
296
237
atomically $ do
297
238
writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) (\ withHieDb -> withHieDb deleteMissingRealFiles)
0 commit comments