+-- Helpers
+
+orIfNotFound :: IO FindResult -> IO FindResult -> IO FindResult
+orIfNotFound this or_this = do
+ res <- this
+ case res of
+ NotFound { fr_paths = paths1, fr_mods_hidden = mh1
+ , fr_pkgs_hidden = ph1, fr_suggestions = s1 }
+ -> do res2 <- or_this
+ case res2 of
+ NotFound { fr_paths = paths2, fr_pkg = mb_pkg2, fr_mods_hidden = mh2
+ , fr_pkgs_hidden = ph2, fr_suggestions = s2 }
+ -> return (NotFound { fr_paths = paths1 ++ paths2
+ , fr_pkg = mb_pkg2 -- snd arg is the package search
+ , fr_mods_hidden = mh1 ++ mh2
+ , fr_pkgs_hidden = ph1 ++ ph2
+ , fr_suggestions = s1 ++ s2 })
+ _other -> return res2
+ _other -> return res
+
+
+homeSearchCache :: HscEnv -> ModuleName -> IO FindResult -> IO FindResult
+homeSearchCache hsc_env mod_name do_this = do
+ m <- lookupFinderCache (hsc_FC hsc_env) mod_name
+ case m of
+ Just result -> return result
+ Nothing -> do
+ result <- do_this
+ addToFinderCache (hsc_FC hsc_env) mod_name result
+ case result of
+ Found loc mod -> addToModLocationCache (hsc_MLC hsc_env) mod loc
+ _other -> return ()
+ return result
+
+findExposedPackageModule :: HscEnv -> ModuleName -> Maybe FastString
+ -> IO FindResult
+findExposedPackageModule hsc_env mod_name mb_pkg
+ -- not found in any package:
+ = case lookupModuleWithSuggestions (hsc_dflags hsc_env) mod_name of
+ Left suggest -> return (NotFound { fr_paths = [], fr_pkg = Nothing
+ , fr_pkgs_hidden = [], fr_mods_hidden = []
+ , fr_suggestions = suggest })
+ Right found
+ | null found_exposed -- Found, but with no exposed copies
+ -> return (NotFound { fr_paths = [], fr_pkg = Nothing
+ , fr_pkgs_hidden = pkg_hiddens, fr_mods_hidden = mod_hiddens
+ , fr_suggestions = [] })
+
+ | [(pkg_conf,_)] <- found_exposed -- Found uniquely
+ -> let pkgid = packageConfigId pkg_conf in
+ findPackageModule_ hsc_env (mkModule pkgid mod_name) pkg_conf
+
+ | otherwise -- Found in more than one place
+ -> return (FoundMultiple (map (packageConfigId.fst) found_exposed))
+ where
+ for_this_pkg = case mb_pkg of
+ Nothing -> found
+ Just p -> filter ((`matches` p) . fst) found
+ found_exposed = filter is_exposed for_this_pkg
+ is_exposed (pkg_conf,exposed_mod) = exposed pkg_conf && exposed_mod
+
+ mod_hiddens = [ packageConfigId pkg_conf
+ | (pkg_conf,False) <- found ]
+
+ pkg_hiddens = [ packageConfigId pkg_conf
+ | (pkg_conf,_) <- found, not (exposed pkg_conf) ]
+
+ pkg_conf `matches` pkg
+ = case packageName pkg_conf of
+ PackageName n -> pkg == mkFastString n
+
+modLocationCache :: HscEnv -> Module -> IO FindResult -> IO FindResult
+modLocationCache hsc_env mod do_this = do
+ mb_loc <- lookupModLocationCache mlc mod
+ case mb_loc of
+ Just loc -> return (Found loc mod)
+ Nothing -> do
+ result <- do_this
+ case result of
+ Found loc mod -> addToModLocationCache (hsc_MLC hsc_env) mod loc
+ _other -> return ()
+ return result
+ where
+ mlc = hsc_MLC hsc_env
+
+addHomeModuleToFinder :: HscEnv -> ModuleName -> ModLocation -> IO Module
+addHomeModuleToFinder hsc_env mod_name loc = do
+ let mod = mkModule (thisPackage (hsc_dflags hsc_env)) mod_name
+ addToFinderCache (hsc_FC hsc_env) mod_name (Found loc mod)
+ addToModLocationCache (hsc_MLC hsc_env) mod loc
+ return mod