on de35c8f help sign in
95 lines 3.3 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 Control.Monad.Except
24import Development.IDE.Types.Options (IdeOptions(..))
25import Development.IDE.Core.FileStore
26import Development.IDE.Core.OfInterest
27import Development.IDE.Types.Logger
28import Development.Shake
29import Data.Either.Extra
30import qualified Language.Haskell.LSP.Messages as LSP
32import Development.IDE.Core.Shake
36newtype GlobalIdeOptions = GlobalIdeOptions IdeOptions
37instance IsIdeGlobal GlobalIdeOptions
39------------------------------------------------------------
40-- Exposed API
42-- | Initialise the Compiler Service.
43initialise :: Rules ()
44 -> (LSP.FromServerMessage -> IO ())
45 -> Logger
46 -> IdeOptions
47 -> VFSHandle
48 -> IO IdeState
49initialise mainRule toDiags logger options vfs =
50 shakeOpen
51 toDiags
52 logger
53 (optShakeProfiling options)
54 (optReportProgress options)
55 (shakeOptions { shakeThreads = optThreads options
56 , shakeFiles = "/dev/null"
57 }) $ do
58 addIdeGlobal $ GlobalIdeOptions options
59 fileStoreRules vfs
60 ofInterestRules
61 mainRule
63writeProfile :: IdeState -> FilePath -> IO ()
64writeProfile = shakeProfile
66-- | Shutdown the Compiler Service.
67shutdown :: IdeState -> IO ()
68shutdown = shakeShut
70-- This will return as soon as the result of the action is
71-- available. There might still be other rules running at this point,
72-- e.g., the ofInterestRule.
73runAction :: IdeState -> Action a -> IO a
74runAction ide action = do
75 bar <- newBarrier
76 res <- shakeRun ide [do v <- action; liftIO $ signalBarrier bar v; return v]
77 -- shakeRun might throw an exception (either through action or a default rule),
78 -- in which case action may not complete successfully, and signalBarrier might not be called.
79 -- Therefore we wait for either res (which propagates the exception) or the barrier.
80 -- Importantly, if the barrier does finish, cancelling res only kills waiting for the result,
81 -- it doesn't kill the actual work
82 fmap fromEither $ race (head <$> res) $ waitBarrier bar
85-- | `runActionSync` is similar to `runAction` but it will
86-- wait for all rules (so in particular the `ofInterestRule`) to
87-- finish running. This is mainly useful in tests, where you want
88-- to wait for all rules to fire so you can check diagnostics.
89runActionSync :: IdeState -> Action a -> IO a
90runActionSync s act = fmap head $ join $ shakeRun s [act]
92getIdeOptions :: Action IdeOptions
93getIdeOptions = do
94 GlobalIdeOptions x <- getIdeGlobalAction
95 return x