3
3
4
4
{-# LANGUAGE ConstraintKinds #-}
5
5
{-# LANGUAGE DerivingStrategies #-}
6
+ {-# LANGUAGE DuplicateRecordFields #-}
6
7
{-# LANGUAGE ExistentialQuantification #-}
7
8
{-# LANGUAGE PolyKinds #-}
8
9
{-# LANGUAGE RankNTypes #-}
@@ -183,8 +184,8 @@ data ShakeExtras = ShakeExtras
183
184
-- positions in a version of that document to positions in the latest version
184
185
-- First mapping is delta from previous version and second one is an
185
186
-- accumlation of all previous mappings.
186
- ,inProgress :: Var ( HMap. HashMap NormalizedFilePath Int )
187
- -- ^ How many rules are running for each file
187
+ ,inProgress :: forall a . NormalizedFilePath -> Action a -> Action a
188
+ -- ^ Report progress for a rule
188
189
,progressUpdate :: ProgressEvent -> IO ()
189
190
,ideTesting :: IdeTesting
190
191
-- ^ Whether to enable additional lsp messages used by the test suite for checking invariants
@@ -473,9 +474,8 @@ shakeOpen :: Maybe (LSP.LanguageContextEnv Config)
473
474
-> Rules ()
474
475
-> IO IdeState
475
476
shakeOpen lspEnv defaultConfig logger debouncer
476
- shakeProfileDir (IdeReportProgress reportProgress ) ideTesting@ (IdeTesting testing) hiedb indexQueue vfs opts rules = mdo
477
+ shakeProfileDir (IdeReportProgress inProgress ) ideTesting@ (IdeTesting testing) hiedb indexQueue vfs opts rules = mdo
477
478
478
- inProgress <- newVar HMap. empty
479
479
us <- mkSplitUniqSupply ' r'
480
480
ideNc <- newIORef (initNameCache us knownKeyNames)
481
481
(shakeExtras, stopProgressReporting) <- do
@@ -487,23 +487,23 @@ shakeOpen lspEnv defaultConfig logger debouncer
487
487
positionMapping <- newVar HMap. empty
488
488
knownTargetsVar <- newVar $ hashed HMap. empty
489
489
let restartShakeSession = shakeRestart ideState
490
- mostRecentProgressEvent <- newTVarIO KickCompleted
491
490
persistentKeys <- newVar HMap. empty
492
- let progressUpdate = atomically . writeTVar mostRecentProgressEvent
493
491
indexPending <- newTVarIO HMap. empty
494
492
indexCompleted <- newTVarIO 0
495
493
indexProgressToken <- newVar Nothing
496
494
let hiedbWriter = HieDbWriter {.. }
497
- progressAsync <- async $
498
- when reportProgress $
499
- progressThread optProgressStyle mostRecentProgressEvent inProgress
500
495
exportsMap <- newVar mempty
501
496
497
+ ProgressReporting {.. } <-
498
+ if inProgress
499
+ then delayedProgressReporting lspEnv optProgressStyle
500
+ else noProgressReporting
502
501
actionQueue <- newQueue
503
502
504
503
let clientCapabilities = maybe def LSP. resClientCapabilities lspEnv
504
+ extras = ShakeExtras {.. }
505
505
506
- pure (ShakeExtras { .. }, cancel progressAsync )
506
+ pure (extras, progressStop )
507
507
(shakeDbM, shakeClose) <-
508
508
shakeOpenDatabase
509
509
opts { shakeExtra = newShakeExtra shakeExtras }
@@ -520,6 +520,34 @@ shakeOpen lspEnv defaultConfig logger debouncer
520
520
startTelemetry otProfilingEnabled logger $ state shakeExtras
521
521
522
522
return ideState
523
+
524
+ data ProgressReporting = ProgressReporting
525
+ { progressUpdate :: ProgressEvent -> IO ()
526
+ , inProgress :: forall a . NormalizedFilePath -> Action a -> Action a
527
+ , progressStop :: IO ()
528
+ }
529
+
530
+ noProgressReporting :: IO ProgressReporting
531
+ noProgressReporting = return $ ProgressReporting
532
+ { progressUpdate = const $ pure ()
533
+ , inProgress = const id
534
+ , progressStop = pure ()
535
+ }
536
+
537
+ delayedProgressReporting
538
+ :: Maybe (LSP. LanguageContextEnv c )
539
+ -> ProgressReportingStyle
540
+ -> IO ProgressReporting
541
+ delayedProgressReporting lspEnv optProgressStyle = do
542
+ inProgressVar <- newVar HMap. empty
543
+ mostRecentProgressEvent <- newTVarIO KickCompleted
544
+ progressAsync <- async $
545
+ progressThread optProgressStyle mostRecentProgressEvent inProgressVar
546
+ let progressUpdate = atomically . writeTVar mostRecentProgressEvent
547
+ progressStop = cancel progressAsync
548
+ inProgress :: NormalizedFilePath -> Action a -> Action a
549
+ inProgress = withProgressVar inProgressVar
550
+ return ProgressReporting {.. }
523
551
where
524
552
-- The progress thread is a state machine with two states:
525
553
-- 1. Idle
@@ -550,7 +578,7 @@ shakeOpen lspEnv defaultConfig logger debouncer
550
578
lspShakeProgress = do
551
579
-- first sleep a bit, so we only show progress messages if it's going to take
552
580
-- a "noticable amount of time" (we often expect a thread kill to arrive before the sleep finishes)
553
- liftIO $ unless testing $ sleep 0.1
581
+ liftIO $ sleep 0.1
554
582
u <- ProgressTextToken . T. pack . show . hashUnique <$> liftIO newUnique
555
583
556
584
void $ LSP. sendRequest LSP. SWindowWorkDoneProgressCreate
@@ -608,6 +636,12 @@ shakeOpen lspEnv defaultConfig logger debouncer
608
636
}
609
637
loop id next
610
638
639
+ withProgressVar var file = actionBracket (f succ ) (const $ f pred ) . const
640
+ -- This functions are deliberately eta-expanded to avoid space leaks.
641
+ -- Do not remove the eta-expansion without profiling a session with at
642
+ -- least 1000 modifications.
643
+ where f shift = void $ modifyVar' var $ HMap. insertWith (\ _ x -> shift x) file (shift 0 )
644
+
611
645
-- | Must be called in the 'Initialized' handler and only once
612
646
shakeSessionInit :: IdeState -> IO ()
613
647
shakeSessionInit IdeState {.. } = do
@@ -952,7 +986,7 @@ defineEarlyCutoff'
952
986
defineEarlyCutoff' doDiagnostics key file old mode action = do
953
987
extras@ ShakeExtras {state, inProgress, logger} <- getShakeExtras
954
988
options <- getIdeOptions
955
- (if optSkipProgress options key then id else withProgressVar inProgress file) $ do
989
+ (if optSkipProgress options key then id else inProgress file) $ do
956
990
val <- case old of
957
991
Just old | mode == RunDependenciesSame -> do
958
992
v <- liftIO $ getValues state key file
@@ -1001,13 +1035,6 @@ defineEarlyCutoff' doDiagnostics key file old mode action = do
1001
1035
A res
1002
1036
where
1003
1037
1004
- withProgressVar :: (Eq a , Hashable a ) => Var (HMap. HashMap a Int ) -> a -> Action b -> Action b
1005
- withProgressVar var file = actionBracket (f succ ) (const $ f pred ) . const
1006
- -- This functions are deliberately eta-expanded to avoid space leaks.
1007
- -- Do not remove the eta-expansion without profiling a session with at
1008
- -- least 1000 modifications.
1009
- where f shift = void $ modifyVar' var $ HMap. insertWith (\ _ x -> shift x) file (shift 0 )
1010
-
1011
1038
isSuccess :: RunResult (A v ) -> Bool
1012
1039
isSuccess (RunResult _ _ (A Failed {})) = False
1013
1040
isSuccess _ = True
0 commit comments