-findModule :: ModuleName -> IO (Either [FilePath] (Module, ModLocation))
-findModule name = do
- r <- lookupFinderCache name
- case r of
- Just result -> return (Right result)
- Nothing -> do
- j <- maybeHomeModule name
- case j of
- Right home_module -> return (Right home_module)
- Left home_files -> do
- r <- findPackageMod name
- case r of
- Right pkg_module -> return (Right pkg_module)
- Left pkg_files -> return (Left (home_files ++ pkg_files))
-
-findPackageModule :: ModuleName -> IO (Either [FilePath] (Module, ModLocation))
-findPackageModule name = do
- r <- lookupFinderCache name
- case r of
- Just result -> return (Right result)
- Nothing -> findPackageMod name
-
-hiBootExt = "hi-boot"
-hiBootVerExt = "hi-boot-" ++ cHscIfaceFileVersion
-
-maybeHomeModule :: ModuleName -> IO (Either [FilePath] (Module, ModLocation))
-maybeHomeModule mod_name = do
- home_path <- readIORef v_Import_paths
+data FindResult
+ = Found ModLocation PackageIdH
+ -- the module was found
+ | 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.
+
+type LocalFindResult = MaybeErr [FilePath] FinderCacheEntry
+ -- LocalFindResult is used for internal functions which
+ -- return a more informative type; it's munged into
+ -- the external FindResult by 'cached'
+
+cached :: (DynFlags -> Module -> IO LocalFindResult)
+ -> DynFlags -> Module -> Bool -> IO FindResult
+cached wrapped_fn dflags name explicit
+ = do { -- First try the cache
+ mb_entry <- lookupFinderCache name
+ ; case mb_entry of {
+ Just old_entry -> return (found old_entry) ;
+ Nothing -> do
+
+ { -- Now try the wrapped function
+ mb_entry <- wrapped_fn dflags name
+ ; case mb_entry of
+ Failed paths -> return (NotFound paths)
+ Succeeded new_entry -> do { addToFinderCache name new_entry
+ ; return (found new_entry) }
+ }}}
+ where
+ -- We've found the module, so the remaining question is
+ -- whether it's visible or not
+ found :: FinderCacheEntry -> FindResult
+ found (loc, Nothing) = Found loc HomePackage
+ 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
+
+addHomeModuleToFinder :: Module -> ModLocation -> IO ()
+addHomeModuleToFinder mod loc = addToFinderCache mod (loc, Nothing)
+
+
+-- -----------------------------------------------------------------------------
+-- The two external entry points
+
+
+findModule :: DynFlags -> Module -> Bool -> IO FindResult
+findModule = cached findModule'
+
+findPackageModule :: DynFlags -> Module -> Bool -> IO FindResult
+findPackageModule = cached findPackageModule'
+
+-- -----------------------------------------------------------------------------
+-- The internal workers
+
+findModule' :: DynFlags -> Module -> IO LocalFindResult
+-- Find home or package module
+findModule' dflags name = do
+ r <- findPackageModule' dflags name
+ case r of
+ Failed pkg_files -> do
+ j <- findHomeModule' dflags name
+ case j of
+ Failed home_files ->
+ return (Failed (home_files ++ pkg_files))
+ other_result
+ -> return other_result
+ other_result
+ -> return other_result
+
+findHomeModule' :: DynFlags -> Module -> IO LocalFindResult
+findHomeModule' dflags mod = do
+ let home_path = importPaths dflags