-findModule :: ModuleName -> IO (Maybe (Module, ModLocation))
-findModule name = do
- r <- lookupFinderCache name
- case r of
- Just result -> return (Just result)
- Nothing -> do
- j <- maybeHomeModule name
- case j of
- Just home_module -> return (Just home_module)
- Nothing -> findPackageMod name
-
-findPackageModule :: ModuleName -> IO (Maybe (Module, ModLocation))
-findPackageModule name = do
- r <- lookupFinderCache name
- case r of
- Just result -> return (Just result)
- Nothing -> findPackageMod name
-
-hiBootExt = "hi-boot"
-hiBootVerExt = "hi-boot-" ++ cHscIfaceFileVersion
-
-maybeHomeModule :: ModuleName -> IO (Maybe (Module, ModLocation))
-maybeHomeModule mod_name = do
- home_path <- readIORef v_Import_paths
- hisuf <- readIORef v_Hi_suf
- mode <- readIORef v_GhcMode
+data FindResult
+ = Found ModLocation PackageIdH
+ -- the module was found
+ | FoundMultiple [PackageId]
+ -- *error*: both in multiple packages
+ | PackageHidden PackageId
+ -- for an explicit source import: the package containing the module is
+ -- not exposed.
+ | ModuleHidden PackageId
+ -- for an explicit source import: the package containing the module is
+ -- exposed, but the module itself is hidden.
+ | NotFound [FilePath]
+ -- the module was not found, the specified places were searched.
+
+findModule :: HscEnv -> Module -> Bool -> IO FindResult
+findModule = findModule' True
+
+findPackageModule :: HscEnv -> Module -> Bool -> IO FindResult
+findPackageModule = findModule' False
+
+
+data LocalFindResult
+ = Ok FinderCacheEntry
+ | CantFindAmongst [FilePath]
+ | MultiplePackages [PackageId]
+
+findModule' :: Bool -> HscEnv -> Module -> Bool -> IO FindResult
+findModule' home_allowed hsc_env name explicit
+ = do -- First try the cache
+ mb_entry <- lookupFinderCache cache name
+ case mb_entry of
+ Just old_entry -> return $! found old_entry
+ Nothing -> not_cached
+
+ where
+ cache = hsc_FC hsc_env
+ dflags = hsc_dflags hsc_env
+
+ -- We've found the module, so the remaining question is
+ -- whether it's visible or not
+ found :: FinderCacheEntry -> FindResult
+ found (loc, Nothing)
+ | home_allowed = Found loc HomePackage
+ | otherwise = NotFound []
+ found (loc, Just (pkg, exposed_mod))
+ | explicit && not exposed_mod = ModuleHidden pkg_name
+ | explicit && not (exposed pkg) = PackageHidden pkg_name
+ | otherwise =
+ Found loc (ExtPackage (mkPackageId (package pkg)))
+ where
+ pkg_name = packageConfigId pkg
+
+ found_new entry = do
+ addToFinderCache cache name entry
+ return $! found entry
+
+ not_cached
+ | not home_allowed = do
+ j <- findPackageModule' dflags name
+ case j of
+ Ok entry -> found_new entry
+ MultiplePackages pkgs -> return (FoundMultiple pkgs)
+ CantFindAmongst paths -> return (NotFound paths)
+
+ | otherwise = do
+ j <- findHomeModule' dflags name
+ case j of
+ Ok entry -> found_new entry
+ MultiplePackages pkgs -> return (FoundMultiple pkgs)
+ CantFindAmongst home_files -> do
+ r <- findPackageModule' dflags name
+ case r of
+ CantFindAmongst pkg_files ->
+ return (NotFound (home_files ++ pkg_files))
+ MultiplePackages pkgs ->
+ return (FoundMultiple pkgs)
+ Ok entry ->
+ found_new entry
+
+addHomeModuleToFinder :: HscEnv -> Module -> ModLocation -> IO ()
+addHomeModuleToFinder hsc_env mod loc
+ = addToFinderCache (hsc_FC hsc_env) mod (loc, Nothing)
+
+uncacheModule :: HscEnv -> Module -> IO ()
+uncacheModule hsc_env mod = removeFromFinderCache (hsc_FC hsc_env) mod
+
+-- -----------------------------------------------------------------------------
+-- The internal workers
+
+findHomeModule' :: DynFlags -> Module -> IO LocalFindResult
+findHomeModule' dflags mod = do
+ let home_path = importPaths dflags
+ hisuf = hiSuf dflags