66-- Stability : experimental
77-- Portability : non-portable
88----------------------------------------------------------------------------
9+ {-# LANGUAGE CPP #-}
910{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1011{-# LANGUAGE DerivingStrategies #-}
1112{-# LANGUAGE OverloadedStrings #-}
1213{-# LANGUAGE RecordWildCards #-}
1314{-# LANGUAGE DeriveAnyClass #-}
1415{-# LANGUAGE DeriveGeneric #-}
1516{-# LANGUAGE LambdaCase #-}
17+ {-# LANGUAGE OverloadedStrings #-}
1618----------------------------------------------------------------------------
1719module DAP.Adaptor
1820 ( -- * Message Construction
@@ -51,16 +53,18 @@ module DAP.Adaptor
5153 -- from child threads (useful for handling asynchronous debugger events).
5254 , runAdaptorWith
5355 , runAdaptor
56+ , withRequest
57+ , getHandle
5458 ) where
5559----------------------------------------------------------------------------
5660import Control.Concurrent.Lifted ( fork , killThread )
5761import Control.Exception ( throwIO )
5862import Control.Concurrent.STM ( atomically , readTVarIO , modifyTVar' )
59- import Control.Monad ( when , unless , void )
60- import Control.Monad.Except ( runExceptT , throwError )
63+ import Control.Monad ( when , unless )
64+ import Control.Monad.Except ( runExceptT , throwError , mapExceptT )
6165import Control.Monad.State ( runStateT , gets , gets , modify' )
6266import Control.Monad.IO.Class ( liftIO )
63- import Control.Monad.Reader ( asks , ask , runReaderT )
67+ import Control.Monad.Reader ( asks , ask , runReaderT , withReaderT )
6468import Data.Aeson ( FromJSON , Result (.. ), fromJSON )
6569import Data.Aeson.Encode.Pretty ( encodePretty )
6670import Data.Aeson.Types ( object , Key , KeyValue ((.=) ), ToJSON )
@@ -71,61 +75,55 @@ import System.IO ( Handle )
7175import qualified Data.ByteString.Lazy.Char8 as BL8
7276import qualified Data.ByteString.Char8 as BS
7377import qualified Data.HashMap.Strict as H
78+ import qualified Data.Text as T
79+ import qualified Data.Text.Encoding as TE
7480----------------------------------------------------------------------------
7581import DAP.Types
7682import DAP.Utils
83+ import DAP.Log
7784import DAP.Internal
7885----------------------------------------------------------------------------
79- logWarn :: BL8. ByteString -> Adaptor app request ()
86+ logWarn :: T. Text -> Adaptor app request ()
8087logWarn msg = logWithAddr WARN Nothing (withBraces msg)
8188----------------------------------------------------------------------------
82- logError :: BL8. ByteString -> Adaptor app request ()
89+ logError :: T. Text -> Adaptor app request ()
8390logError msg = logWithAddr ERROR Nothing (withBraces msg)
8491----------------------------------------------------------------------------
85- logInfo :: BL8. ByteString -> Adaptor app request ()
92+ logInfo :: T. Text -> Adaptor app request ()
8693logInfo msg = logWithAddr INFO Nothing (withBraces msg)
8794----------------------------------------------------------------------------
8895-- | Meant for internal consumption, used to signify a message has been
8996-- SENT from the server
90- debugMessage :: BL8. ByteString -> Adaptor app request ()
91- debugMessage msg = do
92- shouldLog <- getDebugLogging
93- addr <- getAddress
94- liftIO
95- $ when shouldLog
96- $ logger DEBUG addr ( Just SENT ) msg
97+ debugMessage :: DebugStatus -> BL8. ByteString -> Adaptor app request ()
98+ debugMessage dir msg = do
99+ #if MIN_VERSION_text(2,0,0)
100+ logWithAddr DEBUG ( Just dir) ( TE. decodeUtf8Lenient ( BL8. toStrict msg))
101+ #else
102+ logWithAddr DEBUG ( Just dir) ( TE. decodeUtf8 ( BL8. toStrict msg))
103+ #endif
97104----------------------------------------------------------------------------
98105-- | Meant for external consumption
99- logWithAddr :: Level -> Maybe DebugStatus -> BL8. ByteString -> Adaptor app request ()
106+ logWithAddr :: Level -> Maybe DebugStatus -> T. Text -> Adaptor app request ()
100107logWithAddr level status msg = do
101108 addr <- getAddress
102- liftIO (logger level addr status msg)
109+ logAction <- getLogAction
110+ liftIO (logger logAction level addr status msg)
103111----------------------------------------------------------------------------
104112-- | Meant for external consumption
105- logger :: Level -> SockAddr -> Maybe DebugStatus -> BL8. ByteString -> IO ()
106- logger level addr maybeDebug msg = do
107- liftIO
108- $ withGlobalLock
109- $ BL8. putStrLn formatted
110- where
111- formatted
112- = BL8. concat
113- [ withBraces $ BL8. pack (show addr)
114- , withBraces $ BL8. pack (show level)
115- , maybe mempty (withBraces . BL8. pack . show ) maybeDebug
116- , msg
117- ]
118- ----------------------------------------------------------------------------
119- getDebugLogging :: Adaptor app request Bool
120- getDebugLogging = asks (debugLogging . serverConfig)
113+ logger :: LogAction IO DAPLog -> Level -> SockAddr -> Maybe DebugStatus -> T. Text -> IO ()
114+ logger logAction level addr maybeDebug msg =
115+ logAction <& DAPLog level maybeDebug addr msg
121116----------------------------------------------------------------------------
122117getServerCapabilities :: Adaptor app request Capabilities
123118getServerCapabilities = asks (serverCapabilities . serverConfig)
124119----------------------------------------------------------------------------
125120getAddress :: Adaptor app request SockAddr
126121getAddress = asks address
127122----------------------------------------------------------------------------
128- getHandle :: Adaptor app request Handle
123+ getLogAction :: Adaptor app request (LogAction IO DAPLog )
124+ getLogAction = asks logAction
125+ ----------------------------------------------------------------------------
126+ getHandle :: Adaptor app r Handle
129127getHandle = asks handle
130128----------------------------------------------------------------------------
131129getRequestSeqNum :: Adaptor app Request Seq
@@ -178,7 +176,7 @@ registerNewDebugSession k v debuggerConcurrentActions = do
178176 DebuggerThreadState
179177 <$> sequence [fork $ action (runAdaptorWith lcl' emptyState) | action <- debuggerConcurrentActions]
180178 liftIO . atomically $ modifyTVar' store (H. insert k (debuggerThreadState, v))
181- logInfo $ BL8 . pack $ " Registered new debug session: " <> unpack k
179+ logInfo $ T . pack $ " Registered new debug session: " <> unpack k
182180 setDebugSessionId k
183181
184182----------------------------------------------------------------------------
@@ -220,7 +218,7 @@ destroyDebugSession = do
220218 liftIO $ do
221219 mapM_ killThread debuggerThreads
222220 atomically $ modifyTVar' store (H. delete sessionId)
223- logInfo $ BL8 . pack $ " SessionId " <> unpack sessionId <> " ended"
221+ logInfo $ T . pack $ " SessionId " <> unpack sessionId <> " ended"
224222----------------------------------------------------------------------------
225223getAppStore :: Adaptor app request (AppStore app )
226224getAppStore = asks appStore
@@ -279,8 +277,8 @@ sendEvent action = do
279277 messageType <- gets messageType
280278 address <- getAddress
281279 let errorMsg =
282- " Use 'send' function when responding to a DAP request, 'sendEvent'\
283- \ is for responding to events"
280+ " Use 'send' function when responding to a DAP request, "
281+ <> " 'sendEvent' is for responding to events"
284282 case messageType of
285283 MessageTypeResponse ->
286284 sendError (ErrorMessage errorMsg) Nothing
@@ -305,7 +303,7 @@ writeToHandle
305303 -> Adaptor app request ()
306304writeToHandle _ handle evt = do
307305 let msg = encodeBaseProtocolMessage evt
308- debugMessage (" \n " <> encodePretty evt)
306+ debugMessage SENT (" \n " <> encodePretty evt)
309307 withConnectionLock (BS. hPutStr handle msg)
310308----------------------------------------------------------------------------
311309-- | Resets Adaptor's payload
@@ -418,23 +416,26 @@ getArguments = do
418416 let msg = " No args found for this message"
419417 case maybeArgs of
420418 Nothing -> do
421- logError ( BL8. pack msg)
419+ logError msg
422420 liftIO $ throwIO (ExpectedArguments msg)
423421 Just val ->
424422 case fromJSON val of
425423 Success r -> pure r
426- x -> do
427- logError (BL8 . pack ( show x) )
428- liftIO $ throwIO (ParseException ( show x) )
424+ Error reason -> do
425+ logError (T . pack reason )
426+ liftIO $ throwIO (ParseException reason )
429427----------------------------------------------------------------------------
430428-- | Evaluates Adaptor action by using and updating the state in the MVar
431- runAdaptorWith
432- :: AdaptorLocal app request
433- -> AdaptorState
434- -> Adaptor app request ()
435- -> IO ()
436- runAdaptorWith lcl st (Adaptor action) =
437- void (runStateT (runReaderT (runExceptT action) lcl) st)
429+ runAdaptorWith :: AdaptorLocal app request -> AdaptorState -> Adaptor app request () -> IO ()
430+ runAdaptorWith lcl st (Adaptor action) = do
431+ (es,final_st) <- runStateT (runReaderT (runExceptT action) lcl) st
432+ case es of
433+ Left err -> error (" runAdaptorWith, unhandled exception:" <> show err)
434+ Right () -> case final_st of
435+ AdaptorState _ p ->
436+ if null p
437+ then return ()
438+ else error $ " runAdaptorWith, unexpected payload:" <> show p
438439----------------------------------------------------------------------------
439440-- | Utility for evaluating a monad transformer stack
440441runAdaptor :: AdaptorLocal app Request -> AdaptorState -> Adaptor app Request () -> IO ()
@@ -444,3 +445,6 @@ runAdaptor lcl s (Adaptor client) =
444445 runAdaptor lcl s' (sendErrorResponse errorMessage maybeMessage)
445446 (Right () , _) -> pure ()
446447----------------------------------------------------------------------------
448+
449+ withRequest :: Request -> Adaptor app Request a -> Adaptor app r a
450+ withRequest r (Adaptor client) = Adaptor (mapExceptT (withReaderT (\ lcl -> lcl { request = r })) client)
0 commit comments