@@ -78,7 +78,6 @@ import System.FilePath
7878import System.IO.Error
7979import System.IO.Unsafe
8080
81-
8281data Log
8382 = LogCouldNotIdentifyReverseDeps ! NormalizedFilePath
8483 | LogTypeCheckingReverseDeps ! NormalizedFilePath ! (Maybe [NormalizedFilePath ])
@@ -147,6 +146,29 @@ getModificationTimeImpl missingFileDiags file = do
147146 then return (Nothing , ([] , Nothing ))
148147 else return (Nothing , ([diag], Nothing ))
149148
149+
150+ getPhysicalModificationTimeRule :: Recorder (WithPriority Log ) -> Rules ()
151+ getPhysicalModificationTimeRule recorder = defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \ GetPhysicalModificationTime file ->
152+ getPhysicalModificationTimeImpl file
153+
154+ getPhysicalModificationTimeImpl
155+ :: NormalizedFilePath
156+ -> Action (Maybe BS. ByteString , ([FileDiagnostic ], Maybe FileVersion ))
157+ getPhysicalModificationTimeImpl file = do
158+ let file' = fromNormalizedFilePath file
159+ let wrap time = (Just $ LBS. toStrict $ B. encode $ toRational time, ([] , Just $ ModificationTime time))
160+
161+ alwaysRerun
162+
163+ liftIO $ fmap wrap (getModTime file')
164+ `catch` \ (e :: IOException ) -> do
165+ let err | isDoesNotExistError e = " File does not exist: " ++ file'
166+ | otherwise = " IO error while reading " ++ file' ++ " , " ++ displayException e
167+ diag = ideErrorText file (T. pack err)
168+ if isDoesNotExistError e
169+ then return (Nothing , ([] , Nothing ))
170+ else return (Nothing , ([diag], Nothing ))
171+
150172-- | Interface files cannot be watched, since they live outside the workspace.
151173-- But interface files are private, in that only HLS writes them.
152174-- So we implement watching ourselves, and bypass the need for alwaysRerun.
@@ -170,7 +192,11 @@ resetFileStore ideState changes = mask $ \_ -> do
170192 case c of
171193 LSP. FileChangeType_Changed
172194 -- already checked elsewhere | not $ HM.member nfp fois
173- -> atomically $ deleteValue (shakeExtras ideState) GetModificationTime nfp
195+ ->
196+ atomically $ do
197+ ks <- deleteValue (shakeExtras ideState) GetModificationTime nfp
198+ vs <- deleteValue (shakeExtras ideState) GetPhysicalModificationTime nfp
199+ pure $ ks ++ vs
174200 _ -> pure []
175201
176202
@@ -233,6 +259,7 @@ getVersionedTextDoc doc = do
233259fileStoreRules :: Recorder (WithPriority Log ) -> (NormalizedFilePath -> Action Bool ) -> Rules ()
234260fileStoreRules recorder isWatched = do
235261 getModificationTimeRule recorder
262+ getPhysicalModificationTimeRule recorder
236263 getFileContentsRule recorder
237264 addWatchedFileRule recorder isWatched
238265
0 commit comments