Skip to content

Commit 0b70965

Browse files
committed
maximize sharing of NormalizedFilePath values
1 parent 2df3d30 commit 0b70965

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

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

+19-7
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ import Ide.Plugin.Properties (HasProperty,
151151
import Ide.PluginUtils (configForPlugin)
152152
import Ide.Types (DynFlagsModifications (dynFlagsModifyGlobal, dynFlagsModifyParser),
153153
PluginId)
154+
import qualified Data.HashSet as HS
154155

155156
-- | This is useful for rules to convert rules that can only produce errors or
156157
-- a result into the more general IdeResult type that supports producing
@@ -311,6 +312,7 @@ getLocatedImportsRule =
311312
define $ \GetLocatedImports file -> do
312313
ModSummaryResult{msrModSummary = ms} <- use_ GetModSummaryWithoutTimestamps file
313314
targets <- useNoFile_ GetKnownTargets
315+
let targetsMap = HM.mapWithKey const targets
314316
let imports = [(False, imp) | imp <- ms_textual_imps ms] ++ [(True, imp) | imp <- ms_srcimps ms]
315317
env_eq <- use_ GhcSession file
316318
let env = hscEnvWithImportPaths env_eq
@@ -321,14 +323,24 @@ getLocatedImportsRule =
321323
then addRelativeImport file (moduleName $ ms_mod ms) dflags
322324
else dflags
323325
opt <- getIdeOptions
324-
let getTargetExists modName nfp
325-
| isImplicitCradle = getFileExists nfp
326-
| HM.member (TargetModule modName) targets
327-
|| HM.member (TargetFile nfp) targets
328-
= getFileExists nfp
329-
| otherwise = return False
326+
let getTargetFor modName nfp
327+
| isImplicitCradle = do
328+
itExists <- getFileExists nfp
329+
return $ if itExists then Just nfp else Nothing
330+
| Just (TargetFile nfp') <- HM.lookup (TargetFile nfp) targetsMap = do
331+
-- reuse the existing NormalizedFilePath in order to maximize sharing
332+
itExists <- getFileExists nfp'
333+
return $ if itExists then Just nfp' else Nothing
334+
| Just tt <- HM.lookup (TargetModule modName) targets = do
335+
-- reuse the existing NormalizedFilePath in order to maximize sharing
336+
let ttmap = HM.mapWithKey const (HS.toMap tt)
337+
nfp' = HM.lookupDefault nfp nfp ttmap
338+
itExists <- getFileExists nfp'
339+
return $ if itExists then Just nfp' else Nothing
340+
| otherwise
341+
= return Nothing
330342
(diags, imports') <- fmap unzip $ forM imports $ \(isSource, (mbPkgName, modName)) -> do
331-
diagOrImp <- locateModule dflags import_dirs (optExtensions opt) getTargetExists modName mbPkgName isSource
343+
diagOrImp <- locateModule dflags import_dirs (optExtensions opt) getTargetFor modName mbPkgName isSource
332344
case diagOrImp of
333345
Left diags -> pure (diags, Just (modName, Nothing))
334346
Right (FileImport path) -> pure ([], Just (modName, Just path))

ghcide/src/Development/IDE/Import/FindImports.hs

+7-7
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ modSummaryToArtifactsLocation nfp ms = ArtifactsLocation nfp (ms_location <$> ms
6969
locateModuleFile :: MonadIO m
7070
=> [[FilePath]]
7171
-> [String]
72-
-> (ModuleName -> NormalizedFilePath -> m Bool)
72+
-> (ModuleName -> NormalizedFilePath -> m (Maybe NormalizedFilePath))
7373
-> Bool
7474
-> ModuleName
7575
-> m (Maybe NormalizedFilePath)
76-
locateModuleFile import_dirss exts doesExist isSource modName = do
76+
locateModuleFile import_dirss exts targetFor isSource modName = do
7777
let candidates import_dirs =
7878
[ toNormalizedFilePath' (prefix </> M.moduleNameSlashes modName <.> maybeBoot ext)
7979
| prefix <- import_dirs , ext <- exts]
80-
findM (doesExist modName) (concatMap candidates import_dirss)
80+
firstJustM (targetFor modName) (concatMap candidates import_dirss)
8181
where
8282
maybeBoot ext
8383
| isSource = ext ++ "-boot"
@@ -97,12 +97,12 @@ locateModule
9797
=> DynFlags
9898
-> [(Compat.InstalledUnitId, DynFlags)] -- ^ Import directories
9999
-> [String] -- ^ File extensions
100-
-> (ModuleName -> NormalizedFilePath -> m Bool) -- ^ does file exist predicate
100+
-> (ModuleName -> NormalizedFilePath -> m (Maybe NormalizedFilePath)) -- ^ does file exist predicate
101101
-> Located ModuleName -- ^ Module name
102102
-> Maybe FastString -- ^ Package name
103103
-> Bool -- ^ Is boot module
104104
-> m (Either [FileDiagnostic] Import)
105-
locateModule dflags comp_info exts doesExist modName mbPkgName isSource = do
105+
locateModule dflags comp_info exts targetFor modName mbPkgName isSource = do
106106
case mbPkgName of
107107
-- "this" means that we should only look in the current package
108108
Just "this" -> do
@@ -118,7 +118,7 @@ locateModule dflags comp_info exts doesExist modName mbPkgName isSource = do
118118
-- Here the importPaths for the current modules are added to the front of the import paths from the other components.
119119
-- This is particularly important for Paths_* modules which get generated for every component but unless you use it in
120120
-- each component will end up being found in the wrong place and cause a multi-cradle match failure.
121-
mbFile <- locateModuleFile (importPaths dflags : map snd import_paths) exts doesExist isSource $ unLoc modName
121+
mbFile <- locateModuleFile (importPaths dflags : map snd import_paths) exts targetFor isSource $ unLoc modName
122122
case mbFile of
123123
Nothing -> lookupInPackageDB dflags
124124
Just file -> toModLocation file
@@ -129,7 +129,7 @@ locateModule dflags comp_info exts doesExist modName mbPkgName isSource = do
129129
return $ Right $ FileImport $ ArtifactsLocation file (Just loc) (not isSource)
130130

131131
lookupLocal dirs = do
132-
mbFile <- locateModuleFile dirs exts doesExist isSource $ unLoc modName
132+
mbFile <- locateModuleFile dirs exts targetFor isSource $ unLoc modName
133133
case mbFile of
134134
Nothing -> return $ Left $ notFoundErr dflags modName $ LookupNotFound []
135135
Just file -> toModLocation file

0 commit comments

Comments
 (0)