-It does *not* know which particular package a module lives in, because
-that information is only contained in the interface file.
-
-\begin{code}
-initFinder :: [PackageConfig] -> IO ()
-initFinder pkgs = return ()
-
--- empty, and lazilly fill in the package cache
-flushPackageCache :: [PackageConfig] -> IO ()
-flushPackageCache pkgs = return ()
-
-emptyHomeDirCache :: IO ()
-emptyHomeDirCache = return ()
-
-findModule :: ModuleName -> IO (Maybe (Module, ModuleLocation))
-findModule name = findModuleDep name False
-
-findModuleDep :: ModuleName -> Bool -> IO (Maybe (Module, ModuleLocation))
-findModuleDep name is_source
- = do { j <- maybeHomeModule name is_source
- ; case j of
- Just home_module -> return (Just home_module)
- Nothing -> findPackageMod name False is_source
- }
-
-maybeHomeModule :: ModuleName -> Bool -> IO (Maybe (Module, ModuleLocation))
-maybeHomeModule mod_name is_source = do
+-- -----------------------------------------------------------------------------
+-- The Finder
+
+-- The Finder provides a thin filesystem abstraction to the rest of the
+-- compiler. For a given module, it knows (a) whether the module lives
+-- in the home package or in another package, so it can make a Module
+-- from a ModuleName, and (b) where the source, interface, and object
+-- files for a module live.
+--
+-- It does *not* know which particular package a module lives in, because
+-- that information is only contained in the interface file.
+
+-- -----------------------------------------------------------------------------
+-- The finder's cache
+
+GLOBAL_VAR(finder_cache, emptyModuleEnv, ModuleEnv (Module,ModLocation))
+
+-- remove all the home modules from the cache; package modules are
+-- assumed to not move around during a session.
+flushFinderCache :: IO ()
+flushFinderCache = do
+ fm <- readIORef finder_cache
+ writeIORef finder_cache (filterUFM (not . isHomeModule . fst) fm)
+
+addToFinderCache :: ModuleName -> (Module,ModLocation) -> IO ()
+addToFinderCache mod_name stuff = do
+ fm <- readIORef finder_cache
+ writeIORef finder_cache (extendModuleEnvByName fm mod_name stuff)
+
+lookupFinderCache :: ModuleName -> IO (Maybe (Module,ModLocation))
+lookupFinderCache mod_name = do
+ fm <- readIORef finder_cache
+ return $! lookupModuleEnvByName fm mod_name
+
+-- -----------------------------------------------------------------------------
+-- Locating modules
+
+-- This is the main interface to the finder, which maps ModuleNames to
+-- Modules and ModLocations.
+--
+-- The Module contains one crucial bit of information about a module:
+-- whether it lives in the current ("home") package or not (see Module
+-- for more details).
+--
+-- The ModLocation contains the names of all the files associated with
+-- that module: its source file, .hi file, object file, etc.
+
+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