Skip to content

Commit 980890f

Browse files
committed
Only integrate known target in the cache once and clean path comparison
1 parent 1c7b787 commit 980890f

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

ghcide/session-loader/Development/IDE/Session.hs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ import Control.Applicative (Alternative ((<|>)))
9191
import Data.Void
9292

9393
import Control.Concurrent.STM.Stats (atomically, modifyTVar',
94-
readTVar, writeTVar)
94+
readTVar, writeTVar, readTVarIO)
9595
import Control.Concurrent.STM.TQueue
9696
import Control.DeepSeq
9797
import Control.Exception (evaluate)
@@ -124,6 +124,7 @@ import GHC.Driver.Errors.Types
124124
import GHC.Types.Error (errMsgDiagnostic,
125125
singleMessage)
126126
import GHC.Unit.State
127+
import Development.IDE (HscEnvEq(..))
127128

128129
#if MIN_VERSION_ghc(9,13,0)
129130
import GHC.Driver.Make (checkHomeUnitsClosed)
@@ -443,7 +444,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
443444

444445
return $ do
445446
clientConfig <- getClientConfigAction
446-
extras@ShakeExtras{restartShakeSession, ideNc, knownTargetsVar, lspEnv
447+
extras@ShakeExtras{restartShakeSession, ideNc, knownTargetsVar, lspEnv, moduleToPathCache
447448
} <- getShakeExtras
448449
let invalidateShakeCache = do
449450
void $ modifyVar' version succ
@@ -459,6 +460,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
459460
-- files in the project so that `knownFiles` can learn about them and
460461
-- we can generate a complete module graph
461462
let extendKnownTargets newTargets = do
463+
print "extendKnownTargets"
462464
knownTargets <- concatForM newTargets $ \TargetDetails{..} ->
463465
case targetTarget of
464466
TargetFile f -> do
@@ -490,6 +492,22 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
490492
pure hasUpdate
491493
for_ hasUpdate $ \x ->
492494
logWith recorder Debug $ LogKnownFilesUpdated (targetMap x)
495+
496+
497+
-- Clean the module map cache
498+
-- TODO: the clean is total: it refresh the complete module to
499+
-- filename cache. We can imagine something smarter in the future,
500+
-- but anyway, the scan is actually really fast (It lists recursively
501+
-- the content of all your include path, but once. It could only be
502+
-- as slow as the number of files in your include paths, which is,
503+
-- most of the time, the same as the number of module in your
504+
-- project. If there are a lot of not required files inside your
505+
-- include path, this will be an issue) and right now
506+
-- what's expensive is the association of Known target to module,
507+
-- which is still fast considering that it does not do any IO.
508+
atomically $ do
509+
writeTVar moduleToPathCache mempty
510+
493511
return $ toNoFileKey GetKnownTargets
494512

495513
-- Create a new HscEnv from a hieYaml root and a set of options

ghcide/src/Development/IDE/Core/Rules.hs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ import System.Info.Extra (isWindows)
178178
import qualified Data.IntMap as IM
179179
import GHC.Fingerprint
180180
import qualified Data.Map.Strict as Map
181-
import System.FilePath (takeExtension, takeFileName, normalise, dropExtension, splitDirectories)
181+
import System.FilePath (takeExtension, takeFileName, normalise, dropExtension, splitDirectories, equalFilePath)
182182
import Data.Char (isUpper)
183183
import System.Directory.Extra (listFilesInside)
184184

@@ -330,7 +330,7 @@ getLocatedImportsRule recorder =
330330
let dflags = hsc_dflags env
331331
opt <- getIdeOptions
332332

333-
moduleMaps <- extendModuleMapWithKnownTargets file
333+
moduleMaps <- use_ GetModulesPaths file
334334

335335
(diags, imports') <- fmap unzip $ forM imports $ \(isSource, (mbPkgName, modName)) -> do
336336

@@ -643,7 +643,7 @@ getModulesPathsRule recorder = defineEarlyCutoff (cmapWithPrio LogShake recorder
643643
(unzip -> (a, b)) <- flip mapM import_dirs $ \(u, dyn) -> do
644644
(unzip -> (a, b)) <- flip mapM (importPaths dyn) $ \dir' -> do
645645
let dir = normalise dir'
646-
let predicate path = pure (normalise path == dir || case takeFileName path of
646+
let predicate path = pure (equalFilePath path dir || case takeFileName path of
647647
[] -> False
648648
(x:_) -> isUpper x)
649649
let dir_number_directories = length (splitDirectories dir)
@@ -663,21 +663,21 @@ getModulesPathsRule recorder = defineEarlyCutoff (cmapWithPrio LogShake recorder
663663
let res = (mconcat a, mconcat b)
664664
liftIO $ atomically $ modifyTVar' moduleToPathCache (Map.insert (envUnique env_eq) res)
665665

666-
pure (mempty, ([], Just res))
666+
-- Extend the current module map with all the known targets
667+
resExtended <- extendModuleMapWithKnownTargets file res
668+
669+
pure (mempty, ([], Just resExtended))
670+
667671

668672
-- | Extend the map from module name to filepath (exiting on the drive) with
669673
-- the list of known targets provided by HLS
670674
--
671675
-- These known targets are files which were recently created and not yet saved
672676
-- to the filesystem.
673-
--
674-
-- TODO: for now the implementation is O(number_of_known_files *
675-
-- number_of_include_path) which is inacceptable and should be addressed.
676677
extendModuleMapWithKnownTargets
677-
:: NormalizedFilePath
678-
-> Action (Map.Map ModuleName (UnitId, NormalizedFilePath), Map.Map ModuleName (UnitId, NormalizedFilePath))
679-
extendModuleMapWithKnownTargets file = do
680-
(notSourceModules, sourceModules) <- use_ GetModulesPaths file
678+
:: NormalizedFilePath -> (Map.Map ModuleName (UnitId, NormalizedFilePath), Map.Map ModuleName (UnitId, NormalizedFilePath)) ->
679+
Action (Map.Map ModuleName (UnitId, NormalizedFilePath), Map.Map ModuleName (UnitId, NormalizedFilePath))
680+
extendModuleMapWithKnownTargets file (notSourceModules, sourceModules) = do
681681
KnownTargets targetsMap <- useNoFile_ GetKnownTargets
682682

683683
env_eq <- use_ GhcSession file
@@ -717,7 +717,6 @@ extendModuleMapWithKnownTargets file = do
717717
else
718718
pure (Just (modName, (u, path)), Nothing)
719719

720-
721720
pure $ (Map.fromList a <> notSourceModules, Map.fromList b <> sourceModules)
722721

723722

0 commit comments

Comments
 (0)