on debug help sign in
107 lines 3.7 kB history raw
1-- Copyright (c) 2019 The DAML Authors. All rights reserved.
2-- SPDX-License-Identifier: Apache-2.0
4{-# LANGUAGE TypeFamilies #-}
5{-# LANGUAGE FlexibleInstances #-}
7-- | A Shake implementation of the compiler service, built
8-- using the "Shaker" abstraction layer for in-memory use.
9--
10module Development.IDE.Core.Service(
11 getIdeOptions,
12 IdeState, initialise, shutdown,
13 runAction,
14 runActionSync,
15 writeProfile,
16 getDiagnostics, unsafeClearDiagnostics,
17 ideLogger,
18 updatePositionMapping,
19 ) where
21import Control.Concurrent.Extra
22import Control.Concurrent.Async
23import Data.Maybe
24import Development.IDE.Types.Options (IdeOptions(..))
25import Control.Monad
26import Development.IDE.Core.Debouncer
27import Development.IDE.Core.FileStore (VFSHandle, fileStoreRules)
28import Development.IDE.Core.FileExists (fileExistsRules)
29import Development.IDE.Core.OfInterest
30import Development.IDE.Types.Logger
31import Development.Shake
32import Data.Either.Extra
33import qualified Language.Haskell.LSP.Messages as LSP
34import qualified Language.Haskell.LSP.Types as LSP
35import qualified Language.Haskell.LSP.Types.Capabilities as LSP
37import Development.IDE.Core.Shake
41newtype GlobalIdeOptions = GlobalIdeOptions IdeOptions
42instance IsIdeGlobal GlobalIdeOptions
44------------------------------------------------------------
45-- Exposed API
47-- | Initialise the Compiler Service.
48initialise :: LSP.ClientCapabilities
49 -> Rules ()
50 -> IO LSP.LspId
51 -> (LSP.FromServerMessage -> IO ())
52 -> Logger
53 -> Debouncer LSP.NormalizedUri
54 -> IdeOptions
55 -> VFSHandle
56 -> IO IdeState
57initialise caps mainRule getLspId toDiags logger debouncer options vfs =
58 shakeOpen
59 getLspId
60 toDiags
61 logger
62 debouncer
63 (optShakeProfiling options)
64 (optReportProgress options)
65 shakeOptions
66 { shakeThreads = optThreads options
67 , shakeFiles = fromMaybe "/dev/null" (optShakeFiles options)
68 } $ do
69 addIdeGlobal $ GlobalIdeOptions options
70 fileStoreRules vfs
71 ofInterestRules
72 fileExistsRules getLspId caps vfs
73 mainRule
75writeProfile :: IdeState -> FilePath -> IO ()
76writeProfile = shakeProfile
78-- | Shutdown the Compiler Service.
79shutdown :: IdeState -> IO ()
80shutdown = shakeShut
82-- This will return as soon as the result of the action is
83-- available. There might still be other rules running at this point,
84-- e.g., the ofInterestRule.
85runAction :: IdeState -> Action a -> IO a
86runAction ide action = do
87 bar <- newBarrier
88 res <- shakeRun ide [do v <- action; liftIO $ signalBarrier bar v; return v]
89 -- shakeRun might throw an exception (either through action or a default rule),
90 -- in which case action may not complete successfully, and signalBarrier might not be called.
91 -- Therefore we wait for either res (which propagates the exception) or the barrier.
92 -- Importantly, if the barrier does finish, cancelling res only kills waiting for the result,
93 -- it doesn't kill the actual work
94 fmap fromEither $ race (head <$> res) $ waitBarrier bar
97-- | `runActionSync` is similar to `runAction` but it will
98-- wait for all rules (so in particular the `ofInterestRule`) to
99-- finish running. This is mainly useful in tests, where you want
100-- to wait for all rules to fire so you can check diagnostics.
101runActionSync :: IdeState -> Action a -> IO a
102runActionSync s act = fmap head $ join $ shakeRun s [act]
104getIdeOptions :: Action IdeOptions
105getIdeOptions = do
106 GlobalIdeOptions x <- getIdeGlobalAction
107 return x