1
- module Development.IDE.Main (Arguments (.. ), defaultMain ) where
1
+ module Development.IDE.Main
2
+ (Arguments (.. )
3
+ ,Command (.. )
4
+ ,defaultMain
5
+ ) where
2
6
import Control.Concurrent.Extra (newLock , readVar ,
3
7
withLock )
4
8
import Control.Exception.Safe (Exception (displayException ),
5
9
catchAny )
6
10
import Control.Monad.Extra (concatMapM , unless ,
7
11
when )
12
+ import Control.Monad.IO.Class
8
13
import Data.Default (Default (def ))
14
+ import Data.Foldable (toList )
9
15
import qualified Data.HashMap.Strict as HashMap
10
16
import Data.Hashable (hashed )
11
17
import Data.List.Extra (intercalate , isPrefixOf ,
12
18
nub , nubOrd , partition )
13
19
import Data.Maybe (catMaybes , fromMaybe ,
14
- isJust )
20
+ isJust , isNothing )
15
21
import qualified Data.Text as T
16
22
import qualified Data.Text.IO as T
17
- import Development.IDE (Action , Rules ,
18
- hDuplicateTo' )
23
+ import Development.IDE (Action ,
24
+ GetKnownTargets (GetKnownTargets ),
25
+ GetModIfaceFromDiskAndIndex (GetModIfaceFromDiskAndIndex ),
26
+ Rules , hDuplicateTo' )
19
27
import Development.IDE.Core.Debouncer (Debouncer ,
20
28
newAsyncDebouncer )
21
29
import Development.IDE.Core.FileStore (makeVFSHandle )
@@ -34,7 +42,8 @@ import Development.IDE.Core.Rules (GhcSessionIO (GhcSession
34
42
import Development.IDE.Core.Service (initialise , runAction )
35
43
import Development.IDE.Core.Shake (IdeState (shakeExtras ),
36
44
ShakeExtras (state ),
37
- uses )
45
+ toKnownFiles ,
46
+ useNoFile_ , uses )
38
47
import Development.IDE.Core.Tracing (measureMemory )
39
48
import Development.IDE.LSP.LanguageServer (runLanguageServer )
40
49
import Development.IDE.Plugin (Plugin (pluginHandlers , pluginRules ))
@@ -57,6 +66,7 @@ import Development.Shake (action)
57
66
import GHC.IO.Encoding (setLocaleEncoding )
58
67
import GHC.IO.Handle (hDuplicate )
59
68
import HIE.Bios.Cradle (findCradle )
69
+ import qualified HieDb.Run as HieDb
60
70
import Ide.Plugin.Config (CheckParents (NeverCheck ),
61
71
Config ,
62
72
getConfigFromNotification )
@@ -80,9 +90,15 @@ import System.Time.Extra (offsetTime,
80
90
showDuration )
81
91
import Text.Printf (printf )
82
92
93
+ data Command
94
+ = Lsp -- ^ Run the LSP server
95
+ | Check [FilePath ] -- ^ Typecheck some paths and print diagnostics. Exit code is the number of failures
96
+ | Index FilePath -- ^ Index the whole project and print the path to the database
97
+ | Db FilePath HieDb. Options HieDb. Command -- ^ Run a command in the hiedb
98
+
83
99
data Arguments = Arguments
84
100
{ argsOTMemoryProfiling :: Bool
85
- , argFiles :: Maybe [ FilePath ] -- ^ Nothing: lsp server ; Just: typecheck and exit
101
+ , argCommand :: Command
86
102
, argsLogger :: IO Logger
87
103
, argsRules :: Rules ()
88
104
, argsHlsPlugins :: IdePlugins IdeState
@@ -100,7 +116,7 @@ data Arguments = Arguments
100
116
instance Default Arguments where
101
117
def = Arguments
102
118
{ argsOTMemoryProfiling = False
103
- , argFiles = Nothing
119
+ , argCommand = Lsp
104
120
, argsLogger = stderrLogger
105
121
, argsRules = mainRule >> action kick
106
122
, argsGhcidePlugin = mempty
@@ -153,8 +169,8 @@ defaultMain Arguments{..} = do
153
169
inH <- argsHandleIn
154
170
outH <- argsHandleOut
155
171
156
- case argFiles of
157
- Nothing -> do
172
+ case argCommand of
173
+ Lsp -> do
158
174
t <- offsetTime
159
175
hPutStrLn stderr " Starting LSP server..."
160
176
hPutStrLn stderr " If you are seeing this in a terminal, you probably should have run ghcide WITHOUT the --lsp option!"
@@ -188,7 +204,7 @@ defaultMain Arguments{..} = do
188
204
vfs
189
205
hiedb
190
206
hieChan
191
- Just argFiles -> do
207
+ Check argFiles -> do
192
208
dir <- IO. getCurrentDirectory
193
209
dbLoc <- getHieDbLoc dir
194
210
runWithDb dbLoc $ \ hiedb hieChan -> do
@@ -249,8 +265,35 @@ defaultMain Arguments{..} = do
249
265
measureMemory logger [keys] consoleObserver valuesRef
250
266
251
267
unless (null failed) (exitWith $ ExitFailure (length failed))
268
+ Index dir -> do
269
+ dbLoc <- getHieDbLoc dir
270
+ runWithDb dbLoc $ \ hiedb hieChan -> do
271
+ vfs <- makeVFSHandle
272
+ sessionLoader <- loadSessionWithOptions argsSessionLoadingOptions dir
273
+ let options = (argsIdeOptions argsDefaultHlsConfig sessionLoader)
274
+ { optCheckParents = pure NeverCheck
275
+ , optCheckProject = pure False
276
+ }
277
+ ide <- initialise argsDefaultHlsConfig rules Nothing logger debouncer options vfs hiedb hieChan
278
+ registerIdeConfiguration (shakeExtras ide) $ IdeConfiguration mempty (hashed Nothing )
279
+ results <- runAction " Index" ide $ do
280
+ allKnownTargets <- toKnownFiles <$> useNoFile_ GetKnownTargets
281
+ liftIO $ hPutStrLn stderr $ " Found " <> show (length allKnownTargets) <> " targets"
282
+ uses GetModIfaceFromDiskAndIndex $ toList allKnownTargets
283
+ putStrLn dbLoc
284
+ let nfailures = length $ filter isNothing results
285
+ unless (nfailures == 0 ) $ exitWith $ ExitFailure nfailures
286
+ Db dir opts cmd -> do
287
+ dbLoc <- getHieDbLoc dir
288
+ hPutStrLn stderr $ " Using hiedb at: " ++ dbLoc
289
+ mlibdir <- setInitialDynFlags def
290
+ case mlibdir of
291
+ Nothing -> exitWith $ ExitFailure 1
292
+ Just libdir -> HieDb. runCommand libdir opts{HieDb. database = dbLoc} cmd
293
+
252
294
{-# ANN defaultMain ("HLint: ignore Use nubOrd" :: String) #-}
253
295
296
+
254
297
expandFiles :: [FilePath ] -> IO [FilePath ]
255
298
expandFiles = concatMapM $ \ x -> do
256
299
b <- IO. doesFileExist x
0 commit comments