8
8
module Main (main ) where
9
9
10
10
import Arguments
11
- import Data.Functor ((<&>) )
12
11
import Data.Maybe
13
12
import Data.List.Extra
14
13
import System.FilePath
15
14
import Control.Concurrent.Extra
16
15
import Control.Exception
17
16
import Control.Monad.Extra
18
17
import Control.Monad.IO.Class
19
- import qualified Crypto.Hash.SHA1 as H
20
- import qualified Data.ByteString.Char8 as B
21
- import Data.ByteString.Base16
22
18
import Data.Default
23
19
import System.Time.Extra
24
20
import Development.IDE.Core.Debouncer
@@ -41,7 +37,6 @@ import qualified Data.Text as T
41
37
import qualified Data.Text.IO as T
42
38
import Language.Haskell.LSP.Messages
43
39
import Language.Haskell.LSP.Types (LspId (IdInt ))
44
- import Linker
45
40
import Data.Version
46
41
import Development.IDE.LSP.LanguageServer
47
42
import qualified System.Directory.Extra as IO
@@ -50,35 +45,13 @@ import System.IO
50
45
import System.Exit
51
46
import Paths_ghcide
52
47
import Development.GitRev
53
- import Development.Shake (doesDirectoryExist , Action , Rules , action , doesFileExist , need )
48
+ import Development.Shake (Action , Rules , action )
54
49
import qualified Data.HashSet as HashSet
55
50
import qualified Data.Map.Strict as Map
56
-
57
- import GHC hiding (def )
58
- import qualified GHC.Paths
59
- import DynFlags
60
-
61
- import HIE.Bios.Environment
62
51
import HIE.Bios
63
- import HIE.Bios.Cradle
64
- import HIE.Bios.Types
52
+ import Rules
65
53
import RuleTypes
66
54
67
- -- Prefix for the cache path
68
- cacheDir :: String
69
- cacheDir = " ghcide"
70
-
71
- -- Set the GHC libdir to the nix libdir if it's present.
72
- getLibdir :: IO FilePath
73
- getLibdir = fromMaybe GHC.Paths. libdir <$> lookupEnv " NIX_GHC_LIBDIR"
74
-
75
- getCacheDir :: [String ] -> IO FilePath
76
- getCacheDir opts = IO. getXdgDirectory IO. XdgCache (cacheDir </> opts_hash)
77
- where
78
- -- Create a unique folder per set of different GHC options, assuming that each different set of
79
- -- GHC options will create incompatible interface files.
80
- opts_hash = B. unpack $ encode $ H. finalize $ H. updates H. init (map B. pack opts)
81
-
82
55
ghcideVersion :: IO String
83
56
ghcideVersion = do
84
57
path <- getExecutablePath
@@ -122,6 +95,7 @@ main = do
122
95
let options = (defaultIdeOptions $ loadSession dir)
123
96
{ optReportProgress = clientSupportsProgress caps
124
97
, optShakeProfiling = argsShakeProfiling
98
+ , optTesting = IdeTesting argsTesting
125
99
}
126
100
debouncer <- newAsyncDebouncer
127
101
initialise caps (cradleRules >> mainRule >> pluginRules plugins >> action kick)
@@ -177,7 +151,7 @@ main = do
177
151
178
152
cradleRules :: Rules ()
179
153
cradleRules = do
180
- loadGhcSessionIO
154
+ loadGhcSession
181
155
cradleToSession
182
156
183
157
expandFiles :: [FilePath ] -> IO [FilePath ]
@@ -205,93 +179,6 @@ showEvent lock (EventFileDiagnostics (toNormalizedFilePath -> file) diags) =
205
179
withLock lock $ T. putStrLn $ showDiagnosticsColored $ map (file,ShowDiag ,) diags
206
180
showEvent lock e = withLock lock $ print e
207
181
208
- loadGhcSessionIO :: Rules ()
209
- loadGhcSessionIO =
210
- -- This rule is for caching the GHC session. E.g., even when the cabal file
211
- -- changed, if the resulting flags did not change, we would continue to use
212
- -- the existing session.
213
- defineNoFile $ \ (GetHscEnv opts deps) ->
214
- liftIO $ createSession $ ComponentOptions opts deps
215
-
216
- getComponentOptions :: Cradle a -> IO ComponentOptions
217
- getComponentOptions cradle = do
218
- let showLine s = putStrLn (" > " ++ s)
219
- -- WARNING 'runCradle is very expensive and must be called as few times as possible
220
- cradleRes <- runCradle (cradleOptsProg cradle) showLine " "
221
- case cradleRes of
222
- CradleSuccess r -> pure r
223
- CradleFail err -> throwIO err
224
- -- TODO Rather than failing here, we should ignore any files that use this cradle.
225
- -- That will require some more changes.
226
- CradleNone -> fail " 'none' cradle is not yet supported"
227
-
228
-
229
- createSession :: ComponentOptions -> IO HscEnvEq
230
- createSession (ComponentOptions theOpts _) = do
231
- libdir <- getLibdir
232
-
233
- cacheDir <- Main. getCacheDir theOpts
234
-
235
- env <- runGhc (Just libdir) $ do
236
- dflags <- getSessionDynFlags
237
- (dflags', _targets) <- addCmdOpts theOpts dflags
238
- _ <- setSessionDynFlags $
239
- -- disabled, generated directly by ghcide instead
240
- flip gopt_unset Opt_WriteInterface $
241
- -- disabled, generated directly by ghcide instead
242
- -- also, it can confuse the interface stale check
243
- dontWriteHieFiles $
244
- setHiDir cacheDir $
245
- setDefaultHieDir cacheDir $
246
- setIgnoreInterfacePragmas $
247
- setLinkerOptions $
248
- disableOptimisation dflags'
249
- getSession
250
- initDynLinker env
251
- newHscEnvEq env
252
-
253
- -- we don't want to generate object code so we compile to bytecode
254
- -- (HscInterpreted) which implies LinkInMemory
255
- -- HscInterpreted
256
- setLinkerOptions :: DynFlags -> DynFlags
257
- setLinkerOptions df = df {
258
- ghcLink = LinkInMemory
259
- , hscTarget = HscNothing
260
- , ghcMode = CompManager
261
- }
262
-
263
- setIgnoreInterfacePragmas :: DynFlags -> DynFlags
264
- setIgnoreInterfacePragmas df =
265
- gopt_set (gopt_set df Opt_IgnoreInterfacePragmas ) Opt_IgnoreOptimChanges
266
-
267
- disableOptimisation :: DynFlags -> DynFlags
268
- disableOptimisation df = updOptLevel 0 df
269
-
270
- setHiDir :: FilePath -> DynFlags -> DynFlags
271
- setHiDir f d =
272
- -- override user settings to avoid conflicts leading to recompilation
273
- d { hiDir = Just f}
274
-
275
- cradleToSession :: Rules ()
276
- cradleToSession = define $ \ LoadCradle nfp -> do
277
- let f = fromNormalizedFilePath nfp
278
-
279
- -- If the path points to a directory, load the implicit cradle
280
- mbYaml <- doesDirectoryExist f <&> \ isDir -> if isDir then Nothing else Just f
281
- cradle <- liftIO $ maybe (loadImplicitCradle $ addTrailingPathSeparator f) loadCradle mbYaml
282
-
283
- cmpOpts <- liftIO $ getComponentOptions cradle
284
- let opts = componentOptions cmpOpts
285
- deps = componentDependencies cmpOpts
286
- deps' = case mbYaml of
287
- -- For direct cradles, the hie.yaml file itself must be watched.
288
- Just yaml | isDirectCradle cradle -> yaml : deps
289
- _ -> deps
290
- existingDeps <- filterM doesFileExist deps'
291
- need existingDeps
292
- ([] ,) . pure <$> useNoFile_ (GetHscEnv opts deps)
293
-
294
-
295
182
loadSession :: FilePath -> Action (FilePath -> Action HscEnvEq )
296
183
loadSession dir = liftIO $ do
297
184
cradleLoc <- memoIO $ \ v -> do
0 commit comments