@@ -13,7 +13,9 @@ module Development.IDE.Core.Rules(
13
13
-- * Types
14
14
IdeState , GetParsedModule (.. ), TransitiveDependencies (.. ),
15
15
Priority (.. ), GhcSessionIO (.. ), GetClientSettings (.. ),
16
+ HieFileCheck (.. ),
16
17
-- * Functions
18
+ checkHieFile ,
17
19
priorityTypeCheck ,
18
20
priorityGenerateCore ,
19
21
priorityFilesOfInterest ,
@@ -78,6 +80,7 @@ import Data.Aeson (Result (Success),
78
80
toJSON )
79
81
import qualified Data.Aeson.Types as A
80
82
import qualified Data.Binary as B
83
+ import Data.Bool (bool )
81
84
import qualified Data.ByteString as BS
82
85
import qualified Data.ByteString.Lazy as LBS
83
86
import Data.Coerce
@@ -129,7 +132,7 @@ import qualified Development.IDE.Spans.AtPoint as AtPoint
129
132
import Development.IDE.Spans.Documentation
130
133
import Development.IDE.Spans.LocalBindings
131
134
import Development.IDE.Types.Diagnostics as Diag
132
- import Development.IDE.Types.HscEnvEq
135
+ import {- # SOURCE # -} Development.IDE.Types.HscEnvEq
133
136
import Development.IDE.Types.Location
134
137
import Development.IDE.Types.Options
135
138
import qualified GHC.LanguageExtensions as LangExt
@@ -172,8 +175,9 @@ data Log
172
175
= LogShake Shake. Log
173
176
| LogReindexingHieFile ! NormalizedFilePath
174
177
| LogLoadingHieFile ! NormalizedFilePath
175
- | LogLoadingHieFileFail ! FilePath ! SomeException
176
- | LogLoadingHieFileSuccess ! FilePath
178
+ | LogMissingHieFile ! NormalizedFilePath
179
+ | LogLoadingHieFileFail ! NormalizedFilePath ! SomeException
180
+ | LogLoadingHieFileSuccess ! NormalizedFilePath
177
181
| LogTypecheckedFOI ! NormalizedFilePath
178
182
deriving Show
179
183
@@ -184,13 +188,15 @@ instance Pretty Log where
184
188
" Re-indexing hie file for" <+> pretty (fromNormalizedFilePath path)
185
189
LogLoadingHieFile path ->
186
190
" LOADING HIE FILE FOR" <+> pretty (fromNormalizedFilePath path)
191
+ LogMissingHieFile path ->
192
+ " MISSING HIE FILE" <+> pretty (fromNormalizedFilePath path)
187
193
LogLoadingHieFileFail path e ->
188
194
nest 2 $
189
195
vcat
190
- [ " FAILED LOADING HIE FILE FOR " <+> pretty path
196
+ [ " FAILED LOADING HIE FILE" <+> pretty (fromNormalizedFilePath path)
191
197
, pretty (displayException e) ]
192
198
LogLoadingHieFileSuccess path ->
193
- " SUCCEEDED LOADING HIE FILE FOR " <+> pretty path
199
+ " SUCCEEDED LOADING HIE FILE" <+> pretty (fromNormalizedFilePath path)
194
200
LogTypecheckedFOI path -> vcat
195
201
[ " Typechecked a file which is not currently open in the editor:" <+> pretty (fromNormalizedFilePath path)
196
202
, " This can indicate a bug which results in excessive memory usage."
@@ -665,14 +671,14 @@ readHieFileForSrcFromDisk :: Recorder (WithPriority Log) -> NormalizedFilePath -
665
671
readHieFileForSrcFromDisk recorder file = do
666
672
ShakeExtras {withHieDb} <- ask
667
673
row <- MaybeT $ liftIO $ withHieDb (\ hieDb -> HieDb. lookupHieFileFromSource hieDb $ fromNormalizedFilePath file)
668
- let hie_loc = HieDb. hieModuleHieFile row
674
+ let hie_loc = toNormalizedFilePath' $ HieDb. hieModuleHieFile row
669
675
liftIO $ logWith recorder Logger. Debug $ LogLoadingHieFile file
670
676
exceptToMaybeT $ readHieFileFromDisk recorder hie_loc
671
677
672
- readHieFileFromDisk :: Recorder (WithPriority Log ) -> FilePath -> ExceptT SomeException IdeAction Compat. HieFile
678
+ readHieFileFromDisk :: Recorder (WithPriority Log ) -> NormalizedFilePath -> ExceptT SomeException IdeAction Compat. HieFile
673
679
readHieFileFromDisk recorder hie_loc = do
674
680
nc <- asks ideNc
675
- res <- liftIO $ tryAny $ loadHieFile (mkUpdater nc) hie_loc
681
+ res <- liftIO $ tryAny $ loadHieFile (mkUpdater nc) (fromNormalizedFilePath hie_loc)
676
682
let log = (liftIO . ) . logWith recorder
677
683
case res of
678
684
Left e -> log Logger. Debug $ LogLoadingHieFileFail hie_loc e
@@ -854,6 +860,43 @@ getModIfaceFromDiskRule recorder = defineEarlyCutoff (cmapWithPrio LogShake reco
854
860
let ! fp = Just $! hiFileFingerPrint x
855
861
return (fp, (diags, Just x))
856
862
863
+ data HieFileCheck
864
+ = HieFileMissing
865
+ | HieAlreadyIndexed
866
+ | CouldNotLoadHie SomeException
867
+ | DoIndexing Util. Fingerprint HieFile
868
+
869
+ checkHieFile
870
+ :: Recorder (WithPriority Log )
871
+ -> ShakeExtras
872
+ -> String
873
+ -> NormalizedFilePath
874
+ -> IO HieFileCheck
875
+ checkHieFile recorder se@ ShakeExtras {withHieDb} tag hieFileLocation = do
876
+ hieFileExists <- doesFileExist $ fromNormalizedFilePath hieFileLocation
877
+ bool logHieFileMissing checkExistingHieFile hieFileExists
878
+ where
879
+ logHieFileMissing :: IO HieFileCheck
880
+ logHieFileMissing = do
881
+ let log :: Log
882
+ log = LogMissingHieFile hieFileLocation
883
+ logWith recorder Logger. Debug log
884
+ pure HieFileMissing
885
+ checkExistingHieFile :: IO HieFileCheck
886
+ checkExistingHieFile = do
887
+ hash <- Util. getFileHash $ fromNormalizedFilePath hieFileLocation
888
+ mrow <- withHieDb (\ hieDb -> HieDb. lookupHieFileFromHash hieDb hash)
889
+ dbHieFileLocation <- traverse (makeAbsolute . HieDb. hieModuleHieFile) mrow
890
+ bool (tryLoadingHieFile hash) (pure HieAlreadyIndexed ) $
891
+ Just hieFileLocation == fmap toNormalizedFilePath' dbHieFileLocation
892
+ tryLoadingHieFile :: Util. Fingerprint -> IO HieFileCheck
893
+ tryLoadingHieFile hash = do
894
+ ehf <- runIdeAction tag se $ runExceptT $
895
+ readHieFileFromDisk recorder hieFileLocation
896
+ pure $ case ehf of
897
+ Left err -> CouldNotLoadHie err
898
+ Right hf -> DoIndexing hash hf
899
+
857
900
-- | Check state of hiedb after loading an iface from disk - have we indexed the corresponding `.hie` file?
858
901
-- This function is responsible for ensuring database consistency
859
902
-- Whenever we read a `.hi` file, we must check to ensure we have also
@@ -871,31 +914,20 @@ getModIfaceFromDiskAndIndexRule recorder =
871
914
872
915
-- GetModIfaceFromDisk should have written a `.hie` file, must check if it matches version in db
873
916
let ms = hirModSummary x
874
- hie_loc = Compat. ml_hie_file $ ms_location ms
875
- hash <- liftIO $ Util. getFileHash hie_loc
876
- mrow <- liftIO $ withHieDb (\ hieDb -> HieDb. lookupHieFileFromSource hieDb (fromNormalizedFilePath f))
877
- hie_loc' <- liftIO $ traverse (makeAbsolute . HieDb. hieModuleHieFile) mrow
878
- case mrow of
879
- Just row
880
- | hash == HieDb. modInfoHash (HieDb. hieModInfo row)
881
- && Just hie_loc == hie_loc'
882
- -> do
883
- -- All good, the db has indexed the file
884
- when (coerce $ ideTesting se) $ liftIO $ mRunLspT (lspEnv se) $
885
- LSP. sendNotification (SMethod_CustomMethod (Proxy @ " ghcide/reference/ready" )) $
886
- toJSON $ fromNormalizedFilePath f
887
- -- Not in db, must re-index
888
- _ -> do
889
- ehf <- liftIO $ runIdeAction " GetModIfaceFromDiskAndIndex" se $ runExceptT $
890
- readHieFileFromDisk recorder hie_loc
891
- case ehf of
892
- -- Uh oh, we failed to read the file for some reason, need to regenerate it
893
- Left err -> fail $ " failed to read .hie file " ++ show hie_loc ++ " : " ++ displayException err
894
- -- can just re-index the file we read from disk
895
- Right hf -> liftIO $ do
896
- logWith recorder Logger. Debug $ LogReindexingHieFile f
897
- indexHieFile se (toNormalizedFilePath' hie_loc) (HieDb. RealFile $ fromNormalizedFilePath f) hash hf
898
-
917
+ hie_loc = toNormalizedFilePath' $ Compat. ml_hie_file $ ms_location ms
918
+ hieFailure :: Maybe SomeException -> Action ()
919
+ hieFailure mErr = fail $ " failed to read .hie file " ++ show hie_loc ++ " : " ++
920
+ maybe " Does not exist" displayException mErr
921
+ hieCheck <- liftIO $ checkHieFile recorder se " GetModIfaceFromDiskAndIndex" hie_loc
922
+ case hieCheck of
923
+ HieFileMissing -> hieFailure Nothing
924
+ HieAlreadyIndexed -> when (coerce $ ideTesting se) $ liftIO $ mRunLspT (lspEnv se) $
925
+ LSP. sendNotification (SMethod_CustomMethod (Proxy @ " ghcide/reference/ready" )) $
926
+ toJSON $ fromNormalizedFilePath f
927
+ CouldNotLoadHie err -> hieFailure $ Just err
928
+ DoIndexing hash hf -> liftIO $ do
929
+ logWith recorder Logger. Debug $ LogReindexingHieFile f
930
+ indexHieFile se hie_loc (HieDb. RealFile $ fromNormalizedFilePath f) hash hf
899
931
return (Just x)
900
932
901
933
newtype DisplayTHWarning = DisplayTHWarning (IO () )
0 commit comments