@@ -15,7 +15,9 @@ module Development.IDE.Core.FileStore(
15
15
makeVFSHandle ,
16
16
makeLSPVFSHandle ,
17
17
isFileOfInterestRule
18
- ,resetFileStore ) where
18
+ ,resetFileStore
19
+ ,resetInterfaceStore
20
+ ) where
19
21
20
22
import Control.Concurrent.Extra
21
23
import Control.Concurrent.STM (atomically )
@@ -67,6 +69,7 @@ import Language.LSP.Types (FileChangeType (F
67
69
FileEvent (FileEvent ),
68
70
uriToFilePath , toNormalizedFilePath )
69
71
import Language.LSP.VFS
72
+ import System.FilePath
70
73
71
74
makeVFSHandle :: IO VFSHandle
72
75
makeVFSHandle = do
@@ -111,7 +114,7 @@ getModificationTimeRule vfs isWatched =
111
114
pure (Just $ BS. pack $ show ver, ([] , Just $ VFSVersion ver))
112
115
Nothing -> do
113
116
isWF <- isWatched file
114
- unless isWF alwaysRerun
117
+ unless ( isWF || isInterface file) alwaysRerun
115
118
liftIO $ fmap wrap (getModTime file')
116
119
`catch` \ (e :: IOException ) -> do
117
120
let err | isDoesNotExistError e = " File does not exist: " ++ file'
@@ -121,6 +124,19 @@ getModificationTimeRule vfs isWatched =
121
124
then return (Nothing , ([] , Nothing ))
122
125
else return (Nothing , ([diag], Nothing ))
123
126
127
+ -- | Interface files cannot be watched, since they live outside the workspace.
128
+ -- But interface files are private, in that only HLS writes them.
129
+ -- So we implement watching ourselves, and bypass the need for alwaysRerun.
130
+ isInterface :: NormalizedFilePath -> Bool
131
+ isInterface f = takeExtension (fromNormalizedFilePath f) `elem` [" .hi" , " .hie" ]
132
+
133
+ -- | Reset the GetModificationTime state of interface files
134
+ resetInterfaceStore :: ShakeExtras -> FilePath -> IO ()
135
+ resetInterfaceStore state f = do
136
+ forM_ [toNormalizedFilePath' (replaceExtension f ext) | ext <- [" hi" ," hie" ]] $ \ f ->
137
+ forM_ [True ,False ] $ \ gmt ->
138
+ deleteValue state (GetModificationTime_ gmt) f
139
+
124
140
-- | Reset the GetModificationTime state of watched files
125
141
resetFileStore :: IdeState -> [FileEvent ] -> IO ()
126
142
resetFileStore ideState changes = mask $ \ _ ->
@@ -134,8 +150,8 @@ resetFileStore ideState changes = mask $ \_ ->
134
150
OfInterestVar foisVar <- getIdeGlobalExtras (shakeExtras ideState)
135
151
fois <- readVar foisVar
136
152
unless (HM. member (toNormalizedFilePath f) fois) $ do
137
- deleteValue ideState (GetModificationTime_ True ) (toNormalizedFilePath' f)
138
- deleteValue ideState (GetModificationTime_ False ) (toNormalizedFilePath' f)
153
+ deleteValue (shakeExtras ideState) (GetModificationTime_ True ) (toNormalizedFilePath' f)
154
+ deleteValue (shakeExtras ideState) (GetModificationTime_ False ) (toNormalizedFilePath' f)
139
155
_ -> pure ()
140
156
141
157
-- Dir.getModificationTime is surprisingly slow since it performs
0 commit comments