@@ -441,7 +441,13 @@ handle logger m msg =
441441 SMethod_WorkspaceDidChangeConfiguration -> handle' logger (Just $ handleDidChangeConfiguration logger) m msg
442442 -- See Note [LSP configuration]
443443 SMethod_Initialized -> handle' logger (Just $ \ _ -> initialDynamicRegistrations logger >> requestConfigUpdate (cmap (fmap LspCore ) logger)) m msg
444- SMethod_Exit -> exitNotificationHandler logger msg
444+ SMethod_Exit -> handle' logger (Just $ \ _ -> signalExit) m msg
445+ where
446+ signalExit :: LspM config ()
447+ signalExit = do
448+ logger <& Exiting `WithSeverity ` Info
449+ b <- resExit . resState <$> getLspEnv
450+ liftIO $ signalBarrier b ()
445451 SMethod_Shutdown -> handle' logger (Just $ \ _ -> signalShutdown) m msg
446452 where
447453 -- See Note [Shutdown]
@@ -468,9 +474,18 @@ handle' ::
468474 m ()
469475handle' logger mAction m msg = do
470476 shutdown <- isShuttingDown
477+ -- These are the methods that we are allowed to process during shutdown.
478+ -- The reason that we do not include 'shutdown' itself here is because
479+ -- by the time we get the first 'shutdown' message, isShuttingDown will
480+ -- still be false, so we would still be able to process it.
481+ -- This ensures we won't process the second 'shutdown' message and only
482+ -- process 'exit' during shutdown.
483+ let allowedMethod m = case (splitClientMethod m, m) of
484+ (IsClientNot , SMethod_Exit ) -> True
485+ _ -> False
471486
472487 case mAction of
473- Just f | not shutdown -> f msg
488+ Just f | not shutdown || allowedMethod m -> f msg
474489 _ -> pure ()
475490
476491 dynReqHandlers <- getsState resRegistrationsReq
@@ -481,12 +496,14 @@ handle' logger mAction m msg = do
481496
482497 case splitClientMethod m of
483498 -- See Note [Shutdown]
484- IsClientNot | shutdown -> notificationDuringShutdown
499+ IsClientNot | shutdown, not (allowedMethod m) -> notificationDuringShutdown
485500 IsClientNot -> case pickHandler dynNotHandlers notHandlers of
486501 Just h -> liftIO $ h msg
487- Nothing | otherwise -> missingNotificationHandler
502+ Nothing
503+ | SMethod_Exit <- m -> exitNotificationHandler logger msg
504+ | otherwise -> missingNotificationHandler
488505 -- See Note [Shutdown]
489- IsClientReq | shutdown -> requestDuringShutdown msg
506+ IsClientReq | shutdown, not (allowedMethod m) -> requestDuringShutdown msg
490507 IsClientReq -> case pickHandler dynReqHandlers reqHandlers of
491508 Just h -> liftIO $ h msg (runLspT env . sendResponse msg)
492509 Nothing
@@ -547,11 +564,10 @@ progressCancelHandler logger (TNotificationMessage _ _ (WorkDoneProgressCancelPa
547564 logger <& ProgressCancel tid `WithSeverity ` Debug
548565 liftIO cancelAction
549566
550- exitNotificationHandler :: (MonadIO m , MonadLsp config0 m ) => LogAction m (WithSeverity LspProcessingLog ) -> Handler m Method_Exit
551- exitNotificationHandler logger _ = do
552- logger <& Exiting `WithSeverity ` Info
553- b <- resExit . resState <$> getLspEnv
554- liftIO $ signalBarrier b ()
567+ exitNotificationHandler :: (MonadIO m ) => LogAction m (WithSeverity LspProcessingLog ) -> Handler m Method_Exit
568+ exitNotificationHandler _logger _ = do
569+ -- default exit handler do nothing
570+ return ()
555571
556572-- | Default Shutdown handler
557573shutdownRequestHandler :: Handler IO Method_Shutdown
0 commit comments