@@ -109,8 +109,11 @@ import qualified Data.HashMap.Strict as HashMap
109
109
import qualified Language.Haskell.LSP.Messages as LSP
110
110
import qualified Language.Haskell.LSP.Types as LSP
111
111
import Control.Concurrent.STM hiding (orElse )
112
+ import Control.Concurrent.Extra
112
113
import Data.Functor
113
114
import Data.Unique
115
+ import GHC.Fingerprint
116
+ import Debug.Trace
114
117
115
118
-- | Given a string buffer, return the string (after preprocessing) and the 'ParsedModule'.
116
119
parseModule
@@ -471,66 +474,66 @@ spliceExpresions Splices{..} =
471
474
, DL. fromList $ map fst awSplices
472
475
]
473
476
474
- indexHieFile :: ShakeExtras -> ModSummary -> NormalizedFilePath -> Compat. HieFile -> IO ()
475
- indexHieFile se mod_summary srcPath hf = atomically $ do
477
+ indexHieFile :: ShakeExtras -> ModSummary -> NormalizedFilePath -> Fingerprint -> Compat. HieFile -> IO ()
478
+ indexHieFile se mod_summary srcPath hash hf = atomically $ do
476
479
pending <- readTVar indexPending
477
480
case HashMap. lookup srcPath pending of
478
- Just mtime | mtime >= modtime -> pure () -- An index is already scheduled
481
+ Just pendingHash | pendingHash == hash -> pure () -- An index is already scheduled
479
482
_ -> do
480
- modifyTVar' indexPending $ HashMap. insert srcPath modtime
483
+ modifyTVar' indexPending $ HashMap. insert srcPath hash
481
484
writeTQueue indexQueue $ \ db -> do
482
485
-- We are now in the worker thread
486
+ -- Check if a newer index of this file has been scheduled, and if so skip this one
483
487
newerScheduled <- atomically $ do
484
488
pending <- readTVar indexPending
485
- case HashMap. lookup srcPath pending of
486
- Nothing -> pure False
487
- Just mtime -> pure $ mtime > modtime
488
- -- Check if a newer index of this file has been scheduled, and if so skip this one
489
+ pure $ case HashMap. lookup srcPath pending of
490
+ Nothing -> False
491
+ -- If the hash in the pending list doesn't match the current hash, then skip
492
+ Just pendingHash -> pendingHash /= hash
489
493
unless newerScheduled $ do
490
494
tok <- pre
491
- addRefsFromLoaded db targetPath (Just $ fromNormalizedFilePath srcPath) True modtime hf
495
+ addRefsFromLoaded db targetPath (Just $ fromNormalizedFilePath srcPath) True hash hf
492
496
post tok
493
497
where
494
- modtime = ms_hs_date mod_summary
495
498
mod_location = ms_location mod_summary
496
499
targetPath = Compat. ml_hie_file mod_location
497
500
HieDbWriter {.. } = hiedbWriter se
498
501
499
502
-- Get a progress token to report progress and update it for the current file
500
503
pre = do
501
- (! oldTok, ! done, ! remaining) <- atomically $ do
502
- oldTok <- readTVar indexProgressToken
503
- done <- readTVar indexCompleted
504
- remaining <- HashMap. size <$> readTVar indexPending
505
- pure (oldTok, done, remaining)
506
- tok <- case oldTok of
507
- Just x -> pure x
504
+ tok <- modifyVar indexProgressToken $ \ case
505
+ x@ (Just tok) -> pure (x, tok)
506
+ -- Create a token if we don't already have one
508
507
Nothing -> do
509
- lspId <- getLspId se
510
508
u <- LSP. ProgressTextToken . T. pack . show . hashUnique <$> newUnique
511
- eventer se $ LSP. ReqWorkDoneProgressCreate $
509
+ lspId <- getLspId se
510
+ eventer se $ traceShowId $ LSP. ReqWorkDoneProgressCreate $
512
511
LSP. fmServerWorkDoneProgressCreateRequest lspId $
513
512
LSP. WorkDoneProgressCreateParams { _token = u }
514
- eventer se $ LSP. NotWorkDoneProgressBegin $
513
+ eventer se $ traceShowId $ LSP. NotWorkDoneProgressBegin $
515
514
LSP. fmServerWorkDoneProgressBeginNotification
516
515
LSP. ProgressParams
517
516
{ _token = u
518
517
, _value = LSP. WorkDoneProgressBeginParams
519
- { _title = " Indexing References "
518
+ { _title = " Indexing references from: "
520
519
, _cancellable = Nothing
521
520
, _message = Nothing
522
521
, _percentage = Nothing
523
522
}
524
523
}
525
- pure u
524
+ pure (Just u, u)
525
+ (! done, ! remaining) <- atomically $ do
526
+ done <- readTVar indexCompleted
527
+ remaining <- HashMap. size <$> readTVar indexPending
528
+ pure (done, remaining)
526
529
let progress = " (" <> T. pack (show done) <> " /" <> T. pack (show $ done + remaining) <> " )..."
527
- eventer se $ LSP. NotWorkDoneProgressReport $
530
+ eventer se $ traceShowId $ LSP. NotWorkDoneProgressReport $
528
531
LSP. fmServerWorkDoneProgressReportNotification
529
532
LSP. ProgressParams
530
533
{ _token = tok
531
534
, _value = LSP. WorkDoneProgressReportParams
532
535
{ _cancellable = Nothing
533
- , _message = Just $ " Indexing " <> T. pack (show srcPath) <> progress
536
+ , _message = Just $ T. pack (show srcPath) <> progress
534
537
, _percentage = Nothing
535
538
}
536
539
}
@@ -540,7 +543,7 @@ indexHieFile se mod_summary srcPath hf = atomically $ do
540
543
post tok = do
541
544
mdone <- atomically $ do
542
545
-- Remove current element from pending
543
- modifyTVar' indexPending $ HashMap. update (\ qTime -> guard (qTime <= modtime ) $> qTime ) srcPath
546
+ modifyTVar' indexPending $ HashMap. update (\ pendingHash -> guard (pendingHash /= hash ) $> pendingHash ) srcPath
544
547
pending <- readTVar indexPending
545
548
if HashMap. null pending
546
549
then Just <$> swapTVar indexCompleted 0
@@ -549,22 +552,27 @@ indexHieFile se mod_summary srcPath hf = atomically $ do
549
552
pure Nothing
550
553
case mdone of
551
554
Nothing -> pure ()
552
- Just done -> eventer se $ LSP. NotWorkDoneProgressEnd $
553
- LSP. fmServerWorkDoneProgressEndNotification
554
- LSP. ProgressParams
555
- { _token = tok
556
- , _value = LSP. WorkDoneProgressEndParams
557
- { _message = Just $ " Finished indexing " <> T. pack (show done) <> " files"
558
- }
559
- }
555
+ Just done ->
556
+ modifyVar_ indexProgressToken $ \ _ -> do
557
+ eventer se $ traceShowId $ LSP. NotWorkDoneProgressEnd $
558
+ LSP. fmServerWorkDoneProgressEndNotification
559
+ LSP. ProgressParams
560
+ { _token = tok
561
+ , _value = LSP. WorkDoneProgressEndParams
562
+ { _message = Just $ " Finished indexing " <> T. pack (show done) <> " files"
563
+ }
564
+ }
565
+ -- We are done with the current indexing cycle, so destroy the token
566
+ pure Nothing
560
567
561
568
writeAndIndexHieFile :: HscEnv -> ShakeExtras -> ModSummary -> NormalizedFilePath -> [GHC. AvailInfo ] -> HieASTs Type -> BS. ByteString -> IO [FileDiagnostic ]
562
569
writeAndIndexHieFile hscEnv se mod_summary srcPath exports ast source =
563
570
handleGenerationErrors dflags " extended interface write/compression" $ do
564
571
hf <- runHsc hscEnv $
565
572
GHC. mkHieFile' mod_summary exports ast source
566
573
atomicFileWrite targetPath $ flip GHC. writeHieFile hf
567
- indexHieFile se mod_summary srcPath hf
574
+ hash <- getFileHash targetPath
575
+ indexHieFile se mod_summary srcPath hash hf
568
576
where
569
577
dflags = hsc_dflags hscEnv
570
578
mod_location = ms_location mod_summary
0 commit comments