on bec100b help sign in
120 lines 3.9 kB history raw
1-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2-- SPDX-License-Identifier: Apache-2.0
4{-# LANGUAGE TypeFamilies #-}
5{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE FlexibleInstances #-}
8-- | A Shake implementation of the compiler service, built
9-- using the "Shaker" abstraction layer for in-memory use.
10--
11module Development.IDE.State.Service(
12 Env(..),
13 getServiceEnv,
14 IdeState, initialise, shutdown,
15 runAction, runActions,
16 setFilesOfInterest,
17 writeProfile,
18 getDiagnostics, unsafeClearDiagnostics,
19 logDebug, logSeriousError
20 ) where
22import Control.Concurrent.Extra
23import Control.Monad.Except
24import Development.IDE.Types.Options (IdeOptions(..))
25import Development.IDE.State.FileStore
26import qualified Development.IDE.Logger as Logger
27import Data.Maybe
28import Data.Set (Set)
29import qualified Data.Set as Set
30import Development.IDE.Functions.GHCError
31import Development.Shake hiding (Diagnostic, Env, newCache)
32import Development.IDE.Types.LSP as Compiler
34import UniqSupply
36import Development.IDE.State.Shake
39-- | Environment threaded through the Shake actions.
40data Env = Env
41 { envOptions :: IdeOptions
42 -- ^ Compiler options.
43 , envOfInterestVar :: Var (Set FilePath)
44 -- ^ The files of interest.
45 , envUniqSupplyVar :: Var UniqSupply
46 -- ^ The unique supply of names used by the compiler.
47 }
48instance IsIdeGlobal Env
51mkEnv :: IdeOptions -> IO Env
52mkEnv options = do
53 ofInterestVar <- newVar Set.empty
54 uniqSupplyVar <- mkSplitUniqSupply 'a' >>= newVar
55 return Env
56 { envOptions = options
57 , envOfInterestVar = ofInterestVar
58 , envUniqSupplyVar = uniqSupplyVar
59 }
61getDiagnostics :: IdeState -> IO [FileDiagnostic]
62getDiagnostics = getAllDiagnostics
64unsafeClearDiagnostics :: IdeState -> IO ()
65unsafeClearDiagnostics = unsafeClearAllDiagnostics
68------------------------------------------------------------
69-- Exposed API
71-- | Initialise the Compiler Service.
72initialise :: Rules ()
73 -> Maybe (Event -> IO ())
74 -> Logger.Handle
75 -> IdeOptions
76 -> IO IdeState
77initialise mainRule toDiags logger options =
78 shakeOpen
79 (fromMaybe (const $ pure ()) toDiags)
80 logger
81 (setProfiling options $
82 shakeOptions { shakeThreads = optThreads options
83 , shakeFiles = "/dev/null"
84 }) $ do
85 addIdeGlobal =<< liftIO (mkEnv options)
86 fileStoreRules
87 mainRule
89writeProfile :: IdeState -> FilePath -> IO ()
90writeProfile = shakeProfile
92setProfiling :: IdeOptions -> ShakeOptions -> ShakeOptions
93setProfiling opts shakeOpts =
94 maybe shakeOpts (\p -> shakeOpts { shakeReport = [p], shakeTimings = True }) (optShakeProfiling opts)
96-- | Shutdown the Compiler Service.
97shutdown :: IdeState -> IO ()
98shutdown = shakeShut
100-- | Run a single action using the supplied service.
101runAction :: IdeState -> Action a -> IO a
102runAction service action = head <$> runActions service [action]
104-- | Run a list of actions in parallel using the supplied service.
105runActions :: IdeState -> [Action a] -> IO [a]
106runActions x = join . shakeRun x
109-- | Set the files-of-interest which will be built and kept-up-to-date.
110setFilesOfInterest :: IdeState -> Set FilePath -> IO ()
111setFilesOfInterest state files = do
112 Env{..} <- getIdeGlobalState state
113 -- update vars synchronously
114 modifyVar_ envOfInterestVar $ const $ return files
116 -- run shake to update results regarding the files of interest
117 void $ shakeRun state []
119getServiceEnv :: Action Env
120getServiceEnv = getIdeGlobalAction