@@ -56,6 +56,7 @@ module Development.IDE.Core.Rules(
5656 GhcSessionDepsConfig (.. ),
5757 Log (.. ),
5858 DisplayTHWarning (.. ),
59+ extendModuleMapWithKnownTargets ,
5960 ) where
6061
6162import Control.Applicative
@@ -176,11 +177,10 @@ import System.Info.Extra (isWindows)
176177
177178import qualified Data.IntMap as IM
178179import GHC.Fingerprint
179- import Text.Pretty.Simple
180180import qualified Data.Map.Strict as Map
181181import System.FilePath (takeExtension , takeFileName , normalise , dropTrailingPathSeparator , dropExtension , splitDirectories )
182182import Data.Char (isUpper )
183- import System.Directory.Extra (listFilesRecursive , listFilesInside )
183+ import System.Directory.Extra (listFilesInside )
184184import System.IO.Unsafe
185185
186186data Log
@@ -331,7 +331,10 @@ getLocatedImportsRule recorder =
331331 let dflags = hsc_dflags env
332332 opt <- getIdeOptions
333333
334- moduleMaps <- use_ GetModulesPaths file
334+ moduleMaps' <- use_ GetModulesPaths file
335+
336+ moduleMaps <- extendModuleMapWithKnownTargets file moduleMaps'
337+
335338 (diags, imports') <- fmap unzip $ forM imports $ \ (isSource, (mbPkgName, modName)) -> do
336339
337340 diagOrImp <- locateModule moduleMaps (hscSetFlags dflags env) import_dirs (optExtensions opt) modName mbPkgName isSource
@@ -663,16 +666,64 @@ getModulesPathsRule recorder = defineEarlyCutoff (cmapWithPrio LogShake recorder
663666 let res = (mconcat a, mconcat b)
664667 liftIO $ atomically $ modifyTVar' cacheVar (Map. insert (envUnique env_eq) res)
665668
666- pure (mempty , ([] , Just $ (mconcat a, mconcat b)))
669+ pure (mempty , ([] , Just res))
670+
671+ -- | Extend the map from module name to filepath (exiting on the drive) with
672+ -- the list of known targets provided by HLS
673+ --
674+ -- These known targets are files which were recently created and not yet saved
675+ -- to the filesystem.
676+ --
677+ -- TODO: for now the implementation is O(number_of_known_files *
678+ -- number_of_include_path) which is inacceptable and should be addressed.
679+ extendModuleMapWithKnownTargets
680+ :: NormalizedFilePath -> (Map. Map ModuleName (UnitId , NormalizedFilePath ), Map. Map ModuleName (UnitId , NormalizedFilePath ))
681+ -> Action (Map. Map ModuleName (UnitId , NormalizedFilePath ), Map. Map ModuleName (UnitId , NormalizedFilePath ))
682+ extendModuleMapWithKnownTargets file (notSourceModules, sourceModules) = do
683+ KnownTargets targetsMap <- useNoFile_ GetKnownTargets
684+ env_eq <- use_ GhcSession file
685+ let env = hscEnv env_eq
686+ let import_dirs = map (second homeUnitEnv_dflags) $ hugElts $ hsc_HUG env
687+ opt <- getIdeOptions
688+ let exts = (optExtensions opt)
689+ let acceptedExtensions = concatMap (\ x -> [' .' : x, ' .' : x <> " -boot" ]) exts
690+
691+ let notSourceModuleP = Map. fromList $ do
692+ (u, dyn) <- import_dirs
693+ -- TODO: avoid using so much `FilePath` logic AND please please,
694+ -- normalize earlier.
695+ --
696+ -- The normalise here is in order to remove the trailing `.` which
697+ -- could break the comparison later.
698+ (normalise -> dir') <- importPaths dyn
699+ let dirComponents = splitDirectories dir'
700+ let dir_number_directories = length dirComponents
701+ -- TODO: the _target may represents something different than the path
702+ -- stored in paths. This need to be investigated.
703+ (_target, paths) <- HM. toList targetsMap
704+ -- TODO: I have no idea why there is multiple path here
705+ guard $ length paths > 0
706+ let path = head $ toList paths
707+ let pathString = fromNormalizedFilePath path
708+ let pathComponents = splitDirectories pathString
709+
710+ -- Ensure this file is in the directory
711+ guard $ dirComponents `isPrefixOf` pathComponents
712+
713+ -- Ensure that this extension is accepted
714+ guard $ takeExtension pathString `elem` acceptedExtensions
715+ let modName = mkModuleName (intercalate " ." $ drop dir_number_directories (splitDirectories (dropExtension pathString)))
716+ pure (modName, (u, path))
717+
718+ let notSourceModules' = notSourceModules <> notSourceModuleP
719+
720+ pure $!! (notSourceModules', sourceModules)
721+
667722
668723dependencyInfoForFiles :: [NormalizedFilePath ] -> Action (BS. ByteString , DependencyInformation )
669724dependencyInfoForFiles fs = do
670- -- liftIO $ print ("fs length", length fs)
671725 (rawDepInfo, bm) <- rawDependencyInformation fs
672- -- liftIO $ print ("ok with raw deps")
673- -- liftIO $ pPrint rawDepInfo
674726 let (all_fs, _all_ids) = unzip $ HM. toList $ pathToIdMap $ rawPathIdMap rawDepInfo
675- -- liftIO $ print ("all_fs length", length all_fs)
676727 msrs <- uses GetModSummaryWithoutTimestamps all_fs
677728 let mss = map (fmap msrModSummary) msrs
678729 let deps = map (\ i -> IM. lookup (getFilePathId i) (rawImports rawDepInfo)) _all_ids
0 commit comments