13
13
module Main (main ) where
14
14
15
15
import Arguments
16
+ import Control.Concurrent.Async
16
17
import Control.Concurrent.Extra
17
18
import Control.Exception
18
19
import Control.Monad.Extra
@@ -48,7 +49,7 @@ import Development.IDE.Types.Diagnostics
48
49
import Development.IDE.Types.Location
49
50
import Development.IDE.Types.Logger
50
51
import Development.IDE.Types.Options
51
- import Development.Shake (Action , action )
52
+ import Development.Shake (Action )
52
53
import DynFlags (gopt_set , gopt_unset ,
53
54
updOptLevel )
54
55
import DynFlags (PackageFlag (.. ), PackageArg (.. ))
@@ -190,11 +191,11 @@ main = do
190
191
{ optReportProgress = clientSupportsProgress caps
191
192
, optShakeProfiling = argsShakeProfiling
192
193
, optTesting = argsTesting
194
+ , optThreads = argsThreads
193
195
, optInterfaceLoadingDiagnostics = argsTesting
194
- , optThreads = argsThread
195
196
}
196
197
debouncer <- newAsyncDebouncer
197
- initialise caps (mainRule >> pluginRules plugins >> action kick )
198
+ initialise caps (mainRule >> pluginRules plugins)
198
199
getLspId event hlsLogger debouncer options vfs
199
200
else do
200
201
-- GHC produces messages with UTF8 in them, so make sure the terminal doesn't error
@@ -223,7 +224,7 @@ main = do
223
224
224
225
putStrLn " \n Step 4/6: Type checking the files"
225
226
setFilesOfInterest ide $ HashSet. fromList $ map toNormalizedFilePath' files
226
- _ <- runActionSync ide $ uses TypeCheck (map toNormalizedFilePath' files)
227
+ _ <- runActionSync " TypecheckTest " ide $ uses TypeCheck (map toNormalizedFilePath' files)
227
228
-- results <- runActionSync ide $ use TypeCheck $ toNormalizedFilePath' "src/Development/IDE/Core/Rules.hs"
228
229
-- results <- runActionSync ide $ use TypeCheck $ toNormalizedFilePath' "exe/Main.hs"
229
230
return ()
@@ -240,11 +241,13 @@ expandFiles = concatMapM $ \x -> do
240
241
fail $ " Couldn't find any .hs/.lhs files inside directory: " ++ x
241
242
return files
242
243
243
-
244
+ -- Running this every hover is too expensive, 0.2s on GHC for example
245
+ {-
244
246
kick :: Action ()
245
247
kick = do
246
248
files <- getFilesOfInterest
247
249
void $ uses TypeCheck $ HashSet.toList files
250
+ -}
248
251
249
252
-- | Print an LSP event.
250
253
showEvent :: Lock -> FromServerMessage -> IO ()
@@ -408,7 +411,6 @@ loadSession dir = liftIO $ do
408
411
return res
409
412
410
413
lock <- newLock
411
- cradle_lock <- newLock
412
414
413
415
-- This caches the mapping from hie.yaml + Mod.hs -> [String]
414
416
sessionOpts <- return $ \ (hieYaml, file) -> do
@@ -435,17 +437,39 @@ loadSession dir = liftIO $ do
435
437
finished_barrier <- newBarrier
436
438
-- fork a new thread here which won't be killed by shake
437
439
-- throwing an async exception
438
- void $ forkIO $ withLock cradle_lock $ do
439
- putStrLn $ " Shelling out to cabal " <> show file
440
+ void $ forkIO $ do
441
+ putStrLn $ " Consulting the cradle for " <> show file
440
442
cradle <- maybe (loadImplicitCradle $ addTrailingPathSeparator dir) loadCradle hieYaml
441
443
opts <- cradleToSessionOpts cradle cfp
442
444
print opts
443
445
res <- fst <$> session (hieYaml, toNormalizedFilePath' cfp, opts)
444
446
signalBarrier finished_barrier res
445
447
waitBarrier finished_barrier
446
- return $ \ file -> liftIO $ mask_ $ withLock lock $ do
447
- hieYaml <- cradleLoc file
448
- sessionOpts (hieYaml, file)
448
+
449
+ dummyAs <- async $ return (error " Uninitialised" )
450
+ runningCradle <- newIORef dummyAs
451
+ -- The main function which gets options for a file. We only want one of these running
452
+ -- at a time.
453
+ let getOptions file = do
454
+ hieYaml <- cradleLoc file
455
+ sessionOpts (hieYaml, file)
456
+ -- The lock is on the `runningCradle` resource
457
+ return $ \ file -> liftIO $ withLock lock $ do
458
+ as <- readIORef runningCradle
459
+ finished <- poll as
460
+ case finished of
461
+ Just {} -> do
462
+ as <- async $ getOptions file
463
+ writeIORef runningCradle as
464
+ wait as
465
+ -- If it's not finished then wait and then get options, this could of course be killed still
466
+ Nothing -> do
467
+ _ <- wait as
468
+ getOptions file
469
+
470
+
471
+
472
+
449
473
450
474
checkDependencyInfo :: Map. Map FilePath (Maybe UTCTime ) -> IO Bool
451
475
checkDependencyInfo old_di = do
0 commit comments