@@ -15,7 +15,9 @@ module Development.IDE.Core.FileStore(
1515 makeVFSHandle ,
1616 makeLSPVFSHandle ,
1717 isFileOfInterestRule
18- ,resetFileStore ) where
18+ ,resetFileStore
19+ ,resetInterfaceStore
20+ ) where
1921
2022import Control.Concurrent.Extra
2123import Control.Concurrent.STM (atomically )
@@ -67,6 +69,7 @@ import Language.LSP.Types (FileChangeType (F
6769 FileEvent (FileEvent ),
6870 uriToFilePath , toNormalizedFilePath )
6971import Language.LSP.VFS
72+ import System.FilePath
7073
7174makeVFSHandle :: IO VFSHandle
7275makeVFSHandle = do
@@ -111,7 +114,7 @@ getModificationTimeRule vfs isWatched =
111114 pure (Just $ BS. pack $ show ver, ([] , Just $ VFSVersion ver))
112115 Nothing -> do
113116 isWF <- isWatched file
114- unless isWF alwaysRerun
117+ unless ( isWF || isInterface file) alwaysRerun
115118 liftIO $ fmap wrap (getModTime file')
116119 `catch` \ (e :: IOException ) -> do
117120 let err | isDoesNotExistError e = " File does not exist: " ++ file'
@@ -121,6 +124,18 @@ getModificationTimeRule vfs isWatched =
121124 then return (Nothing , ([] , Nothing ))
122125 else return (Nothing , ([diag], Nothing ))
123126
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" , " .hi-boot" ]
132+
133+ -- | Reset the GetModificationTime state of interface files
134+ resetInterfaceStore :: ShakeExtras -> NormalizedFilePath -> IO ()
135+ resetInterfaceStore state f = do
136+ deleteValue state (GetModificationTime_ True ) f
137+ deleteValue state (GetModificationTime_ False ) f
138+
124139-- | Reset the GetModificationTime state of watched files
125140resetFileStore :: IdeState -> [FileEvent ] -> IO ()
126141resetFileStore ideState changes = mask $ \ _ ->
@@ -134,8 +149,8 @@ resetFileStore ideState changes = mask $ \_ ->
134149 OfInterestVar foisVar <- getIdeGlobalExtras (shakeExtras ideState)
135150 fois <- readVar foisVar
136151 unless (HM. member (toNormalizedFilePath f) fois) $ do
137- deleteValue ideState (GetModificationTime_ True ) (toNormalizedFilePath' f)
138- deleteValue ideState (GetModificationTime_ False ) (toNormalizedFilePath' f)
152+ deleteValue (shakeExtras ideState) (GetModificationTime_ True ) (toNormalizedFilePath' f)
153+ deleteValue (shakeExtras ideState) (GetModificationTime_ False ) (toNormalizedFilePath' f)
139154 _ -> pure ()
140155
141156-- Dir.getModificationTime is surprisingly slow since it performs
0 commit comments