44{-# LANGUAGE LambdaCase #-}
55{-# LANGUAGE OverloadedStrings #-}
66{-# LANGUAGE RecordWildCards #-}
7+ {-# LANGUAGE ViewPatterns #-}
78
89-- | TODO: This module should be called Launch.
910module Development.Debug.Adapter.Init where
1011
1112import qualified Data.Text as T
1213import qualified Data.Text.IO as T
1314import qualified System.Process as P
15+ import Control.Monad.Except
16+ import Control.Monad.Trans
1417import Data.Function
1518import Data.Functor
19+ import Data.Maybe
1620import Data.Version (Version (.. ), showVersion , makeVersion )
1721import Control.Monad.IO.Class
1822import System.IO
@@ -62,16 +66,16 @@ data LaunchArgs
6266 = LaunchArgs
6367 { __sessionId :: Maybe String
6468 -- ^ SessionID, set by VSCode client
65- , projectRoot :: FilePath
69+ , projectRoot :: Maybe FilePath
6670 -- ^ Absolute path to the project root
67- , entryFile :: FilePath
71+ , entryFile :: Maybe FilePath
6872 -- ^ The file with the entry point e.g. @app/Main.hs@
69- , entryPoint :: String
73+ , entryPoint :: Maybe String
7074 -- ^ Either @main@ or a function name
71- , entryArgs :: [String ]
75+ , entryArgs :: Maybe [String ]
7276 -- ^ The arguments to either set as environment arguments when @entryPoint = "main"@
7377 -- or function arguments otherwise.
74- , extraGhcArgs :: [String ]
78+ , extraGhcArgs :: Maybe [String ]
7579 -- ^ Additional arguments to pass to the GHC invocation inferred by hie-bios for this project
7680 } deriving stock (Show , Eq , Generic )
7781 deriving anyclass FromJSON
@@ -80,39 +84,53 @@ data LaunchArgs
8084-- * Launch Debugger
8185--------------------------------------------------------------------------------
8286
87+ -- | Exception type for when initialization fails
88+ newtype InitFailed = InitFailed String deriving Show
89+
8390-- | Initialize debugger
8491--
85- -- Returns @True@ if successful.
86- initDebugger :: Recorder (WithSeverity InitLog ) -> LaunchArgs -> DebugAdaptor Bool
87- initDebugger l LaunchArgs {__sessionId, projectRoot, entryFile = entryFile, entryPoint, entryArgs, extraGhcArgs} = do
92+ -- Returns @()@ if successful, throws @InitFailed@ otherwise
93+ initDebugger :: Recorder (WithSeverity InitLog ) -> LaunchArgs -> ExceptT InitFailed DebugAdaptor ()
94+ initDebugger l LaunchArgs { __sessionId
95+ , projectRoot = givenRoot
96+ , entryFile = entryFileMaybe
97+ , entryPoint = fromMaybe " main" -> entryPoint
98+ , entryArgs = fromMaybe [] -> entryArgs
99+ , extraGhcArgs = fromMaybe [] -> extraGhcArgs
100+ } = do
88101 syncRequests <- liftIO newEmptyMVar
89102 syncResponses <- liftIO newEmptyMVar
103+
104+ entryFile <- case entryFileMaybe of
105+ Nothing -> throwError $ InitFailed " Missing \" entryFile\" key in debugger configuration"
106+ Just ef -> pure ef
107+
108+ projectRoot <- maybe (liftIO getCurrentDirectory) pure givenRoot
109+
90110 let hieBiosLogger = cmapWithSev FlagsLog l
91111 cradle <- liftIO (hieBiosCradle hieBiosLogger projectRoot entryFile) >>=
92112 \ case
93- Left e ->
94- exitWithMsg e
95-
113+ Left e -> throwError $ InitFailed e
96114 Right c -> pure c
97115
98- Output. console $ T. pack " Checking GHC version against debugger version..."
116+ lift $ Output. console $ T. pack " Checking GHC version against debugger version..."
99117 -- GHC is found in PATH (by hie-bios as well).
100118 actualVersion <- liftIO (hieBiosRuntimeGhcVersion hieBiosLogger cradle) >>=
101119 \ case
102- Left e ->
103- exitWithMsg e
120+ Left e -> throwError $ InitFailed e
104121 Right c -> pure c
105122 -- Compare the GLASGOW_HASKELL version (e.g. 913) with the actualVersion (e.g. 9.13.1):
106123 when (compileTimeGhcWithoutPatchVersion /= forgetPatchVersion actualVersion) $ do
107- exitWithMsg $ " Aborting...! The GHC version must be the same which " ++
108- " ghc-debug-adapter was compiled against (" ++
109- showVersion compileTimeGhcWithoutPatchVersion++
110- " ). Instead, got " ++ (showVersion actualVersion) ++ " ."
124+ throwError $ InitFailed $
125+ " Aborting...! The GHC version must be the same which " ++
126+ " ghc-debug-adapter was compiled against (" ++
127+ showVersion compileTimeGhcWithoutPatchVersion++
128+ " ). Instead, got " ++ (showVersion actualVersion) ++ " ."
111129
112- Output. console $ T. pack " Discovering session flags with hie-bios..."
130+ lift $ Output. console $ T. pack " Discovering session flags with hie-bios..."
113131 mflags <- liftIO (hieBiosFlags hieBiosLogger cradle projectRoot entryFile)
114132 case mflags of
115- Left e -> exitWithMsg e
133+ Left e -> throwError $ InitFailed e
116134 Right flags -> do
117135
118136 let nextFreshBreakpointId = 0
@@ -138,7 +156,7 @@ initDebugger l LaunchArgs{__sessionId, projectRoot, entryFile = entryFile, entry
138156 finished_init <- liftIO $ newEmptyMVar
139157
140158 let absEntryFile = normalise $ projectRoot </> entryFile
141- registerNewDebugSession (maybe " debug-session" T. pack __sessionId) DAS {entryFile= absEntryFile,.. }
159+ lift $ registerNewDebugSession (maybe " debug-session" T. pack __sessionId) DAS {entryFile= absEntryFile,.. }
142160 [ debuggerThread l finished_init writeDebuggerOutput projectRoot flags extraGhcArgs absEntryFile defaultRunConf syncRequests syncResponses
143161 , handleDebuggerOutput readDebuggerOutput
144162 , stdoutCaptureThread
@@ -147,14 +165,13 @@ initDebugger l LaunchArgs{__sessionId, projectRoot, entryFile = entryFile, entry
147165
148166 -- Do not return until the initialization is finished
149167 liftIO (takeMVar finished_init) >>= \ case
150- Right () -> return True
168+ Right () -> pure ()
151169 Left e -> do
152170 -- The process terminates cleanly with an error code (probably exit failure = 1)
153171 -- This can happen if compilation fails and the compiler exits cleanly.
154172 --
155173 -- Instead of signalInitialized, respond with error and exit.
156- exitCleanupWithMsg readDebuggerOutput e
157- return False
174+ throwError $ InitFailed e
158175
159176-- | This thread captures stdout from the debugger and sends it to the client.
160177-- NOTE, redirecting the stdout handle is a process-global operation. So this thread
0 commit comments